using KarleyLibrary.Attributes;
using KarleyLibrary.Erweiterungen;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using WK5.Core.Models.VatChecker;

namespace WK5.Core.Models
{
    public class Kunde : IVatCheckable
    {
        #region Felder
        private string _kund_wk5_ust_name = String.Empty;
        private string _kund_wk5_ust_strasse = String.Empty;
        private string _kund_wk5_ust_plz = String.Empty;
        private string _kund_wk5_ust_ort = String.Empty;
        private string _name1 = String.Empty;
        private string _name2 = String.Empty;
        private string _name3 = string.Empty;
        private string _ort = string.Empty;
        private string _postleitzahl = string.Empty;
        private string _strasse = string.Empty;
        private string _land = "DE";
        #endregion
        #region Datenbankfelder
        #region Alphanumerische Werte
        public string? KUND_A_ANREDE { get; set; }
        public string? KUND_A_ANSPRPARTN { get; set; }
        public string? KUND_A_ART { get; set; }
        public string? KUND_A_BANKKONTO { get; set; }
        public string? KUND_A_BANKNAME { get; set; }
        public string? KUND_A_BELEGHINWEIS { get; set; }
        public string? KUND_A_BIC { get; set; }
        public string? KUND_A_BLZ { get; set; }
        public string? KUND_A_DEBITORNR { get; set; }
        public string? KUND_A_EMAIL { get; set; } = String.Empty;
        public string? KUND_A_ENDTEXT_LS { get; set; }
        public string? KUND_A_ENDTEXT_RE { get; set; }
        public string? KUND_A_ERLOESKONTO { get; set; }
        public string? KUND_A_FACTORING { get; set; }
        public string? KUND_A_FAX { get; set; }
        public string? KUND_A_GLN { get; set; }
        public string? KUND_A_GLN_Z { get; set; }
        public string? KUND_A_HANDY { get; set; }
        public string? KUND_A_IBAN { get; set; }
        public string? KUND_A_KONTOINHABER { get; set; }
        public string KUND_A_LAND { get => _land; set => _land = (value ?? string.Empty).Trim(); }
        public string? KUND_A_LIEFNR { get; set; }
        public string? KUND_A_LIMITINFO { get; set; }
        public string KUND_A_NAME1 { get => _name1; set => _name1 = (value ?? string.Empty).Trim(); }
        public string KUND_A_NAME2 { get => _name2; set => _name2 = (value ?? string.Empty).Trim(); }
        public string KUND_A_NAME3 { get => _name3; set => _name3 = (value ?? string.Empty).Trim(); }
        public string KUND_A_NR { get; set; } = String.Empty;
        public string KUND_A_ORT { get => _ort; set => _ort = (value ?? string.Empty).Trim(); }
        public string? KUND_A_PARTNER_NR { get; set; }
        public string KUND_A_PLZ { get => _postleitzahl; set => _postleitzahl = (value ?? string.Empty).Trim(); }
        public string? KUND_A_PRODUKTETIKETT { get; set; }
        public string? KUND_A_SELEKTION1 { get; set; }
        public string? KUND_A_SELEKTION2 { get; set; }
        public string? KUND_A_SELEKTION3 { get; set; }
        public string? KUND_A_SELEKTION4 { get; set; }
        public string? KUND_A_SELEKTION5 { get; set; }
        public string? KUND_A_SELEKTION6 { get; set; }
        public string? KUND_A_SPERRVERMERK { get; set; }
        public string? KUND_A_SPERRVERMERK2 { get; set; }
        public string? KUND_A_SPRACHE { get; set; }
        public string? KUND_A_STEUERNR { get; set; }
        public string KUND_A_STRASSE { get => _strasse; set => _strasse = (value ?? string.Empty).Trim(); }
        public string? KUND_A_SUCHCODE { get; set; }
        public string? KUND_A_TEL1 { get; set; }
        public string? KUND_A_TEL2 { get; set; }
        public string? KUND_A_URL { get; set; }
        public string? KUND_A_USTIDNR { get; set; }
        public string KUND_A_WAEHRUNG { get; set; } = "EUR";
        public string? KUND_A_ZENTRALE { get; set; }
        public string? KUND_B_LASTKONTAKT { get; set; }
        public string? KUND_B_NOTIZ { get; set; }
        public string? KUND_B_WIEDERVORL { get; set; }
        public string? KUND_WK5_A_HRB { get; set; }
        public string? KUND_WK5_A_AMTSGERICHT { get; set; }
        public string? KUND_WK5_A_MANDATSREFERENZ { get; set; }
        public string? KUND_WK5_A_EMPFOHLEN_VON { get; set; }
        public string? KUND_WK5_A_LEITWEG_ID { get; set; }
        #endregion
        #region Logische Werte
        public bool KUND_L_AUSLAND { get; set; }
        public bool KUND_L_BAUDIENSTLEIST { get; set; }
        public bool KUND_L_BONUS { get; set; }
        public bool KUND_L_BRUTTOKUNDE { get; set; }
        public bool KUND_L_EUKUNDE { get; set; }
        public bool KUND_L_FRACHTFREI { get; set; }
        public bool KUND_L_FREISTELLBESCHEID { get; set; }
        public bool KUND_L_INTERESSENT { get; set; }
        public bool KUND_L_LIEFERNACHR { get; set; }
        public bool KUND_L_LS_MAIL { get; set; }
        public bool KUND_L_MAILING { get; set; }
        public bool KUND_L_MWST { get; set; }
        public bool KUND_L_NEUTRALVERSAND { get; set; }
        public bool KUND_L_PARGR13B { get; set; }
        public bool KUND_L_RE_MAIL { get; set; }
        public bool KUND_L_SONDERPREISE { get; set; }
        public bool KUND_L_SPERRE { get; set; }
        public bool KUND_L_SPERRE_LIEFERUNG { get; set; }
        public bool KUND_L_SPERRE_OP { get; set; } = true;
        [CompareField("KUND_L_NUR_RE_PDF")]
        public bool NurRechnungAlsPdf { get; set; }
        public bool KUND_WK5_L_XRECHNUNG { get; set; }
        #endregion
        #region DateTime Werte
        public DateTime KUND_D_ERFASSDATUM { get; set; }
        public DateTime KUND_D_LASTKONTAKT { get; set; }
        public DateTime KUND_D_PARGR13B { get; set; }
        public DateTime KUND_D_WIEDERVORL { get; set; }
        public DateTime KUND_TIMESTAMP { get; set; }
        #endregion
        #region Numerische Werte
        public int KUND_N_ABWEICH_RECHN { get; set; }
        public int KUND_N_ABWEICHLIEF { get; set; }
        public int KUND_N_BELTEXT_AN { get; set; }
        public int KUND_N_BELTEXT_AU { get; set; }
        public int KUND_N_BELTEXT_GU { get; set; }
        public int KUND_N_BELTEXT_LS { get; set; }
        public int KUND_N_BELTEXT_RE { get; set; }
        public int KUND_N_COLOR { get; set; }
        public int KUND_N_DR_AN { get; set; }
        public int KUND_N_DR_AU { get; set; }
        public int KUND_N_DR_GU { get; set; }
        public int KUND_N_DR_LS { get; set; }
        public int KUND_N_DR_RE { get; set; }
        public int KUND_N_FREISTELL_JAHR { get; set; }
        public int KUND_N_KUNDGRUPPE { get; set; }
        public int KUND_N_LASTUSER { get; set; }
        public int KUND_N_LIEFERUNG { get; set; }
        public int KUND_N_PL_ALTER { get; set; }
        public int KUND_N_PLVK { get; set; }
        public int KUND_N_PREISLISTNR { get; set; }
        public int KUND_N_RABATTKZ { get; set; }
        public int KUND_N_RECHART { get; set; }
        public int KUND_N_SPERRUSERID { get; set; }
        public int KUND_N_TOUR1 { get; set; }
        public int KUND_N_TOUR2 { get; set; }
        public int KUND_N_TOUR3 { get; set; }
        public int KUND_N_TOUR4 { get; set; }
        public int KUND_N_TOUR5 { get; set; }
        public int KUND_N_TOUR6 { get; set; }
        public int KUND_N_VERTRETNUMM { get; set; }
        public int KUND_N_ZAHLUNG { get; set; }
        public decimal KUND_N_BONUS1PROZ { get; set; }
        public decimal KUND_N_BONUS1WERT { get; set; }
        public decimal KUND_N_BONUS2PROZ { get; set; }
        public decimal KUND_N_BONUS2WERT { get; set; }
        public decimal KUND_N_BONUS3PROZ { get; set; }
        public decimal KUND_N_BONUS3WERT { get; set; }
        public decimal KUND_N_KREDITLIMIT { get; set; }
        public decimal KUND_N_VERT_PROV { get; set; }
        #endregion
        #region Werte aus WK5
        public bool KUND_WK5_L_REDRUCK { get; set; }
        public bool KUND_WK5_L_KEINMAILING { get; set; }
        public bool KUND_WK5_L_EXKUNDE { get; set; }
        public bool KUND_WK5_L_REMINDER { get; set; }
        [CompareField("KUND_L_KEINE_WARTUNGEN")]
        public bool KeineWartungen { get; set; }

