using System;
using System.Collections.Generic;

namespace WK5.Core.Basis.Filter
{
    public class BelegÜbersichtFilter : PageFilter
    {
        private int _phase = 1;
        public const int MaxPhase = 5;
        public const int MinPhase = 1;
        public const int AbortableUntilPhase = 2;

        public int Phase
        {
            get
            {
                if (_phase < MinPhase)
                {
                    return MinPhase;
                }
                else if (_phase > MaxPhase)
                {
                    return MaxPhase;
                }
                else
                {
                    return _phase;
                }
            }

            set
            {
                if (value < MinPhase)
                {
                    _phase = MinPhase;
                }
                else if (value > MaxPhase)
                {
                    _phase = MaxPhase;
                }
                else
                {
                    _phase = value;
                }
            }
        }
        public bool DoPhaseSearch => !String.IsNullOrWhiteSpace(Suchbegriff);

        public bool IsFilterActive
        {
            get
            {
                if (!String.IsNullOrWhiteSpace(Suchbegriff))
                {
                    return true;
                }
                if (Sammelrechnung)
                {
                    return true;
                }

                if (Erledigt)
                {
                    return true;
                }

                if (Direktlieferung)
                {
                    return true;
                }

                if (AngebotsNummer > 0)
                {
                    return true;
                }

                if (AuftragsNummer > 0)
                {
                    return true;
                }

                if (LieferscheinNummer > 0)
                {
                    return true;
                }

                if (RechnungsNummer > 0)
                {
                    return true;
                }

                if (GutschriftsNummer > 0)
                {
                    return true;
                }

                if (ZeitraumFiltern)
                {
                    return true;
                }

                if (Bezahlt)
                {
                    return true;
                }

                if (Neutral)
                {
                    return true;
                }

                if (Pausiert)
                {
                    return true;
                }

                if (Sammelrechnung)
                {
                    return true;
                }

                if (Wiedervorlage)
                {
                    return true;
                }


                if (Vertreter > 0)
                {
                    return true;
                }


                if (Zahlungsbedingung > 0)
                {
                    return true;
                }

                if (Lieferbedingung > 0)
                {
                    return true;
                }

                if(NurTechnikbelege)
                {
                    return true;
                }

                return false;
            }
        }
        private void BuildPhase1Condition(FbController2 fbController)
        {
            sqlBuilder.Append(" CAST(UPPER(BELE_N_NR) AS VARCHAR(255)) = @SUCHBEGRIFF OR CAST(UPPER(BELE_A_KUNDENNR) AS VARCHAR(255)) = @SUCHBEGRIFF ");
            fbController.AddParameter("@SUCHBEGRIFF", Suchbegriff.ToUpper());
        }

        private void BuildPhase2Condition(FbController2 fbController)
        {
            List<string> searches = new List<string>();
            foreach (string suchfeld in Suchfelder)
            {
                searches.Add($" CAST(UPPER({suchfeld}) AS VARCHAR(255)) = @SUCHBEGRIFF ");
            }

            sqlBuilder.Append(String.Join(" OR ", searches));

            fbController.AddParameter("@SUCHBEGRIFF", Suchbegriff.ToUpper());
        }
        private void BuildPhase3Condition(FbController2 fbController)
        {
            List<string> searches = new List<string>();
            foreach (string suchfeld in Suchfelder)
            {
                searches.Add($" CAST(UPPER({suchfeld}) AS VARCHAR(255)) SIMILAR TO @SUCHBEGRIFF escape '\\'");
            }

            sqlBuilder.Append(String.Join(" OR ", searches));

            fbController.AddParameter("@SUCHBEGRIFF", $"%{FbController2.SanitizeRegex(Suchbegriff).Replace(' ', '_')}%");
        }

        private void BuildPhase4Condition(FbController2 fbController)
        {
            List<string> searches = new List<string>();
            int zähler = 0;
            foreach (string suchfeld in Suchfelder)
            {
                List<string> subsearches = new List<string>();
                foreach (string token in Suchbegriff.Split(' ', '-', '_', ','))
                {
                    zähler++;
                    subsearches.Add($" CAST(UPPER({suchfeld}) AS VARCHAR(255)) SIMILAR TO @SUCHBEGRIFF{zähler} escape '\\' ");
                    fbController.AddParameter($"@SUCHBEGRIFF{zähler}", $"%{FbController2.SanitizeRegex(token)}%");
                }

                searches.Add($"({String.Join(" AND ", subsearches)})");
            }

            sqlBuilder.Append(String.Join(" OR ", searches));
        }

