using ecoDMS.Library;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Serilog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Toolbelt.Blazor.HotKeys;
using WK5.Core;
using WK5.Core.Basis;
using WK5.Core.Basis.Erweiterungen;
using WK5.Core.Basis.Filter;
using WK5.Core.Models;
using WK5.Core.Models.Lager;

namespace WK5_Blazor.Pages.Lager.Zugänge
{
    public partial class LieferscheinZugang
    {
#nullable disable
        [CascadingParameter] public AppMitarbeiter Mitarbeiter { get; set; }
#nullable enable
        public LieferscheinBuchenInput Input { get; set; } = new LieferscheinBuchenInput();
        public Lieferant? Lieferant { get; set; }
        private LieferantenFilter FilterLieferanten { get; set; } = new LieferantenFilter();
        private BestellungFilter FilterBestellungen { get; set; } = new BestellungFilter
        {
            Option = BestellungFilterOption.NurOffeneBestellungen
        };
        private ArtikelFilter FilterArtikel { get; set; } = new ArtikelFilter()
        {
            NurArtikelVomLieferantenAnzeigen = true
        };
        private PositionBuchenInput? DeleteSelectedPositionsInput { get; set; }
        private Bestellung? SelectedBestellung { get; set; }

        private bool _showArtikelSucheModal;
        private bool _showBestellungSucheModal;
        private bool _hideBestellungÜbernehmenButton;
        private bool _hideAddArtikelButton;
        private async Task SaveAsync()
        {
            if (Lieferant is null)
            {
                return;
            }

            using FbController2 fbController = new FbController2(Mitarbeiter.PersonalNummer);
            int zugangsnummer = await lagerService.CreateZugangAsync(fbController, Mitarbeiter.PersonalNummer, Input, Lieferant);
            await AddAlertAsync(new AlertBox()
            {
                AlertType = AlertType.Success,
                Message = $"Zugang {zugangsnummer} erfolgreich gebucht."
            });


            // ecoDMS Upload
            if (!String.IsNullOrWhiteSpace(Input.Lieferscheindatei) && File.Exists(Input.Lieferscheindatei))
            {
                try
                {
                    EcoDmsController ecoController = await EcoDmsController.CreateAsync(new Uri(GlobalConfig.ECODMS_BASIS_URL), $"{Mitarbeiter.Username}:{Mitarbeiter.Passwort}", Log.Logger);
                    bool angemeldet = await ecoController.AnmeldenAsync();
                    if (angemeldet)
                    {
                        // Wir prüfen erst, ob das Dokument bereits in ecoDMS archiviert worden ist
                        List<EcoSearchFilter> suchbedingungen = new List<EcoSearchFilter>
                        {
                            new EcoSearchFilter
                            {
                                ClassifyAttribut = ecoController.ClassifyAttributes.GetKeyByValue("Belegnummer")!,
                                SearchOperator = SuchOperator.Gleich,
                                SearchValue = Input.Lieferscheindatei
                            },
                            new EcoSearchFilter
                            {
                                ClassifyAttribut = "docart",
                                SearchOperator = SuchOperator.Gleich,
                                SearchValue = "11"
                            }
                        };

                        List<EcoDMSdocInfoCL> result = await ecoController.EcoSucheDoksAsync(suchbedingungen);
                        EcoDMSdocInfoCL? ecoDokument = result.FirstOrDefault();
                        if (ecoDokument is null)
                        {
                            // Rechnung in ecoDMS hochladen
                            // TODO: (BIG) Felder und Eigenschaften per Einstellungen Konfigurierbar
                            Dictionary<string, string> klassifizierung = new Dictionary<string, string>
                            {
                                {"docart", "11" },
                                {"folder", "3" },
                                {"mainfolder", "3" },
                                {"status", "1" },
                                {ecoController.ClassifyAttributes.GetKeyByValue("Kontonummer")!, Lieferant.LIEF_N_NR.ToString() },
                                {"cdate", Input.LieferscheinDatum.ToString("yyyy-MM-dd") },
                                {"bemerkung", Lieferant.LIEF_A_NAME1 },
                                {ecoController.ClassifyAttributes.GetKeyByValue("Belegnummer")!, Input.LieferscheinNummer },
                            };

                            List<string> editRoles = new List<string>
                            {
                                "r_LDAP_Buchhaltung", "r_ecodms", "ecoSIMSADMIN", "LDAP_r_ley"
                            };

                            List<string> readRoles = new List<string>
                            {
                                "ecoSIMSUSER"
                            };

                            int docId = await ecoController.UploadFileAsync(Input.Lieferscheindatei, klassifizierung, readRoles, editRoles);

                            if (docId > 0)
                            {
                                await lagerService.SetEcoDmsDocIdAsync(fbController, zugangsnummer, docId, true);
                            }
                        }
                        else
                        {
                            await AddAlertAsync(new AlertBox
                            {
                                AlertType = AlertType.Warning,
                                Message = $"Der Lieferschein {Input.LieferscheinNummer} wurde bereits in ecoDMS gefunden. Der Lieferschein wurde daher nicht erneut archiviert."
                            });
                        }
                        await ecoController.AbmeldenAsync();
                    }
                }
                catch (Exception ex)
                {
                    await AddAlertAsync(new AlertBox
                    {
                        AlertType = AlertType.Danger,
                        Message = $"Der Lieferschein konnte nicht in ecoDMS archiviert werden. Bitte den Lieferschein manuell archivieren.{Environment.NewLine}Fehler: {ex}"
                    });
                }

            }


            navigationManager.NavigateTo($"/Zugang");
        }
        private async Task BestellungÜbernehmen(Bestellung bestellung)
        {
            if(Lieferant is null)
            {
                return;
            }
            _hideBestellungÜbernehmenButton = true;
            _hideAddArtikelButton = true;
            using FbController2 fbController = new FbController2();
            foreach (var pos in bestellung.Positionen)
            {
                if (!pos.BEPO_L_ERLEDIGT)
                {
                    Artikel? artikel = await artikelService.GetAsync(pos.BEPO_A_ARTIKELNR, fbController);

                    if (artikel is null)
                    {
                        continue;
                    }

                    decimal bezahlterBedarf = await artikelService.GetBedarfBezahlt(artikel.Artikelnummer, Program.AppDaten.Zahlungsbedingungen);
                    
                    decimal offen = pos.BEPO_N_MENGE - pos.BEPO_N_LIEFERMENGE;
                    
                    Input.Positionen.Add(new PositionBuchenInput(artikel.ARTI_L_SN, offen)
                    {
                        Artikelnummer = pos.BEPO_A_ARTIKELNR,
                        Bestellnummer = pos.BEPO_N_BESTNR,
                        BestellungPosId = pos.BEPO_N_POS,
                        Menge = offen,
                        BezahlterBedarf = bezahlterBedarf,
                        Auftragsnummer = bestellung.BEST_N_AB_NR,
                        Preis = pos.PreisMitRabatt,
                        MwstSatz = Lieferant.LIEF_L_MWST ? artikel.MWST_N_PROZENT : 0
                    });
                    
                }

            }
            Input.Zusatzkosten += bestellung.Zusatzkosten;
            Input.BestellungNotiz = new ZugangBestellnotizInput(bestellung.Bestellnummer, bestellung.BEST_B_NOTIZ);



            _showBestellungSucheModal = false;
        }
        private async Task AddArtikel(Artikel artikel)
        {
            _hideBestellungÜbernehmenButton = true;
            _showArtikelSucheModal = false;

            decimal bezahlterBedarf = await artikelService.GetBedarfBezahlt(artikel.Artikelnummer, Program.AppDaten.Zahlungsbedingungen);

            Input.Positionen.Add(new PositionBuchenInput(artikel.ARTI_L_SN, artikel.Bestellt)
            {
                Artikelnummer = artikel.Artikelnummer,
                Menge = artikel.Bestellt,
                BezahlterBedarf = bezahlterBedarf,
                Preis = artikel.DurchschnittsEinkaufspreis
            });
        }
        private Task SelectLieferant(Lieferant lieferant)
        {
            Lieferant = lieferant;
            FilterBestellungen.LieferantId = lieferant.LIEF_N_NR;
            FilterArtikel.LieferantenId = lieferant.LIEF_N_NR;
            return Task.CompletedTask;
        }
        private Task SelectBestellung(Bestellung bestellung)
        {
            SelectedBestellung = bestellung;
            return Task.CompletedTask;
        }
        private Task LieferantenModalClosed()
        {
            if (Lieferant is null)
            {
                navigationManager.NavigateTo("/Zugang");
            }
            return Task.CompletedTask;
        }
        private async Task OnInputFileChange(InputFileChangeEventArgs e)
        {
            if (!Path.GetExtension(e.File.Name).Equals(".pdf", StringComparison.OrdinalIgnoreCase))
            {
                await jsRuntime.ShowToast(ToastType.error, "Upload fehlgeschlagen. Bitte laden Sie eine PDF-Datei hoch.");
                return;
            }

            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Uploads");
            string filename = Path.Combine(path, e.File.Name);

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            await using FileStream fs = new(filename, FileMode.Create);
            await e.File.OpenReadStream(e.File.Size).CopyToAsync(fs);
            
            Input.Lieferscheindatei = filename;
        }
        public override void AddHotKeys(HotKeysContext context)
        {
            context
                .Add(ModKeys.Alt, Keys.S, SaveAsync, "Speichert den Zugang", Exclude.Default)
                .Add(ModKeys.Alt, Keys.Insert, () => { _showArtikelSucheModal = true; StateHasChanged(); }, "Fügt dem Zugang einen neuen Artikel hinzu", Exclude.Default)
                .Add(ModKeys.Alt, Keys.B, () => { _showBestellungSucheModal = true; StateHasChanged(); }, "Fügt dem Zugang einen neuen Artikel hinzu", Exclude.Default)
                ;
        }
    }
}