        /// <summary>
        /// Gibt an, dass bei diesem Kunden Versandpreise manuell über onlinembe angefragt werden müssen.
        /// </summary>
        public bool KUND_WK5_L_VERSANDWARNUNG { get; set; }


        /// <summary>
        /// Ruft einen Wert ab, der angibt, ob der Vertrieb bei einer fehlenden UstId durch die automatische UstIdPrüfung benachrichtigt werden soll, oder nicht.
        /// </summary>
        /// <value>Wenn true, dann bekommt der Vertrieb keine Benachrichtigung</value>
        public bool KUND_WK5_L_USTIDFEHLTGEPRUEFT { get; set; }

        public string KUND_WK5_A_UST_NAME { get => _kund_wk5_ust_name; set => _kund_wk5_ust_name = value ?? String.Empty; }
        public string KUND_WK5_A_UST_STRASSE { get => _kund_wk5_ust_strasse; set => _kund_wk5_ust_strasse = value ?? String.Empty; }
        public string KUND_WK5_A_UST_PLZ { get => _kund_wk5_ust_plz; set => _kund_wk5_ust_plz = value ?? String.Empty; }
        public string KUND_WK5_A_UST_ORT { get => _kund_wk5_ust_ort; set => _kund_wk5_ust_ort = value ?? String.Empty; }


        [CompareField("KUND_WK5_L_USTID_GUELTIG")]
        public bool IstUstIdGültig { get; set; }
        [CompareField("KUND_WK5_D_USTID_GEPRUEFT_DATE")]
        public DateTime UstIdLastPrüfung { get; set; }

        public DateTime KUND_WK5_D_AUSSTELLUNG_MANDAT { get; set; }
        #endregion
        #endregion        
        public decimal OffenePosten { get; set; }
        [CompareField("OFFENE_AUFTRAEGE")]
        public decimal OffeneAufträge { get; set; }
        [CompareField("OFFENES_LIMIT")]
        public decimal OffenesKreditlimit { get; set; }

        /// <summary>
        /// Liefert zur zugehörigen Kundennummer den Kunden
        /// </summary>
        /// <param name="kundennummer"></param>
        /// <returns>Gibt ein Objekt der Klasse <see cref="Kunde"/> zurück. Wenn der Kunde nicht existiert, dann liefert die Funktion null zurück.</returns>
        public static async Task<Kunde?> GetKundeAsync(string kundennummer)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@KUND_A_NR", kundennummer);
            DataRow? row = await fbController.SelectRowAsync(@"SELECT K.*,
(SELECT CAST(REPLACE(IIF(COALESCE(INHALT,'')='','0.0',INHALT),',','.') AS TMONEY) FROM PROZ_LIMITPRUEFUNG(K.KUND_A_NR,2)) AS OFFENES_LIMIT,
(SELECT COALESCE(SUM(BELE_N_NETTO),0) FROM KUNDENBELEGE WHERE BELE_A_TYP = 'AU' AND COALESCE(BELE_L_ERLEDIGT,'N') = 'N' AND BELE_A_KUNDENNR = K.KUND_A_NR) AS OFFENE_AUFTRAEGE,
(SELECT SUM(OP) AS OFFENEPOSTEN FROM
(
select
BELE_A_TYP, 
CASE WHEN BELE_A_TYP = 'GU' THEN
     -COALESCE(SUM(BELE_N_BRUTTO), 0) - coalesce(SUM(BezahltBetrag), 0)
ELSE
     COALESCE(SUM(BELE_N_BRUTTO), 0) - coalesce(SUM(BezahltBetrag), 0)
END AS OP
from
  KUNDENBELEGE
where
  (
    (
      BELE_A_TYP ='RE'
    and BELE_L_BEZAHLT = 'N'
    ) or
   (BELE_A_TYP ='GU' and BELE_L_VERRECHNET = 'N' )
  )
 and BELE_A_KUNDENNR = K.KUND_A_NR
 GROUP BY BELE_A_TYP)
) FROM KUNDEN K WHERE K.KUND_A_NR = @KUND_A_NR");

            return row is null ? null : ObjectErweiterung.DataRowZuObjekt(new Kunde(), row);
        }

