using KarleyLibrary.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using WK5.Core.Models;
using WK5.Core.Models.VatChecker;
using WK5.Core.Services;

namespace WK5.Core.PageModels.Stammdaten.Kunden
{
    /// <summary>
    /// Stellt ein Objekt zur Validierung von Kundendaten dar.
    /// </summary>
    public class KundeInput
    {
        public string? Kundennummer { get; }
        #region Ansprechpartner, Liefer- und Rechungsanschriften
        [IgnoreModificationCheck] public AnsprechpartnerInput? SelectedAnsprechpartner { get; set; }
        [IgnoreModificationCheck] public LieferanschriftInput? SelectedLieferanschrift { get; set; }
        [IgnoreModificationCheck] public RechnungsanschriftInput? SelectedRechnungsanschrift { get; set; }
        public List<AnsprechpartnerInput> Ansprechpartner { get; } = new List<AnsprechpartnerInput>();
        public List<LieferanschriftInput> Lieferanschriften { get; } = new List<LieferanschriftInput>();
        public List<RechnungsanschriftInput> Rechnungsanschriften { get; } = new List<RechnungsanschriftInput>();



        public void SetHauptLieferanschrift(LieferanschriftInput anschrift)
        {
            foreach (var item in Lieferanschriften)
            {
                if (item != anschrift)
                {
                    item.Hauptanschrift = false;
                }
            }
        }

        public void SetHauptRechnungsanschrift(RechnungsanschriftInput anschrift)
        {
            foreach (var item in Rechnungsanschriften)
            {
                if (item != anschrift)
                {
                    item.Hauptanschrift = false;
                }
            }
        }
        public void AddLieferanschrift()
        {
            var newAnschrift = new LieferanschriftInput()
            {
                Kundennummer = Kundennummer,
                Firma = Firma,
                Name2 = Name2 ?? string.Empty,
                Name3 = Name3,
                Telefon = Telefon1 ?? Telefon2,
                Fax = Fax,
                Land = Land
            };
            Lieferanschriften.Add(newAnschrift);
            SelectedLieferanschrift = newAnschrift;
        }

        public void RemoveLieferanschrift()
        {
            if (SelectedLieferanschrift is null)
            {
                return;
            }

            SelectedLieferanschrift = Lieferanschriften.Remove(SelectedLieferanschrift) ? null : SelectedLieferanschrift;
        }

        public void AddRechnungsanschrift()
        {
            var newAnschrift = new RechnungsanschriftInput()
            {
                Kundennummer = Kundennummer,
                Firma = Firma,
                Name2 = Name2,
                Name3 = Name3,
                Telefon = Telefon1 ?? Telefon2,
                Fax = Fax,
                Land = Land
            };
            Rechnungsanschriften.Add(newAnschrift);
            SelectedRechnungsanschrift = newAnschrift;
        }

