using KarleyLibrary.Erweiterungen;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WK5.Core;
using WK5.Core.Basis;
using WK5.Core.Models;
using WK5.Core.PageModels.Tools;
using WK5_Blazor.Components;

namespace WK5_Blazor.Pages.Tools
{
    public struct ZahlungsPrüfungsData
    {
        public Beleg Beleg { get; set; }
        public Beleg? Zahlbeleg { get; set; }        

        public bool CanTakePayment
        {
            get
            {
                BelegTyp typ = EnumHelper.GetBelegTyp(Beleg.Belegtyp);

                if (typ is BelegTyp.Rechnung && Program.AppDaten.Zahlungsbedingungen.IstRechnung(Beleg.ZahlungsbedingungId))
                {
                    return true;
                }
                else if (typ is BelegTyp.Auftrag && Program.AppDaten.Zahlungsbedingungen.IstVorkasse(Beleg.ZahlungsbedingungId))
                {
                    return true;
                }
                return false;
            }
        }
    }

    public partial class ZahlungsPrüfung
    {
        public string Suchbegriff { get; set; } = String.Empty;
#nullable disable        
        [CascadingParameter] public AppMitarbeiter Mitarbeiter { get; set; }
#nullable enable

        public List<ZahlungsPrüfungsData> Suchergebnisse { get; set; } = new List<ZahlungsPrüfungsData>();

        private bool _gesperrt = false;
        public List<ZahlungsPrüfungsData> SelectedSubBelege { get; set; } = new List<ZahlungsPrüfungsData>();

        protected async override Task OnParametersSetAsync()
        {
            using FbController2 fbController = new FbController2();
            Zahlungsbedingungen = await Zahlungsbedingung.GetZahlungsbedingungenAsync(fbController);
        }
        public async Task SuchenAsync()
        {
            _gesperrt = true;
            await InvokeAsync(StateHasChanged);

            using FbController2 fbController = new FbController2();
            Suchergebnisse.Clear();
            await foreach (Beleg b in zahlungsService.SucheBelegeAsync(Suchbegriff.Trim()))
            {
                Suchergebnisse.Add(new ZahlungsPrüfungsData()
                {
                    Beleg = b,
                    Zahlbeleg = await zahlungsService.GetZahlBeleg(b)                    
                });
            }
            _gesperrt = false;
        }

        private bool _subbelegeLoading = false;
        public async Task LadeSubbelegeAsync(Beleg beleg)
        {
            if (beleg == SelectedBeleg)
            {
                SelectedBeleg = null;
                SelectedSubBelege.Clear();
            }
            else
            {
                _subbelegeLoading = true;
                await InvokeAsync(StateHasChanged);
                SelectedSubBelege.Clear();
                using FbController2 fbController = new FbController2();
                SelectedBeleg = beleg;
                Dictionary<BelegTyp, List<int>> result = await belegService.GetSubBelege(EnumHelper.GetBelegTyp(beleg.Belegtyp), beleg.Belegnummer, fbController);

                foreach (KeyValuePair<BelegTyp, List<int>> kvp in result)
                {
                    if (kvp.Key is BelegTyp.Rechnung or BelegTyp.Auftrag)
                    {
                        foreach (int belegnummer in kvp.Value)
                        {
                            Beleg? b = await Beleg.GetBelegAsync(kvp.Key, belegnummer, fbController);
                            if (b is not null)
                            {
                                SelectedSubBelege.Add(new ZahlungsPrüfungsData()
                                {
                                    Beleg = b,
                                    Zahlbeleg = await zahlungsService.GetZahlBeleg(b)                                    
                                });
                            }
                        }
                    }
                }
                _subbelegeLoading = false;
            }
        }

        public Beleg? Zahlbeleg { get; set; }
        public Beleg? SelectedBeleg { get; set; } = null;
        private bool _showZahlungsModal = false;

        public ZahlungsPrüfungInput Input { get; set; } = new();
        public ZahlungsbedingungCollection Zahlungsbedingungen { get; set; } = new ZahlungsbedingungCollection();
        public async Task ÖffneZahlModal(Beleg beleg)
        {
            ResetZahlmodal();
            Zahlbeleg = await zahlungsService.GetZahlBeleg(beleg);
            SelectedBeleg = beleg;
            if (Zahlbeleg is not null)
            {                
                Input.Zahlbetrag = Math.Max(Zahlbeleg.GetBruttoBetrag(Program.AppDaten.Optionen, Program.AppDaten.VersandMehrwertsteuer) - Zahlbeleg.WK5_BELE_N_BEZAHLT_WERT,0.0m);
                Input.Zahldatum = beleg.WK5_BELE_D_BEZAHLT_DATUM ?? DateTime.Now;
                Input.Zahltext = beleg.WK5_BELE_A_ZAHL_KOMMENTAR ?? String.Empty;
                _showZahlungsModal = true;
            }
            else
            {
                await AddAlertAsync(new AlertBox
                {
                    AlertType = AlertType.Danger,
                    DecayTime = 5,
                    Message = "Es konnte kein Beleg gefunden werden in den die Zahlung eingetrage werden sollte"

                });
                await SetAlerts();
            }
        }

        public string GetProblemText(Beleg beleg)
        {
            StringBuilder sb = new StringBuilder();
            if (beleg is not Rechnung && beleg is not Auftrag)
            {
                sb.AppendLine($"In einem Beleg vom Typ {beleg.GetType().Name} darf keine Zahlung eingetragen werden");
            }

            if (beleg is Rechnung && !Zahlungsbedingungen.IstRechnung(beleg.ZahlungsbedingungId))
            {
                sb.AppendLine("In einer Rechnung dürfen keine Vorkasse Zahlungen eingetragen werden!");
            }

            if (beleg is Auftrag && !Zahlungsbedingungen.IstVorkasse(beleg.ZahlungsbedingungId))
            {
                sb.AppendLine("In einem Auftrag dürfen keine Rechnungszahlungen eingetragen werden!");
            }

            return sb.ToString().Replace("\r\n", "<br/>");
        }

        public void ResetZahlmodal()
        {
            Input.Zahldatum = DateTime.Now;
            Input.Zahlbetrag = 0.0m;
            Input.Zahltext = String.Empty;            
            SelectedBeleg = null;
            Zahlbeleg = null;

        }

        public async Task SpeichernAsync()
        {
            using FbController2 fbController = new FbController2(Mitarbeiter.PersonalNummer);
            if (Zahlbeleg.WK5_BELE_N_BEZAHLT_WERT > 0)
            {
                Input.Zahlbetrag += Zahlbeleg.WK5_BELE_N_BEZAHLT_WERT;
            }
            await zahlungsService.SetBezahlt(Zahlbeleg, Input, fbController);
            _showZahlungsModal = false;

            ResetZahlmodal();


            await AddAlertAsync(new AlertBox
            {
                AlertType = AlertType.Success,
                DecayTime = 5,
                Message = "Die Zahlungsdaten wurden erfolgreich eingetragen"

            });
            await SetAlerts();

            await SuchenAsync();
        }
    }
}