        /// <summary>
        /// Ruft alle freien Kundennummern aus der W4 ab.
        /// </summary>
        /// <returns></returns>
        public static async Task<List<int>> GetFreieKundennummernW4Async()
        {
            using FbController2 fbController = new FbController2();
            var kundenNummern = await fbController.SelectDataAsync("SELECT KUND_A_NR from KUNDEN where kund_a_nr SIMILAR TO '[0-9]+' AND cast(kunden.kund_a_nr as Int) > 10000 ORDER BY KUND_A_NR ASC");


            HashSet<int> w4Kunden = kundenNummern.AsEnumerable().Select(s => Convert.ToInt32(s.Field<string>("KUND_A_NR"))).ToHashSet<int>();
            var freieNummern = HashSetErweiterung.FindeFehlendeNummern(w4Kunden);
            // Es kann sein, dass alle Nummern lückenlos vergeben sind, dann nehmen wir die nächst höchste.
            if (!freieNummern.Any())
            {
                freieNummern.Append(w4Kunden.Max() + 1);
            }


            DataRow? nummernKreis = await fbController.SelectRowAsync("SELECT * FROM NUMKREISE WHERE NUMK_N_ID = 1");

            if (nummernKreis is not null)
            {
                var list = freieNummern.ToList();
                list.RemoveAll(x => x < nummernKreis.Field<int>("NUMK_N_KUND_VON") || x > nummernKreis.Field<int>("NUMK_N_KUND_BIS"));
                return list;
            }
            else
            {
                return freieNummern.ToList();
            }
        }

        public string NotizAsText
        {
            get
            {
                if (KUND_B_NOTIZ is null)
                {
                    return String.Empty;
                }
                return KUND_B_NOTIZ.Replace("\n", "<br>");
            }
        }