        private void BuildPhase5Condition(FbController2 fbController)
        {
            List<string> searches = new List<string>();
            int zähler = 0;
            foreach (string suchfeld in Suchfelder)
            {
                List<string> subsearches = new List<string>();
                foreach (string token in Suchbegriff.Split(' ', '-', '_', ','))
                {
                    zähler++;
                    subsearches.Add($" CAST(UPPER({suchfeld}) AS VARCHAR(255)) SIMILAR TO @SUCHBEGRIFF{zähler} escape '\\' ");
                    fbController.AddParameter($"@SUCHBEGRIFF{zähler}", $"%{FbController2.SanitizeRegex(token)}%");
                }

                searches.Add($"({String.Join(" OR ", subsearches)})");
            }

            sqlBuilder.Append(String.Join(" OR ", searches));

            fbController.AddParameter("@SUCHBEGRIFF", $"%{Suchbegriff}%");
        }

        private List<string> Suchfelder { get; set; } = new List<string>()
        {
            "BELE_N_NR",
            "BELE_A_NAME1",
            "BELE_A_NAME2",
            "BELE_A_NAME3",
            "BELE_A_KUNDENNR",
            "BELE_A_ORT",
            "BELE_A_STRASSE",
            "BELE_A_BESTAET_NR",
            "WK5_BELE_A_TRANSAKTIONS_ID"
        };
        public override string ToCountQuery(FbController2 fbController)
        {
            sqlBuilder.Clear();
            sqlBuilder.Append("SELECT COUNT(*) FROM BELEGE WHERE 1=1");
            BuildQueryConditions(fbController);
            return sqlBuilder.ToString();
        }