        public void RemoveRechnungsanschrift()
        {
            if (SelectedRechnungsanschrift is null)
            {
                return;
            }

            SelectedRechnungsanschrift = Rechnungsanschriften.Remove(SelectedRechnungsanschrift) ? null : SelectedRechnungsanschrift;
        }
        #endregion
        #region Felder
        private string _email = String.Empty;
        private string? _telefon1 = null; // _telefon1 und _telefon2 sind dafür da, da das PhoneAttribute einen leeren String als invalid kennzeichnet. Er muss null sein für OK
        private string? _telefon2 = null;
        private int _kundengruppeId = 2; // Firmenkunde ist der Standardwert
        #endregion
        #region Properties        
        public string Firma { get; set; } = String.Empty;
        public string? Name2 { get; set; }
        public string? Name3 { get; set; }
        public string Strasse { get; set; } = String.Empty;
        public string Ort { get; set; } = String.Empty;
        public string Land { get; set; } = "DE";
        public string Postleitzahl { get; set; } = String.Empty;
        public string Anrede { get; set; } = "Sehr geehrte Damen und Herren";
        public string? Telefon1
        {
            get => _telefon1;
            set
            {
                if (value != null && value.Equals(String.Empty))
                {
                    value = null;
                }

                _telefon1 = value;
            }
        }
        public string? Telefon2
        {
            get => _telefon2;
            set
            {
                if (value != null && value.Equals(String.Empty))
                {
                    value = null;
                }

                _telefon2 = value;
            }
        }
        public string? Fax { get; set; }
        public string? Handy { get; set; }
        public string Email
        {
            get => _email;
            set
            {
                _email = value.Trim().Trim('\t');
                AutoCompleteHomepage();
            }
        }
        public string? Homepage { get; set; }
        public string? Suchbegriff { get; set; }
        public int LieferbedingungId { get; set; } = 1; // Versand Paketdienst ist standard
        public int ZahlungsbedingungId { get; set; } = 22; // Vorkasse ist standard
        public int VertreterId { get; set; }
        public int KundengruppeId
        {
            get => _kundengruppeId;
            set
            {
                _kundengruppeId = value;
                PreislisteId = value switch
                {
                    1 => 1,
                    2 => 2,
                    3 => 3,
                    4 => 2,
                    5 => 2,
                    7 => 2,
                    8 => 2,
                    _ => 2
                };
            }
        }
        public int PreislisteId { get; set; } = 2; // Firmenpreisliste ist Standard
        public decimal Kreditlimit { get; set; }
        public string? Debitorennummer { get; set; }
        public string? UstId { get; set; }
        public string? Steuernummer { get; set; }
        public string? LieferantNummer { get; set; }
        public string? Gln { get; set; }
        public string? Handelsregisternummer { get; set; }
        public string? Amtsgericht { get; set; }
        public bool MwstBerechnen { get; set; } = true;
        public bool Gesperrt { get; set; }
        public bool SperreBeiOp { get; set; } = true;
        public bool Frachtfrei { get; set; }
        public bool NeutraleVersandadresse { get; set; }
        public bool Bonus { get; set; }
        public string? Selektionsmerkmal1 { get; set; }
        public string? Selektionsmerkmal2 { get; set; }
        public string? Selektionsmerkmal3 { get; set; }
        public string? Selektionsmerkmal4 { get; set; }
        public string? Selektionsmerkmal5 { get; set; }
        public string? Selektionsmerkmal6 { get; set; }
        public bool Reminder { get; set; }
        public bool Rechnungsdruck { get; set; }
        public bool NurRechnungAlsPdf { get; set; }
        public bool Exkunde { get; set; }
        public bool KeinMailing { get; set; }
        public bool BenachrichtigenBeiFehlenderUstId { get; set; }
        public bool VersandkostenManuellAnfragen { get; set; }
        public bool UstIdIstGültig { get; set; }
        public bool KeineWartungen { get; set; }
        public string SteuernGrund(List<Land> länder)
        {

            if (länder.Any(x => x.LAND_A_ID == Land && !x.WK5_LAND_L_ISTEULAND))
            {
                return "(Nicht EU-Ausland)";
            }

            if (Land.Equals("DE", StringComparison.OrdinalIgnoreCase))
            {
                return "(DE)";
            }

            if (länder.Any(x => x.LAND_A_ID == Land && Land != "DE" && x.WK5_LAND_L_ISTEULAND && UstIdIstGültig))
            {
                return "(EU-Ausland mit gültiger UstId.)";
            }

            return "(EU-Ausland ohne gültige UstId.)";
        }
        public string IBAN { get; set; } = String.Empty;
        public string BIC { get; set; } = String.Empty;
        public DateTime MandatsAusstellungsdatum { get; set; }

        public string? Sperrvermerk { get; set; }
        public DateTime LetzteAbfrageUstId { get; set; }
        public string? Notiz { get; set; }
        public string Mandatsreferenz { get; set; } = String.Empty;
        public string EmpfohlenVon { get; set; } = String.Empty;
        public string LeitwegId { get; set; } = String.Empty;

        public bool XRechnungSenden { get; set; } = true;

        #endregion
        #region AutoComplete
        public async Task<VatCheck> PrüfeUstIdAsync(VatService vatService)
        {
            bool useCustomAddress = !String.IsNullOrWhiteSpace(UstIdFirma);
            VatRequest vatRequest = new VatRequest
            (
                UstId ?? String.Empty,
                useCustomAddress ? UstIdFirma : Firma,
                useCustomAddress ? UstIdOrt : Ort,
                useCustomAddress ? UstIdPostleitzahl : Postleitzahl,
                useCustomAddress ? UstIdStrasse : Strasse,
                Kundennummer ?? "Keine Kundennummer angegeben",
                true,
                VatZuordnung.Kunde,
                0
            );

            using FbController2 fbController = new FbController2();
            var vatResult = await vatService.CheckVatAsync(vatRequest, fbController, true);
            UstIdIstGültig = vatService.IsVatCheckValid(vatResult);
            LetzteAbfrageUstId = DateTime.Now;
            return vatResult;
        }
      
        private void AutoCompleteHomepage()
        {
            string domain = Regex.Replace(Email, @".*@", "");
            if (!GlobalConfig.Freemails.Contains(domain))
            {
                Homepage = domain;
            }
        }

