using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WK5.Core.Basis.Filter
{
    public class ZeitenFilter : Filter
    {
        public ZeitenFilterOption Option { get; set; }
        public string Kundennummer { get; set; } = string.Empty;
        public bool ZeitraumEingrenzen { get; set; }
        public Zeitraum Zeitraum { get; set; }
        public bool AusschließlichZeitenDieBerechnetWerden { get; set; }
        public bool NurAbzurechnendeLeistungen { get; set; }
        public bool IgnoreOption { get; set; }
        public string ToKundenQuery(FbController2 fbController)
        {
            sqlBuilder.Append(@"SELECT 
ZEIT_A_KUNDENNR,
KUND_A_NAME1,
SUM(DATEDIFF(minute from (ZEIT_D_START + ZEIT_T_START) to (ZEIT_D_ENDE + ZEIT_T_ENDE))) as MINUTEN
FROM ZEITEN Z
LEFT JOIN KUNDEN K ON K.KUND_A_NR = Z.ZEIT_A_KUNDENNR
WHERE 1 = 1
AND ZEIT_D_ENDE IS NOT NULL AND ZEIT_D_ENDE <> '01.01.0001' 
AND ZEIT_T_ENDE IS NOT NULL AND ZEIT_T_ENDE <> '00:00:00'
AND ZEIT_D_START >= CAST(@STARTDATUM as DATE) AND ZEIT_D_ENDE <= CAST(@ENDDATUM AS DATE)");
            if (AusschließlichZeitenDieBerechnetWerden)
            {
                sqlBuilder.Append("AND ZEIT_L_BERECHNET = 'Y'");
            }

            if(NurAbzurechnendeLeistungen)
            {
                sqlBuilder.Append(" AND ZEIT_L_ABGERECHNET = 'N'");
            }

            sqlBuilder.Append(@" 
GROUP BY ZEIT_A_KUNDENNR, KUND_A_NAME1
HAVING SUM(DATEDIFF(minute from (ZEIT_D_START + ZEIT_T_START) to (ZEIT_D_ENDE + ZEIT_T_ENDE))) >= 0");

            fbController.AddParameter("@STARTDATUM", Zeitraum.Von.ToShortDateString());
            fbController.AddParameter("@ENDDATUM", Zeitraum.Bis.ToShortDateString());

            string sql = sqlBuilder.ToString();
            sqlBuilder.Clear();
            return sql;
        }
        public override string ToSqlQuery(FbController2 fbController)
        {
            CheckFilterConditions();

            sqlBuilder.AppendLine("SELECT * FROM ZEITEN WHERE 1 = 1");
            BuildQueryConditions(fbController);
            sqlBuilder.AppendLine(" ORDER BY ZEIT_N_ID DESC");

            string sql = sqlBuilder.ToString();
            sqlBuilder.Clear();
            return sql;
        }

        protected override void BuildQueryConditions(FbController2 fbController)
        {
            if (!IgnoreOption)
            {
                sqlBuilder.AppendLine(Option switch
                {
                    ZeitenFilterOption.Angebot => " AND ZEIT_A_TYP = 'AN'",
                    ZeitenFilterOption.Auftrag => " AND ZEIT_A_TYP = 'AU'",
                    ZeitenFilterOption.Lieferschein => " AND ZEIT_A_TYP = 'LS'",
                    ZeitenFilterOption.Rechnung => " AND ZEIT_A_TYP = 'RE'",
                    ZeitenFilterOption.Gutschrift => " AND ZEIT_A_TYP = 'GU'",
                    ZeitenFilterOption.RMA => " AND ZEIT_A_TYP = 'RM'",
                    ZeitenFilterOption.Kunde => " AND ZEIT_A_TYP = 'KU'",
                    _ => throw new Exception($"'{Option}' ist keine gültige Option.")
                });

            }

            if(IgnoreOption)
            {
                sqlBuilder.AppendLine(@" AND ZEIT_D_ENDE IS NOT NULL AND ZEIT_D_ENDE <> '01.01.0001'
AND ZEIT_T_ENDE IS NOT NULL AND ZEIT_T_ENDE <> '00:00:00'");
            }

            if (Option is ZeitenFilterOption.Kunde)
            {
                sqlBuilder.AppendLine(" AND CAST(ZEIT_A_KUNDENNR AS VARCHAR(255)) = @SUCHBEGRIFF");
            }
            else
            {
                sqlBuilder.AppendLine(" AND CAST(ZEIT_N_BELEGNR AS VARCHAR(255)) = @SUCHBEGRIFF");
            }

            if (ZeitraumEingrenzen)
            {
                sqlBuilder.AppendLine(" AND ZEIT_D_ENDE IS NOT NULL AND ZEIT_D_START >= CAST(@STARTDATUM as DATE) AND ZEIT_D_ENDE <= CAST(@ENDDATUM AS DATE)");
                fbController.AddParameter("@STARTDATUM", Zeitraum.Von.ToShortDateString());
                fbController.AddParameter("@ENDDATUM", Zeitraum.Bis.ToShortDateString());
            }

            if(AusschließlichZeitenDieBerechnetWerden)
            {
                sqlBuilder.AppendLine(" AND ZEIT_L_BERECHNET = 'Y'");
            }

            if (NurAbzurechnendeLeistungen)
            {
                sqlBuilder.Append(" AND ZEIT_L_ABGERECHNET = 'N'");
            }

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

        private void CheckFilterConditions()
        {
            if(string.IsNullOrWhiteSpace(Suchbegriff))
            {
                throw new ArgumentException($"Bitte spezifizieren Sie für die Option '{Option}' einen entsprechenden Suchbegriff, welcher die Zuordnung enthält");
            }
        }

        public ZeitenFilter()
        {
            DateTime letzterMonat = DateTime.Now.AddMonths(-1);

            DateTime start = new DateTime(letzterMonat.Year, letzterMonat.Month, 1);
            DateTime ende = new DateTime(letzterMonat.Year, letzterMonat.Month, DateTime.DaysInMonth(letzterMonat.Year, letzterMonat.Month));
            Zeitraum = new Zeitraum(start, ende);
        }
    }

    public enum ZeitenFilterOption
    {
        Angebot,
        Auftrag,
        Lieferschein,
        Rechnung,
        Gutschrift,
        RMA,
        Kunde
    }
}
