using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;

namespace Elwig.Models {
    [Table("member"), PrimaryKey("MgNr")]
    public class Member {
        [Column("mgnr")]
        public int MgNr { get; set; }

        [Column("predecessor_mgnr")]
        public int? PredecessorMgNr { get; set; }

        [Column("prefix")]
        public string? Prefix { get; set; }

        [Column("given_name")]
        public string GivenName { get; set; }

        [Column("middle_names")]
        public string? MiddleName { get; set; }

        [NotMapped]
        public string[] MiddleNames {
            get { return (MiddleName != null) ? MiddleName.Split(" ") : Array.Empty<string>(); }
            set { MiddleName = (value.Length > 0) ? string.Join(" ", value) : null; }
        }

        [Column("family_name")]
        public string FamilyName { get; set; }

        [Column("suffix")]
        public string? Suffix { get; set; }

        [Column("birthday")]
        public string? Birthday { get; set; }

        [Column("entry_date")]
        public string? EntryDate { get; set; }

        [Column("exit_date")]
        public string? ExitDate { get; set; }

        [Column("business_shares")]
        public int BusinessShares { get; set; }

        [Column("accounting_nr")]
        public string? AccountingNr { get; set; }

        [Column("zwstid")]
        public string? ZwstId { get; set; }

        [Column("lfbis_nr")]
        public string? LfbisNr { get; set; }

        [Column("ustid")]
        public string? UstId { get; set; }

        [Column("volllieferant")]
        public bool IsVollLieferant { get; set; }

        [Column("buchführend")]
        public bool IsBuchführend { get; set; }

        [Column("funktionär")]
        public bool IsFunktionär { get; set; }

        [Column("active")]
        public bool IsActive { get; set; }

        [Column("iban")]
        public string? Iban { get; set; }

        [Column("bic")]
        public string? Bic { get; set; }

        [Column("country")]
        public string CountryCode { get; set; }

        [Column("postal_dest")]
        public string PostalDestId { get; set; }

        [Column("address")]
        public string Address { get; set; }

        [Column("email")]
        public string? Email { get; set; }

        [Column("phone_landline")]
        public string? PhoneLandline { get; set; }

        [Column("phone_mobile_1")]
        public string? PhoneMobile1 { get; set; }

        [Column("phone_mobile_2")]
        public string? PhoneMobile2 { get; set; }

        [Column("default_kgnr")]
        public int? DefaultKgNr { get; set; }

        [Column("default_contact")]
        public string DefaultContact { get; set; }

        [Column("comment")]
        public string? Comment { get; set; }

        [ForeignKey("PredecessorMgNr")]
        public virtual Member? Predecessor { get; private set; }

        [ForeignKey("CountryCode")]
        public virtual Country Country { get; private set; }

        [ForeignKey("CountryCode, PostalDestId")]
        public virtual PostalDest PostalDest { get; private set; }

        [ForeignKey("DefaultKgNr")]
        public virtual AT_Kg? DefaultKg { get; private set; }

        [ForeignKey("ZwstId")]
        public virtual Branch? Branch { get; private set; }

        [InverseProperty("Member")]
        public virtual ISet<Contract> Contracts { get; private set; }

        [InverseProperty("Member")]
        public virtual BillingAddress BillingAddress { get; private set; }

        public int SearchScore(IEnumerable<string> keywords) {
            keywords = keywords.Where(s => s.Length >= 2 || (s.Length > 0 && s.All(c => char.IsDigit(c))));
            if (!keywords.Any())
                return 0;

            string?[] check = new string?[] {
                MgNr.ToString(),
                FamilyName.ToLower(), MiddleName?.ToLower(), GivenName.ToLower(),
                BillingAddress?.Name.ToLower(),
                Comment?.ToLower(),
            };

            int i = 0;
            foreach (string? c in check) {
                if (c == null) {
                    continue;
                } else if (keywords.Any(f => c == f)) {
                    i += 100;
                } else if (keywords.Any(f => c.Split(" ").Any(a => a == f))) {
                    i += 99;
                } else if (keywords.Any(f => f != null && c.Contains(f))) {
                    i += 1;
                }
            }
            return i;
        }
    }
}