        #endregion
        #region UstId Adresse        
        public string UstIdFirma { get; set; } = String.Empty;
        public string UstIdStrasse { get; set; } = String.Empty;
        public string UstIdPostleitzahl { get; set; } = String.Empty;
        public string UstIdOrt { get; set; } = String.Empty;
        #endregion
        #region Konvertierung
        public Kunde ToKunde(List<Land> länder)
        {
            return new Kunde
            {
                KUND_A_NAME1 = Firma,
                KUND_A_NAME2 = Name2 ?? string.Empty,
                KUND_A_NAME3 = Name3 ?? string.Empty,
                KUND_A_STRASSE = Strasse,
                KUND_A_ORT = Ort,
                KUND_A_LAND = Land,
                KUND_A_PLZ = Postleitzahl,
                KUND_A_ANREDE = Anrede,
                KUND_A_TEL1 = Telefon1,
                KUND_A_TEL2 = Telefon2,
                KUND_A_FAX = Fax,
                KUND_A_HANDY = Handy,
                KUND_A_EMAIL = Email,
                KUND_A_URL = Homepage,
                KUND_A_SUCHCODE = Suchbegriff,
                KUND_N_LIEFERUNG = LieferbedingungId,
                KUND_N_ZAHLUNG = ZahlungsbedingungId,
                KUND_N_VERTRETNUMM = VertreterId,
                KUND_N_PREISLISTNR = PreislisteId,
                KUND_N_KREDITLIMIT = Kreditlimit,
                KUND_A_DEBITORNR = Debitorennummer,
                KUND_A_USTIDNR = UstId,
                KUND_A_STEUERNR = Steuernummer,
                KUND_A_LIEFNR = LieferantNummer,
                KUND_A_GLN = Gln,
                KUND_WK5_A_HRB = Handelsregisternummer,
                KUND_WK5_A_AMTSGERICHT = Amtsgericht,
                KUND_L_MWST = MwstBerechnen,
                KUND_L_SPERRE = Gesperrt,
                KUND_L_SPERRE_OP = SperreBeiOp,
                KUND_L_FRACHTFREI = Frachtfrei,
                KUND_L_NEUTRALVERSAND = NeutraleVersandadresse,
                KUND_L_BONUS = Bonus,
                KUND_A_SELEKTION1 = Selektionsmerkmal1,
                KUND_A_SELEKTION2 = Selektionsmerkmal2,
                KUND_A_SELEKTION3 = Selektionsmerkmal3,
                KUND_A_SELEKTION4 = Selektionsmerkmal4,
                KUND_A_SELEKTION5 = Selektionsmerkmal5,
                KUND_A_SELEKTION6 = Selektionsmerkmal6,
                KUND_WK5_L_REMINDER = Reminder,
                KUND_WK5_L_REDRUCK = Rechnungsdruck,
                KUND_WK5_L_EXKUNDE = Exkunde,
                KUND_WK5_L_KEINMAILING = KeinMailing,
                KUND_L_AUSLAND = länder.Any(x => !x.WK5_LAND_L_ISTEULAND && x.LAND_A_ID == Land),
                KUND_L_EUKUNDE = Land != "DE" && länder.Any(x => x.WK5_LAND_L_ISTEULAND && x.LAND_A_ID == Land),
                KUND_A_NR = Kundennummer!,
                KUND_N_KUNDGRUPPE = KundengruppeId,
                KUND_WK5_L_USTIDFEHLTGEPRUEFT = BenachrichtigenBeiFehlenderUstId,
                KUND_WK5_L_VERSANDWARNUNG = VersandkostenManuellAnfragen,
                KUND_B_NOTIZ = Notiz,
                KUND_A_IBAN = IBAN,
                KUND_A_BIC = BIC,
                IstUstIdGültig = UstIdIstGültig,
                UstIdLastPrüfung = LetzteAbfrageUstId,
                KUND_WK5_A_UST_NAME = UstIdFirma,
                KUND_WK5_A_UST_ORT = UstIdOrt,
                KUND_WK5_A_UST_PLZ = UstIdPostleitzahl,
                KUND_WK5_A_UST_STRASSE = UstIdStrasse,
                KUND_WK5_A_MANDATSREFERENZ = Mandatsreferenz,
                KUND_WK5_A_EMPFOHLEN_VON = EmpfohlenVon,
                KUND_WK5_D_AUSSTELLUNG_MANDAT = MandatsAusstellungsdatum,
                NurRechnungAlsPdf = NurRechnungAlsPdf,
                KeineWartungen = KeineWartungen,
                KUND_A_SPERRVERMERK = Sperrvermerk,
                KUND_WK5_A_LEITWEG_ID = LeitwegId,
                KUND_WK5_L_XRECHNUNG = XRechnungSenden
            };
        }
        #endregion

        public KundeInput(string? kundennummer = null)
        {
            Kundennummer = kundennummer;
        }
    }
}