        public static async Task UpdateKundeAsync(Kunde kunde, int userId)
        {
            if (String.IsNullOrWhiteSpace(kunde.KUND_A_NR))
            {
                throw new ArgumentException("Der Kunde verfügt über keine Kundennummer");
            }

            using FbController2 fbController = new FbController2(userId);

            /*
             * Folgende Felder werden nicht upgedatet, da diese nur durch Software von uns konfiguriert werden:
             * KUND_WK5_L_EXKUNDE
             * KUND_WK5_L_KEINMAILING
             */
            #region Parameter
            fbController.AddParameter("@KUND_A_NAME1", kunde.KUND_A_NAME1.Trim());
            fbController.AddParameter("@KUND_A_NAME2", kunde.KUND_A_NAME2?.Trim());
            fbController.AddParameter("@KUND_A_NAME3", kunde.KUND_A_NAME3?.Trim());
            fbController.AddParameter("@KUND_A_STRASSE", kunde.KUND_A_STRASSE?.Trim());
            fbController.AddParameter("@KUND_A_ORT", kunde.KUND_A_ORT?.Trim());
            fbController.AddParameter("@KUND_A_LAND", kunde.KUND_A_LAND.Trim());
            fbController.AddParameter("@KUND_A_PLZ", kunde.KUND_A_PLZ?.Trim());
            fbController.AddParameter("@KUND_A_ANREDE", kunde.KUND_A_ANREDE?.Trim());
            fbController.AddParameter("@KUND_A_TEL1", kunde.KUND_A_TEL1?.Trim());
            fbController.AddParameter("@KUND_A_TEL2", kunde.KUND_A_TEL2?.Trim());
            fbController.AddParameter("@KUND_A_FAX", kunde.KUND_A_FAX?.Trim());
            fbController.AddParameter("@KUND_A_HANDY", kunde.KUND_A_HANDY?.Trim());
            fbController.AddParameter("@KUND_A_EMAIL", kunde.KUND_A_EMAIL?.Trim());
            fbController.AddParameter("@KUND_A_URL", kunde.KUND_A_URL?.Trim());
            fbController.AddParameter("@KUND_A_SUCHCODE", kunde.KUND_A_SUCHCODE?.Trim());
            fbController.AddParameter("@KUND_N_LIEFERUNG", kunde.KUND_N_LIEFERUNG);
            fbController.AddParameter("@KUND_N_ZAHLUNG", kunde.KUND_N_ZAHLUNG);
            fbController.AddParameter("@KUND_N_VERTRETNUMM", kunde.KUND_N_VERTRETNUMM);
            fbController.AddParameter("@KUND_N_PREISLISTNR", kunde.KUND_N_PREISLISTNR);
            fbController.AddParameter("@KUND_N_KREDITLIMIT", kunde.KUND_N_KREDITLIMIT);
            fbController.AddParameter("@KUND_A_DEBITORNR", kunde.KUND_A_DEBITORNR?.Trim());
            fbController.AddParameter("@KUND_A_USTIDNR", kunde.KUND_A_USTIDNR?.Trim());
            fbController.AddParameter("@KUND_A_STEUERNR", kunde.KUND_A_STEUERNR?.Trim());
            fbController.AddParameter("@KUND_A_LIEFNR", kunde.KUND_A_LIEFNR?.Trim());
            fbController.AddParameter("@KUND_A_GLN", kunde.KUND_A_GLN?.Trim());
            fbController.AddParameter("@KUND_L_MWST", kunde.KUND_L_MWST ? "Y" : "N");
            fbController.AddParameter("@KUND_L_SPERRE", kunde.KUND_L_SPERRE ? "Y" : "N");
            fbController.AddParameter("@KUND_L_SPERRE_OP", kunde.KUND_L_SPERRE_OP ? "Y" : "N");
            fbController.AddParameter("@KUND_L_FRACHTFREI", kunde.KUND_L_FRACHTFREI ? "Y" : "N");
            fbController.AddParameter("@KUND_L_NEUTRALVERSAND", kunde.KUND_L_NEUTRALVERSAND ? "Y" : "N");
            fbController.AddParameter("@KUND_L_BONUS", kunde.KUND_L_BONUS ? "Y" : "N");
            fbController.AddParameter("@KUND_A_SELEKTION1", kunde.KUND_A_SELEKTION1?.Trim());
            fbController.AddParameter("@KUND_A_SELEKTION2", kunde.KUND_A_SELEKTION2?.Trim());
            fbController.AddParameter("@KUND_A_SELEKTION3", kunde.KUND_A_SELEKTION3?.Trim());
            fbController.AddParameter("@KUND_A_SELEKTION4", kunde.KUND_A_SELEKTION4?.Trim());
            fbController.AddParameter("@KUND_A_SELEKTION5", kunde.KUND_A_SELEKTION5?.Trim());
            fbController.AddParameter("@KUND_A_SELEKTION6", kunde.KUND_A_SELEKTION6?.Trim());
            fbController.AddParameter("@KUND_WK5_L_REMINDER", kunde.KUND_WK5_L_REMINDER.ToFirebirdBool());
            fbController.AddParameter("@KUND_WK5_L_REDRUCK", kunde.KUND_WK5_L_REDRUCK.ToFirebirdBool());
            fbController.AddParameter("@KUND_L_AUSLAND", kunde.KUND_L_AUSLAND.ToFirebirdBool());
            fbController.AddParameter("@KUND_L_EUKUNDE", kunde.KUND_L_EUKUNDE.ToFirebirdBool());
            fbController.AddParameter("@KUND_N_KUNDGRUPPE", kunde.KUND_N_KUNDGRUPPE);
            fbController.AddParameter("@KUND_A_NR", kunde.KUND_A_NR);
            fbController.AddParameter("@KUND_WK5_L_VERSANDWARNUNG", kunde.KUND_WK5_L_VERSANDWARNUNG.ToFirebirdBool());
            fbController.AddParameter("@KUND_WK5_L_USTIDFEHLTGEPRUEFT", kunde.KUND_WK5_L_USTIDFEHLTGEPRUEFT.ToFirebirdBool());
            fbController.AddParameter("@KUND_B_NOTIZ", kunde.KUND_B_NOTIZ?.Trim());
            fbController.AddParameter("@KUND_WK5_A_HRB", kunde.KUND_WK5_A_HRB?.Trim());
            fbController.AddParameter("@KUND_WK5_A_AMTSGERICHT", kunde.KUND_WK5_A_AMTSGERICHT?.Trim());
            fbController.AddParameter("@KUND_A_IBAN", kunde.KUND_A_IBAN);
            fbController.AddParameter("@KUND_A_BIC", kunde.KUND_A_BIC);
            fbController.AddParameter("@KUND_A_BANKNAME", kunde.KUND_A_BANKNAME);
            fbController.AddParameter("@KUND_WK5_L_KEINMAILING", kunde.KUND_WK5_L_KEINMAILING.ToFirebirdBool());
            fbController.AddParameter("@KUND_WK5_A_UST_NAME", kunde.KUND_WK5_A_UST_NAME);
            fbController.AddParameter("@KUND_WK5_A_UST_STRASSE", kunde.KUND_WK5_A_UST_STRASSE);
            fbController.AddParameter("@KUND_WK5_A_UST_PLZ", kunde.KUND_WK5_A_UST_PLZ);
            fbController.AddParameter("@KUND_WK5_A_UST_ORT", kunde.KUND_WK5_A_UST_ORT);
            fbController.AddParameter("@KUND_WK5_A_MANDATSREFERENZ", kunde.KUND_WK5_A_MANDATSREFERENZ);
            fbController.AddParameter("@KUND_WK5_A_EMPFOHLEN_VON", kunde.KUND_WK5_A_EMPFOHLEN_VON);
            fbController.AddParameter("@KUND_WK5_D_AUSSTELLUNG_MANDAT", kunde.KUND_WK5_D_AUSSTELLUNG_MANDAT);
            fbController.AddParameter("@KUND_L_NUR_RE_PDF", kunde.NurRechnungAlsPdf);
            fbController.AddParameter("@KUND_L_KEINE_WARTUNGEN", kunde.KeineWartungen);
            fbController.AddParameter("@KUND_A_SPERRVERMERK", kunde.KUND_A_SPERRVERMERK);
            fbController.AddParameter("@KUND_WK5_A_LEITWEG_ID", kunde.KUND_WK5_A_LEITWEG_ID);
            fbController.AddParameter("@KUND_WK5_L_XRECHNUNG", kunde.KUND_WK5_L_XRECHNUNG);

            #endregion
            await fbController.QueryAsync(@"UPDATE KUNDEN SET
KUND_A_NAME1 = @KUND_A_NAME1, KUND_A_NAME2 = @KUND_A_NAME2, KUND_A_NAME3 = @KUND_A_NAME3,
KUND_A_STRASSE = @KUND_A_STRASSE, KUND_A_ORT = @KUND_A_ORT, KUND_A_PLZ = @KUND_A_PLZ, KUND_A_LAND = @KUND_A_LAND,
KUND_A_TEL1 = @KUND_A_TEL1, KUND_A_TEL2 = @KUND_A_TEL2, KUND_A_FAX = @KUND_A_FAX, KUND_A_HANDY = @KUND_A_HANDY,
KUND_A_SELEKTION1 = @KUND_A_SELEKTION1, KUND_A_SELEKTION2 = @KUND_A_SELEKTION2, KUND_A_SELEKTION3 = @KUND_A_SELEKTION3,
KUND_A_SELEKTION4 = @KUND_A_SELEKTION4, KUND_A_SELEKTION5 = @KUND_A_SELEKTION5, KUND_A_SELEKTION6 = @KUND_A_SELEKTION6,
KUND_A_EMAIL = @KUND_A_EMAIL, KUND_A_URL = @KUND_A_URL, KUND_A_ANREDE = @KUND_A_ANREDE, KUND_A_SUCHCODE = @KUND_A_SUCHCODE,
KUND_N_LIEFERUNG = @KUND_N_LIEFERUNG, KUND_N_ZAHLUNG = @KUND_N_ZAHLUNG, KUND_N_VERTRETNUMM = @KUND_N_VERTRETNUMM, 
KUND_N_PREISLISTNR = @KUND_N_PREISLISTNR, KUND_N_KREDITLIMIT = @KUND_N_KREDITLIMIT, KUND_A_DEBITORNR = @KUND_A_DEBITORNR,
KUND_A_USTIDNR = @KUND_A_USTIDNR, KUND_A_STEUERNR = @KUND_A_STEUERNR, KUND_A_LIEFNR = @KUND_A_LIEFNR,
KUND_A_GLN = @KUND_A_GLN, KUND_L_MWST = @KUND_L_MWST, KUND_L_SPERRE = @KUND_L_SPERRE, KUND_L_SPERRE_OP = @KUND_L_SPERRE_OP,
KUND_L_FRACHTFREI = @KUND_L_FRACHTFREI, KUND_L_NEUTRALVERSAND = @KUND_L_NEUTRALVERSAND, KUND_L_BONUS = @KUND_L_BONUS,
KUND_WK5_L_REMINDER = @KUND_WK5_L_REMINDER, KUND_WK5_L_REDRUCK = @KUND_WK5_L_REDRUCK,
KUND_L_AUSLAND = @KUND_L_AUSLAND, KUND_L_EUKUNDE = @KUND_L_EUKUNDE, KUND_N_KUNDGRUPPE = @KUND_N_KUNDGRUPPE,
KUND_WK5_L_VERSANDWARNUNG = @KUND_WK5_L_VERSANDWARNUNG, KUND_WK5_L_USTIDFEHLTGEPRUEFT = @KUND_WK5_L_USTIDFEHLTGEPRUEFT,
KUND_B_NOTIZ = @KUND_B_NOTIZ, KUND_WK5_A_HRB = @KUND_WK5_A_HRB, KUND_WK5_A_AMTSGERICHT = @KUND_WK5_A_AMTSGERICHT,
KUND_A_IBAN = @KUND_A_IBAN, KUND_A_BIC = @KUND_A_BIC, KUND_A_BANKNAME = @KUND_A_BANKNAME, KUND_WK5_L_KEINMAILING = @KUND_WK5_L_KEINMAILING,
KUND_WK5_A_UST_NAME = @KUND_WK5_A_UST_NAME, KUND_WK5_A_UST_STRASSE = @KUND_WK5_A_UST_STRASSE, KUND_WK5_A_UST_PLZ = @KUND_WK5_A_UST_PLZ, KUND_WK5_A_UST_ORT = @KUND_WK5_A_UST_ORT,
KUND_WK5_A_MANDATSREFERENZ = @KUND_WK5_A_MANDATSREFERENZ,
KUND_WK5_A_EMPFOHLEN_VON = @KUND_WK5_A_EMPFOHLEN_VON, KUND_WK5_D_AUSSTELLUNG_MANDAT = @KUND_WK5_D_AUSSTELLUNG_MANDAT,
KUND_L_NUR_RE_PDF = @KUND_L_NUR_RE_PDF,
KUND_L_KEINE_WARTUNGEN = @KUND_L_KEINE_WARTUNGEN,
KUND_A_SPERRVERMERK = @KUND_A_SPERRVERMERK,
KUND_WK5_A_LEITWEG_ID = @KUND_WK5_A_LEITWEG_ID,
KUND_WK5_L_XRECHNUNG = @KUND_WK5_L_XRECHNUNG
WHERE KUND_A_NR = @KUND_A_NR");

            await UpdateUstIdZuordnungAsync(kunde, fbController);
        }

        public VatRequest ToVatRequest()
        {
            if (String.IsNullOrWhiteSpace(KUND_WK5_A_UST_NAME))
            {
                return new VatRequest(KUND_A_USTIDNR, KUND_A_NAME1, KUND_A_ORT, KUND_A_PLZ, KUND_A_STRASSE, KUND_A_NR, false, VatZuordnung.Kunde, 0);
            }
            else
            {
                return new VatRequest(KUND_A_USTIDNR, KUND_WK5_A_UST_NAME, KUND_WK5_A_UST_ORT, KUND_WK5_A_UST_PLZ, KUND_WK5_A_UST_STRASSE, KUND_A_NR, true, VatZuordnung.Kunde, 0);
            }
        }

        private static async Task UpdateUstIdZuordnungAsync(Kunde kunde, FbController2 fbController)
        {
            fbController.AddParameter("@KUND_WK5_L_USTID_GUELTIG", kunde.IstUstIdGültig);
            fbController.AddParameter("@KUND_A_NR", kunde.KUND_A_NR);
            fbController.AddParameter("@KULA_WK5_D_USTID_GEPRUEFT_DATE", kunde.UstIdLastPrüfung);
            await fbController.QueryAsync("UPDATE KUNDEN SET KUND_WK5_L_USTID_GUELTIG = @KUND_WK5_L_USTID_GUELTIG, KUND_WK5_D_USTID_GEPRUEFT_DATE = @KULA_WK5_D_USTID_GEPRUEFT_DATE WHERE KUND_A_NR = @KUND_A_NR");

            fbController.AddParameter("@KULA_WK5_L_USTID_GUELTIG", kunde.IstUstIdGültig);
            fbController.AddParameter("@KULA_A_LAND", kunde.KUND_A_LAND);
            fbController.AddParameter("@KULA_A_KUNDNR", kunde.KUND_A_NR);
            fbController.AddParameter("@KULA_WK5_D_USTID_GEPRUEFT_DATE", kunde.UstIdLastPrüfung);
            await fbController.QueryAsync("UPDATE LIEFERANSCHRIFTEN SET KULA_WK5_L_USTID_GUELTIG = @KULA_WK5_L_USTID_GUELTIG, KULA_WK5_D_USTID_GEPRUEFT_DATE = @KULA_WK5_D_USTID_GEPRUEFT_DATE WHERE KULA_A_LAND = @KULA_A_LAND AND KULA_A_KUNDNR = @KULA_A_KUNDNR");
        }
        public static async Task<Kunde> CreateKundeAsync(Kunde kunde, int userId)
        {
            using FbController2 fbController = new FbController2(userId);
            await fbController.StartTransactionAsync();
            List<int> freiKundennummern = await Kunde.GetFreieKundennummernW4Async();
            if (freiKundennummern.Count < 1)
            {
                throw new IndexOutOfRangeException("Es konnte keine freie Kundennummer innerhalb des Nummernkreis gefunden werden");
            }
            int kundennummer = freiKundennummern.First();
            #region Parameter
            fbController.AddParameter("@KUND_A_NR", kundennummer.ToString());
            fbController.AddParameter("@KUND_A_NAME1", kunde.KUND_A_NAME1.Trim());
            fbController.AddParameter("@KUND_A_NAME2", kunde.KUND_A_NAME2?.Trim());
            fbController.AddParameter("@KUND_A_NAME3", kunde.KUND_A_NAME3?.Trim());
            fbController.AddParameter("@KUND_A_STRASSE", kunde.KUND_A_STRASSE?.Trim());
            fbController.AddParameter("@KUND_A_LAND", kunde.KUND_A_LAND?.Trim());
            fbController.AddParameter("@KUND_A_PLZ", kunde.KUND_A_PLZ?.Trim());
            fbController.AddParameter("@KUND_A_ORT", kunde.KUND_A_ORT?.Trim());
            fbController.AddParameter("@KUND_A_TEL1", kunde.KUND_A_TEL1?.Trim());
            fbController.AddParameter("@KUND_A_TEL2", kunde.KUND_A_TEL2?.Trim());
            fbController.AddParameter("@KUND_A_FAX", kunde.KUND_A_FAX?.Trim());
            fbController.AddParameter("@KUND_A_EMAIL", kunde.KUND_A_EMAIL?.Trim());
            fbController.AddParameter("@KUND_A_ANREDE", kunde.KUND_A_ANREDE?.Trim());
            fbController.AddParameter("@KUND_A_USTIDNR", kunde.KUND_A_USTIDNR?.Trim());
            fbController.AddParameter("@KUND_N_KUNDGRUPPE", kunde.KUND_N_KUNDGRUPPE);
            fbController.AddParameter("@KUND_N_PREISLISTNR", kunde.KUND_N_PREISLISTNR);
            fbController.AddParameter("@KUND_N_ZAHLUNG", kunde.KUND_N_ZAHLUNG);
            fbController.AddParameter("@KUND_N_LASTUSER", kunde.KUND_N_LASTUSER);
            fbController.AddParameter("@KUND_N_VERTRETNUMM", kunde.KUND_N_VERTRETNUMM);
            fbController.AddParameter("@KUND_N_LIEFERUNG", kunde.KUND_N_LIEFERUNG);
            fbController.AddParameter("@KUND_L_MWST", kunde.KUND_L_MWST.ToFirebirdBool());
            fbController.AddParameter("@KUND_L_BRUTTOKUNDE", kunde.KUND_L_BRUTTOKUNDE.ToFirebirdBool());
            fbController.AddParameter("@KUND_A_URL", kunde.KUND_A_URL?.Trim());
            fbController.AddParameter("@KUND_A_SELEKTION1", kunde.KUND_A_SELEKTION1?.Trim());
            fbController.AddParameter("@KUND_A_SELEKTION2", kunde.KUND_A_SELEKTION2?.Trim());
            fbController.AddParameter("@KUND_A_SELEKTION3", kunde.KUND_A_SELEKTION3?.Trim());
            fbController.AddParameter("@KUND_A_SELEKTION4", kunde.KUND_A_SELEKTION4?.Trim());
            fbController.AddParameter("@KUND_A_SELEKTION5", kunde.KUND_A_SELEKTION5?.Trim());
            fbController.AddParameter("@KUND_A_SELEKTION6", kunde.KUND_A_SELEKTION6?.Trim());
            fbController.AddParameter("@KUND_L_EUKUNDE", kunde.KUND_L_EUKUNDE.ToFirebirdBool());
            fbController.AddParameter("@KUND_L_AUSLAND", kunde.KUND_L_AUSLAND.ToFirebirdBool());
            fbController.AddParameter("@KUND_WK5_L_REMINDER", kunde.KUND_WK5_L_REMINDER.ToFirebirdBool());
            fbController.AddParameter("@KUND_WK5_L_REDRUCK", kunde.KUND_WK5_L_REDRUCK.ToFirebirdBool());
            fbController.AddParameter("@KUND_N_KREDITLIMIT", kunde.KUND_N_KREDITLIMIT);
            fbController.AddParameter("@KUND_A_DEBITORNR", kunde.KUND_A_DEBITORNR?.Trim());
            fbController.AddParameter("@KUND_A_STEUERNR", kunde.KUND_A_STEUERNR?.Trim());
            fbController.AddParameter("@KUND_A_LIEFNR", kunde.KUND_A_LIEFNR?.Trim());
            fbController.AddParameter("@KUND_A_GLN", kunde.KUND_A_GLN?.Trim());
            fbController.AddParameter("@KUND_A_HANDY", kunde.KUND_A_HANDY?.Trim());
            fbController.AddParameter("@KUND_A_SUCHCODE", kunde.KUND_A_SUCHCODE?.Trim());
            fbController.AddParameter("@KUND_L_SPERRE", kunde.KUND_L_SPERRE.ToFirebirdBool());
            fbController.AddParameter("@KUND_L_SPERRE_OP", kunde.KUND_L_SPERRE_OP.ToFirebirdBool());
            fbController.AddParameter("@KUND_L_FRACHTFREI", kunde.KUND_L_FRACHTFREI.ToFirebirdBool());
            fbController.AddParameter("@KUND_L_NEUTRALVERSAND", kunde.KUND_L_NEUTRALVERSAND.ToFirebirdBool());
            fbController.AddParameter("@KUND_L_BONUS", kunde.KUND_L_BONUS.ToFirebirdBool());
            fbController.AddParameter("@KUND_WK5_L_VERSANDWARNUNG", kunde.KUND_WK5_L_VERSANDWARNUNG.ToFirebirdBool());
            fbController.AddParameter("@KUND_WK5_L_USTIDFEHLTGEPRUEFT", kunde.KUND_WK5_L_USTIDFEHLTGEPRUEFT.ToFirebirdBool());
            fbController.AddParameter("@KUND_B_NOTIZ", kunde.KUND_B_NOTIZ?.Trim());
            fbController.AddParameter("@KUND_A_IBAN", kunde.KUND_A_IBAN);
            fbController.AddParameter("@KUND_A_BIC", kunde.KUND_A_BIC);
            fbController.AddParameter("@KUND_A_BANKNAME", kunde.KUND_A_BANKNAME);
            fbController.AddParameter("@KUND_WK5_A_HRB", kunde.KUND_WK5_A_HRB?.Trim());
            fbController.AddParameter("@KUND_WK5_A_AMTSGERICHT", kunde.KUND_WK5_A_AMTSGERICHT?.Trim());
            fbController.AddParameter("@KUND_WK5_L_KEINMAILING", kunde.KUND_WK5_L_KEINMAILING.ToFirebirdBool());
            fbController.AddParameter("@KUND_WK5_A_UST_NAME", kunde.KUND_WK5_A_UST_NAME);
            fbController.AddParameter("@KUND_WK5_A_UST_STRASSE", kunde.KUND_WK5_A_UST_STRASSE);
            fbController.AddParameter("@KUND_WK5_A_UST_PLZ", kunde.KUND_WK5_A_UST_PLZ);
            fbController.AddParameter("@KUND_WK5_A_UST_ORT", kunde.KUND_WK5_A_UST_ORT);
            fbController.AddParameter("@KUND_WK5_A_MANDATSREFERENZ", kunde.KUND_WK5_A_MANDATSREFERENZ);
            fbController.AddParameter("@KUND_WK5_A_EMPFOHLEN_VON", kunde.KUND_WK5_A_EMPFOHLEN_VON);
            fbController.AddParameter("@KUND_WK5_D_AUSSTELLUNG_MANDAT", kunde.KUND_WK5_D_AUSSTELLUNG_MANDAT);
            fbController.AddParameter("@KUND_L_NUR_RE_PDF", kunde.NurRechnungAlsPdf);
            fbController.AddParameter("@KUND_L_KEINE_WARTUNGEN", kunde.KeineWartungen);
            fbController.AddParameter("@KUND_A_SPERRVERMERK", kunde.KUND_A_SPERRVERMERK);
            fbController.AddParameter("@KUND_WK5_A_LEITWEG_ID", kunde.KUND_WK5_A_LEITWEG_ID);
            fbController.AddParameter("@KUND_WK5_L_XRECHNUNG", kunde.KUND_WK5_L_XRECHNUNG);
            #endregion

            await fbController.QueryAsync(@"INSERT INTO KUNDEN
(
KUND_A_NR, KUND_A_NAME1, KUND_A_NAME2, KUND_A_NAME3, KUND_A_STRASSE, KUND_A_LAND, KUND_A_PLZ, KUND_A_ORT,
KUND_A_TEL1, KUND_A_TEL2, KUND_A_FAX, KUND_A_EMAIL, KUND_A_ANREDE, KUND_L_SPERRE, KUND_A_USTIDNR, KUND_N_KUNDGRUPPE, 
KUND_N_PREISLISTNR, KUND_A_WAEHRUNG, KUND_N_VERTRETNUMM, KUND_N_LIEFERUNG, KUND_N_ZAHLUNG, KUND_L_MWST, KUND_L_BRUTTOKUNDE, 
KUND_A_SELEKTION1, KUND_A_SELEKTION2, KUND_A_SELEKTION3, KUND_A_SELEKTION4, KUND_A_SELEKTION5, KUND_A_SELEKTION6, 
KUND_TIMESTAMP, KUND_N_LASTUSER, KUND_A_URL, KUND_D_ERFASSDATUM, KUND_L_EUKUNDE, KUND_L_AUSLAND,
KUND_WK5_L_REMINDER, KUND_WK5_L_REDRUCK, KUND_N_KREDITLIMIT, KUND_A_DEBITORNR, KUND_A_STEUERNR, KUND_A_LIEFNR, KUND_A_GLN,
KUND_A_HANDY, KUND_A_SUCHCODE, KUND_L_SPERRE_OP, KUND_L_FRACHTFREI, KUND_L_NEUTRALVERSAND, KUND_L_BONUS,
KUND_WK5_L_VERSANDWARNUNG, KUND_WK5_L_USTIDFEHLTGEPRUEFT, KUND_B_NOTIZ, KUND_A_IBAN, KUND_A_BIC, KUND_A_BANKNAME, 
KUND_WK5_A_HRB, KUND_WK5_A_AMTSGERICHT, KUND_WK5_L_KEINMAILING,
KUND_WK5_A_UST_NAME, KUND_WK5_A_UST_STRASSE, KUND_WK5_A_UST_PLZ, KUND_WK5_A_UST_ORT, KUND_WK5_A_MANDATSREFERENZ,
KUND_WK5_A_EMPFOHLEN_VON, KUND_WK5_D_AUSSTELLUNG_MANDAT, KUND_L_NUR_RE_PDF,
KUND_L_KEINE_WARTUNGEN, KUND_A_SPERRVERMERK, KUND_WK5_A_LEITWEG_ID,
KUND_WK5_L_XRECHNUNG
)
VALUES
(
@KUND_A_NR, @KUND_A_NAME1, @KUND_A_NAME2, @KUND_A_NAME3, @KUND_A_STRASSE, @KUND_A_LAND, @KUND_A_PLZ, @KUND_A_ORT,
@KUND_A_TEL1, @KUND_A_TEL2, @KUND_A_FAX, @KUND_A_EMAIL, @KUND_A_ANREDE, @KUND_L_SPERRE, @KUND_A_USTIDNR, @KUND_N_KUNDGRUPPE,
@KUND_N_PREISLISTNR, 'EUR', @KUND_N_VERTRETNUMM, @KUND_N_LIEFERUNG, @KUND_N_ZAHLUNG, @KUND_L_MWST, @KUND_L_BRUTTOKUNDE,
@KUND_A_SELEKTION1, @KUND_A_SELEKTION2, @KUND_A_SELEKTION3, @KUND_A_SELEKTION4, @KUND_A_SELEKTION5, @KUND_A_SELEKTION6, 
CURRENT_TIMESTAMP, @KUND_N_LASTUSER, @KUND_A_URL, CURRENT_DATE, @KUND_L_EUKUNDE, @KUND_L_AUSLAND,
@KUND_WK5_L_REMINDER, @KUND_WK5_L_REDRUCK, @KUND_N_KREDITLIMIT, @KUND_A_DEBITORNR, @KUND_A_STEUERNR, @KUND_A_LIEFNR, @KUND_A_GLN,
@KUND_A_HANDY, @KUND_A_SUCHCODE, @KUND_L_SPERRE_OP, @KUND_L_FRACHTFREI, @KUND_L_NEUTRALVERSAND, @KUND_L_BONUS,
@KUND_WK5_L_VERSANDWARNUNG, @KUND_WK5_L_USTIDFEHLTGEPRUEFT, @KUND_B_NOTIZ, @KUND_A_IBAN, @KUND_A_BIC, @KUND_A_BANKNAME,
@KUND_WK5_A_HRB, @KUND_WK5_A_AMTSGERICHT, @KUND_WK5_L_KEINMAILING,
@KUND_WK5_A_UST_NAME, @KUND_WK5_A_UST_STRASSE, @KUND_WK5_A_UST_PLZ, @KUND_WK5_A_UST_ORT, @KUND_WK5_A_MANDATSREFERENZ,
@KUND_WK5_A_EMPFOHLEN_VON, @KUND_WK5_D_AUSSTELLUNG_MANDAT, @KUND_L_NUR_RE_PDF,
@KUND_L_KEINE_WARTUNGEN, @KUND_A_SPERRVERMERK, @KUND_WK5_A_LEITWEG_ID,
@KUND_WK5_L_XRECHNUNG
)");

            //Änderungen für Englische Formulare bei Ländern != DE,CH,AT
            if (kunde.KUND_A_LAND != "DE" && kunde.KUND_A_LAND != "CH" && kunde.KUND_A_LAND != "AT")
            {
                fbController.AddParameter("@KUND_A_NR", kundennummer);
                await fbController.QueryAsync(@"UPDATE kunden SET 
KUND_N_BELTEXT_AN = 2, KUND_N_DR_AN = 1, 
KUND_N_BELTEXT_AU = 3, KUND_N_DR_AU = 1,
KUND_N_BELTEXT_LS = 4, KUND_N_DR_LS = 1, 
KUND_A_ENDTEXT_LS = 'LF_FUSSE', KUND_N_BELTEXT_RE = 5, 
KUND_N_DR_RE = 1, KUND_A_ENDTEXT_RE = 'RE_FUSSE' 
WHERE KUND_A_NR = @KUND_A_NR");

            }



            kunde.KUND_A_NR = kundennummer.ToString();
            await UpdateUstIdZuordnungAsync(kunde, fbController);
            await fbController.CommitChangesAsync();

            return kunde;
        }


        public static async Task<bool> IstErstkundeAsync(string kundennummer)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@BELE_A_KUNDENNR", kundennummer);
            var anzahlRechnungen = Convert.ToInt32(await fbController.FetchObjectAsync("SELECT COUNT(*) FROM BELEGE WHERE BELE_A_TYP = 'RE' AND BELE_A_KUNDENNR = @BELE_A_KUNDENNR"));

            return anzahlRechnungen <= 1;
        }

        public static async IAsyncEnumerable<string> GetGeworbeneKunden(string KUND_A_NR)
        {
            string sql = "SELECT KUND_A_NR FROM KUNDEN WHERE KUND_WK5_A_EMPFOHLEN_VON = @KUND_A_NR";

            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@KUND_A_NR", KUND_A_NR);

            DataTable data = await fbController.SelectDataAsync(sql);

            foreach (DataRow row in data.Rows)
            {
                if (row is not null)
                {
                    yield return row.Field<string>("KUND_A_NR")!;
                }
            }
        }

        /// <summary>
        /// Prüft ob für einen Kunden das Kreditlimit überschritten wurde
        /// </summary>
        /// <param name="rest">Der Rest der vom Kreditlimit übrig bleibt</param>
        /// <param name="zahlungsart">Die Zahlungsart des Beleg. Wenn der Beleg Vorkasse ist entfällt die Kreditlimit Prüfung</param>
        /// <returns>Gibt einen <see cref="bool"/> zurück der angibt ob das Kreditlimit überschritten wurde</returns>
        public async Task<(bool überschritten, decimal rest)> KreditlimitÜberschrittenAsync(int zahlungsart, ZahlungsbedingungCollection zahlungsbedingungen)
        {
            if (zahlungsbedingungen.IstVorkasse(zahlungsart))
            {
                return (false, KUND_N_KREDITLIMIT);
            }
            if (KUND_N_KREDITLIMIT <= 0)
            {
                return (false, 0);
            }

            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@KUNDNR", KUND_A_NR);
            string sql = "SELECT INHALT FROM PROZ_LIMITPRUEFUNG(@KUNDNR,2)";
            object? limit = await fbController.FetchObjectAsync(sql);

            if (limit is null)
            {
                return (false, 0);
            }

            _ = decimal.TryParse(limit.ToString(), out decimal freiesKreditlimit);


            return (freiesKreditlimit <= 0, freiesKreditlimit);
        }

        public static async Task DeleteKundeAsync(string kundnr, FbController2 fbController)
        {
            if (!await IsKundeDeletable(kundnr))
            {
                throw new Exception("Kunde kann nicht gelöscht werden solange er noch in Belegen vorhanden ist!");
            }

            string sql = "UPDATE BELEGE SET BELE_A_KUNDENNR = 0 WHERE BELE_D_DATE <= @DATE AND BELE_A_KUNDENNR = @KUNDNR AND BELE_A_TYP = @TYP";
            fbController.AddParameter("@KUNDNR", kundnr);
            fbController.AddParameter("@DATE", new DateTime(DateTime.Now.Year - 8, 12, 31));
            fbController.AddParameter("@TYP", "AN");
            await fbController.QueryAsync(sql);


            List<string> queries = new List<string>()
            {
                "DELETE FROM ANSPRECHPARTNER WHERE PART_A_KUNDNR = @KUNDNR",
                "DELETE FROM BELEG_CHANGE WHERE BCNG_A_BELEGTYP = 'KU' AND BCNG_N_BELEGNR = @KUNDNR",
                "DELETE FROM KUNDENKONTAKTE WHERE KUKO_A_KUNDNR = @KUNDNR",
                "DELETE FROM KUNDENSACHNUMMER WHERE KUSA_A_KUNDE = @KUNDNR",
                "DELETE FROM KUNDENRECHNANSCHR WHERE KURE_A_KUNDNR = @KUNDNR",
                "DELETE FROM KUNDENRABATTE WHERE KURA_A_KUNDE = @KUNDNR",
                "DELETE FROM WK5_WERBEMITTEL_ZU_KUNDE WHERE WZK_A_KUNDENNR = @KUNDNR",
                "DELETE FROM WK5_KUNDEN_ZUSATZ WHERE KUNDZU_A_NR = @KUNDNR",
                "DELETE FROM WK5_WICHTIGKEIT_KUNDEN WHERE WICH_A_KUNDNR = @KUNDNR",
                "DELETE FROM LIEFERANSCHRIFTEN WHERE KULA_A_KUNDNR = @KUNDNR",
                "DELETE FROM KUNDEN WHERE KUND_A_NR = @KUNDNR"
            };

            foreach (string query in queries)
            {
                fbController.AddParameter("@KUNDNR", kundnr);
                await fbController.QueryAsync(query);
            }
        }

        public static async Task<bool> IsKundeDeletable(string kundnr)
        {
            string belegeExistsQuery = "SELECT BELE_A_TYP,BELE_N_NR FROM BELEGE WHERE BELE_A_TYP IN ('AU','LS','RE','GU') AND BELE_A_KUNDENNR = @KUNDNR";
            string alteAngeboteQuery = "SELECT BELE_A_TYP, BELE_N_NR FROM BELEGE WHERE BELE_D_DATE > @DATE AND BELE_A_KUNDENNR = @KUNDNR AND BELE_A_TYP = @TYP";

            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@KUNDNR", kundnr);

            DataTable belegData = await fbController.SelectDataAsync(belegeExistsQuery);

            if (belegData.Rows.Count > 0) { return false; }


            fbController.AddParameter("@KUNDNR", kundnr);
            fbController.AddParameter("@TYP", "AN");
            fbController.AddParameter("@DATE", new DateTime(DateTime.Now.Year - 8, 12, 31));

            DataTable angebotData = await fbController.SelectDataAsync(alteAngeboteQuery);
            if (angebotData.Rows.Count > 0) { return false; }

            return true;
        }

        public static async Task UpdateParsedTelefonnummern(string kundennummer, FbController2? fbController = null)
        {            
            Kunde? kunde = await Kunde.GetKundeAsync(kundennummer);
            if(kunde is not null)
            {
                await kunde.UpdateParsedTelefonnummern(fbController);
            }
        }

        public async Task UpdateParsedTelefonnummern(FbController2? fbController = null)
        {
            await Telefonnummer.DeleteAsync(KUND_A_NR, "KU", fbController);
            if (!String.IsNullOrWhiteSpace(KUND_A_TEL1))
            {
                await Telefonnummer.InsertOrUpdateAsync(KUND_A_NR, "KU", Telefonnummer.Sanitize(KUND_A_TEL1), fbController);
            }

            if (!String.IsNullOrWhiteSpace(KUND_A_TEL2))
            {
                await Telefonnummer.InsertOrUpdateAsync(KUND_A_NR, "KU", Telefonnummer.Sanitize(KUND_A_TEL2), fbController);
            }

            if (!String.IsNullOrWhiteSpace(KUND_A_HANDY))
            {
                await Telefonnummer.InsertOrUpdateAsync(KUND_A_NR, "KU", Telefonnummer.Sanitize(KUND_A_HANDY), fbController);
            }

            List<Ansprechpartner> partner = await Ansprechpartner.GetAnsprechpartnerAsync(KUND_A_NR).ToListAsync();
            foreach (Ansprechpartner part in partner)
            {
                if (!String.IsNullOrWhiteSpace(part.PART_A_TELEFON))
                {
                    await Telefonnummer.InsertOrUpdateAsync(part.PART_A_KUNDNR, "KU", Telefonnummer.Sanitize(part.PART_A_TELEFON), fbController);
                }

                if (!String.IsNullOrWhiteSpace(part.PART_A_MOBIL))
                {
                    await Telefonnummer.InsertOrUpdateAsync(part.PART_A_KUNDNR, "KU", Telefonnummer.Sanitize(part.PART_A_MOBIL), fbController);
                }
            }

            List<Lieferanschrift> lieferanschriften = await Lieferanschrift.GetLieferanschriftenAsync(KUND_A_NR).ToListAsync();
            foreach (Lieferanschrift lieferanschrift in lieferanschriften)
            {
                if (!String.IsNullOrWhiteSpace(lieferanschrift.KULA_A_TEL))
                {
                    await Telefonnummer.InsertOrUpdateAsync(lieferanschrift.KULA_A_KUNDNR, "KU", Telefonnummer.Sanitize(lieferanschrift.KULA_A_TEL), fbController);
                }
            }

            List<Rechnungsanschrift> rechnungsanschriften = await Rechnungsanschrift.GetRechnungsanschriftenAsync(KUND_A_NR).ToListAsync();
            foreach (Rechnungsanschrift rechnungsanschrift in rechnungsanschriften)
            {
                if (!String.IsNullOrWhiteSpace(rechnungsanschrift.KURE_A_TEL))
                {
                    await Telefonnummer.InsertOrUpdateAsync(rechnungsanschrift.KURE_A_KUNDNR, "KU", Telefonnummer.Sanitize(rechnungsanschrift.KURE_A_TEL), fbController);
                }
            }
        }
    }
}