        public override string ToSqlQuery(FbController2 fbController)
        {
            sqlBuilder.Clear();

            // Kunden Name, TEL
            sqlBuilder.Append($@"SELECT FIRST {Limit} SKIP {(Seite - 1) * Limit}
BELE_N_NR, BELE_A_TYP, BELE_A_NAME1, BELE_A_NAME2, BELE_A_NAME3, BELE_A_ORT, BELE_A_PLZ, BELE_A_LAND, BELE_A_STRASSE,
BELE_A_KUNDENNR, BELE_N_NETTO, BELE_N_BRUTTO, BELE_N_MWST,BELE_N_MWST_SATZ1, BELE_A_STATUSFELD, BELE_D_DATE, BELE_A_GRUPPE, WK5_BELE_L_DIREKTLIEFERUNG,
BELE_A_BESTAET_NR, BELE_N_NR_AN, BELE_N_NR_AU, BELE_N_NR_LS, BELE_N_NR_RE, BELE_N_NR_GU, BELE_D_LIEFERDATE, BELE_D_NACHFRAGDAT,
BELE_D_FIBUUEBERGDATE, BELE_L_ARCHIVIERT_KARLEY, BELE_L_ERLEDIGT, BELE_L_FIBUUEBERGABE, BELE_L_MWST, BELE_L_NEUTRAL, BELE_N_ANLAGEUSER,
BELE_N_VERTRETER, BELE_N_LIEFERUNG, BELE_N_ZAHLUNG, WK5_BELE_L_PAUSIERT, WK5_BELE_L_SAMMELRECHNUNG, WK5_BELE_L_WIEDERVORLAGE, BELE_L_BEZAHLT, BELE_L_STORNO
FROM BELEGE
WHERE 1=1");

            BuildQueryConditions(fbController);
            sqlBuilder.Append(" ORDER BY BELE_D_DATE DESC, BELE_N_NR DESC");
            return sqlBuilder.ToString();
        }

        protected override void BuildQueryConditions(FbController2 fbController)
        {
            sqlBuilder.Append(" AND BELE_A_TYP = @BELE_A_TYP");
            fbController.AddParameter("@BELE_A_TYP", EnumHelper.GetBelegTypString(Belegtyp));

            if (!String.IsNullOrWhiteSpace(Suchbegriff))
            {
                if (Suchbegriff.Length > 255)
                {
                    throw new ArgumentOutOfRangeException("Der Suchbegriff darf nicht mehr als 255 Zeichen haben");
                }

                // "Etiketten" "201mm"
                //fbController.AddParameter("@SUCHBEGRIFF", $"%{String.Join($"%{(SuchbegriffOderVerknüpfung ? "|" : "&")}%", Suchbegriff.Split(' ', '-', '_', ','))}%");
                sqlBuilder.Append(" AND ( ");
                switch (Phase)
                {
                    case 1:
                        BuildPhase1Condition(fbController);
                        break;
                    case 2:
                        BuildPhase2Condition(fbController);
                        break;
                    case 3:
                        BuildPhase3Condition(fbController);
                        break;
                    case 4:
                        BuildPhase4Condition(fbController);
                        break;
                    case 5:
                        BuildPhase5Condition(fbController);
                        break;
                    default:
                        BuildPhase1Condition(fbController);
                        break;
                }
                sqlBuilder.Append(" ) ");
            }

            if (Erledigt)
            {
                sqlBuilder.Append(" AND BELE_L_ERLEDIGT = 'Y'");
            }

            if (Direktlieferung)
            {
                sqlBuilder.Append(" AND WK5_BELE_L_DIREKTLIEFERUNG = 'Y'");
            }

            if (ZeitraumFiltern)
            {
                if (Von != default)
                {
                    sqlBuilder.Append(" AND BELE_D_DATE >= @VON");
                    fbController.AddParameter("@VON", Von);
                }

                if (Bis != default)
                {
                    sqlBuilder.Append(" AND BELE_D_DATE <= @BIS");
                    fbController.AddParameter("@BIS", Bis);
                }

            }

            if (Bezahlt)
            {
                sqlBuilder.Append(" AND BELE_L_BEZAHLT = 'Y'");
            }

            if (Neutral)
            {
                sqlBuilder.Append(" AND BELE_L_NEUTRAL = 'Y'");
            }

            if (Pausiert)
            {
                sqlBuilder.Append(" AND WK5_BELE_L_PAUSIERT = 'Y'");
            }

            if (Sammelrechnung)
            {
                sqlBuilder.Append(" AND WK5_BELE_L_SAMMELRECHNUNG = 'Y'");
            }

            if (Wiedervorlage)
            {
                sqlBuilder.Append(" AND WK5_BELE_L_WIEDERVORLAGE = 'Y'");
            }

            
            if(NurTechnikbelege)
            {
                sqlBuilder.Append(" AND BELE_L_TECHNIKBELEG = 'Y'");
            }

            if (Vertreter > 0)
            {
                sqlBuilder.Append(" AND BELE_N_VERTRETER = @VERT");
                fbController.AddParameter("@VERT", Vertreter);
            }

            if (Zahlungsbedingung > 0)
            {
                sqlBuilder.Append(" AND BELE_N_ZAHLUNG = @ZAHLUNG");
                fbController.AddParameter("@ZAHLUNG", Zahlungsbedingung);
            }

            if (Lieferbedingung > 0)
            {
                sqlBuilder.Append(" AND BELE_N_LIEFERUNG = @LIEFERUNG");
                fbController.AddParameter("@LIEFERUNG", Lieferbedingung);
            }

            if (AngebotsNummer > 0)
            {
                sqlBuilder.Append(" AND BELE_N_NR_AN = @AN_NR");
                fbController.AddParameter("@AN_NR", AngebotsNummer);
            }

            if (AuftragsNummer > 0)
            {
                sqlBuilder.Append(" AND BELE_N_NR_AU = @AU_NR");
                fbController.AddParameter("@AU_NR", AuftragsNummer);
            }

            if (LieferscheinNummer > 0)
            {
                sqlBuilder.Append(" AND BELE_N_NR_LS = @LS_NR");
                fbController.AddParameter("@LS_NR", LieferscheinNummer);
            }

            if (RechnungsNummer > 0)
            {
                sqlBuilder.Append(" AND BELE_N_NR_RE = @RE_NR");
                fbController.AddParameter("@RE_NR", RechnungsNummer);
            }

            if (GutschriftsNummer > 0)
            {
                sqlBuilder.Append(" AND BELE_N_NR_GU = @GU_NR");
                fbController.AddParameter("@GU_NR", RechnungsNummer);
            }            
        }

        public bool Erledigt { get; set; }
        public bool Direktlieferung { get; set; }
        public int AngebotsNummer { get; set; }
        public int AuftragsNummer { get; set; }
        public int LieferscheinNummer { get; set; }
        public int RechnungsNummer { get; set; }
        public int GutschriftsNummer { get; set; }
        public bool ZeitraumFiltern { get; set; } = false;
        public DateTime Von { get; set; } = DateTime.Now.AddDays(-14);
        public DateTime Bis { get; set; } = DateTime.Now;
        public bool Bezahlt { get; set; }
        public bool Neutral { get; set; }
        public bool Pausiert { get; set; }
        public bool Sammelrechnung { get; set; }
        public bool Wiedervorlage { get; set; }
        public int Vertreter { get; set; }
        public int Zahlungsbedingung { get; set; }
        public int Lieferbedingung { get; set; }
        public BelegTyp Belegtyp { get; set; }
        public bool NurTechnikbelege { get; set; }
        public bool TransaktionsnummernSuchen { get; set; } = false;
    }
}
