using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WK5.Core;
using WK5.Core.Basis;
using WK5.Core.Basis.Filter;
using WK5.Core.Models;
using WK5.Core.Models.Lager;

namespace WK5_Blazor.Pages.Stammdaten.Artikeldaten
{
    public partial class ChargeUmbuchen
    {
        [Parameter] public string Artikelnummer { get; set; } = String.Empty;
#nullable disable
        [CascadingParameter] public AppMitarbeiter Mitarbeiter { get; set; }
#nullable enable
        public ChargenUmbuchenInput Input { get; set; } = new ChargenUmbuchenInput();
        private ChargenFilter _chargenFilter { get; set; } = new ChargenFilter()
        {
            NurOffene = true
        };

        private SeriennummerFilter _seriennummerFilter = new SeriennummerFilter
        {
            NurNichtAusgelieferte = true
        };

        public ArtikelFilter _artikelFilter { get; set; } = new ArtikelFilter()
        {
            NurArtikelMitLagerführung = true
        };

        private bool _showArtikelSucheModal { get; set; } = false;

        private EditForm? _editForm;

        private Task OnChargeSelected(Charge charge)
        {
            Input.Charge = charge.CHAR_N_NR;
            Input.Menge = charge.CHAR_N_MENGEOFFEN;
            Input.MaxMenge = charge.CHAR_N_MENGEOFFEN;
            return Task.CompletedTask;
        }

        private Task OnSeriennummerSelected(Seriennummer seriennummer)
        {
            Input.Seriennummer = seriennummer.Nummer;
            Input.Charge = seriennummer.Charge;
            Input.Menge = 1;
            Input.MaxMenge = 1;
            return Task.CompletedTask;
        }

        protected override async Task OnParametersSetAsync()
        {
            using FbController2 fbController = new FbController2();
            Artikel? artikel = await artikelService.GetAsync(Artikelnummer, fbController);

            if (artikel is not null)
            {
                _chargenFilter.Artikelnummer = artikel.Artikelnummer;
                Input.AlteArtikelnummer = artikel.Artikelnummer;
                Input.BenötigtSeriennummer = artikel.ARTI_L_SN;
                _seriennummerFilter.Artikelnummer = artikel.Artikelnummer;
                if (artikel.ARTI_L_SN)
                {
                    _artikelFilter.MussSeriennummerHaben = true;
                }
                else
                {
                    _artikelFilter.DarfKeineSeriennummerHaben = true;
                }
                _artikelFilter.AusgeschlosseneArtikel = new List<string>()
                {
                    artikel.Artikelnummer
                };
            }
        }

        public Task OnNeuerArtikelSelected(Artikel artikel)
        {
            Input.NeueArtikelnummer = artikel.Artikelnummer;
            _showArtikelSucheModal = false;
            return Task.CompletedTask;
        }

        public async Task SaveAsync()
        {
            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }

            if (_editForm.EditContext.Validate())
            {

                ShowAlerts.Clear();
                using FbController2 fbController = new FbController2(Mitarbeiter.PersonalNummer);
                Charge? charge = await Charge.GetChargeAsync(Input.Charge, fbController);
                if (charge is not null)
                {

                    Seriennummer? seriennummer = null;
                    if (!String.IsNullOrWhiteSpace(Input.Seriennummer))
                    {
                        seriennummer = await Seriennummer.GetSeriennummerAsync(Input.Seriennummer, charge.CHAR_N_NR);
                        if (seriennummer is null)
                        {
                            ShowAlerts.Add(new AlertBox { AlertType = AlertType.Warning, Message = $"Die ausgewählte Seriennummer {Input.Seriennummer} konnte nicht gefunden werden." });
                            return;
                        }
                    }

                    Zugang? alterZugang = await Zugang.GetZugangAsync(charge.CHAR_N_STAPELNR);
                    if (alterZugang is null)
                    {
                        ShowAlerts.Add(new AlertBox { AlertType = AlertType.Warning, Message = $"Der Zugang ({charge.CHAR_N_STAPELNR}) der Charge konnte nicht gefunden werden." });
                        return;
                    }

                    Lieferant? lieferant = await Lieferant.GetLieferantAsync(alterZugang.ZUGA_N_LIEF);

                    if (lieferant is null)
                    {
                        ShowAlerts.Add(new AlertBox { AlertType = AlertType.Warning, Message = $"Der Lieferant ({alterZugang.ZUGA_N_LIEF}) des Zugang konnte nicht gefunden werden." });
                        return;
                    }

                    // Für zukünftige Änderung wenn andere Mengen als Menge 1 umgebucht werden sollen                

                    AbgangBuchenInput abgang = new AbgangBuchenInput()
                    {
                        Artikelnummer = charge.CHAR_A_ARTINR,
                        Charge = charge.CHAR_N_NR,
                        Datum = DateTime.Now,
                        Menge = Input.Menge,
                        BenötigtSeriennummer = seriennummer is not null,
                        Seriennummer = seriennummer?.Nummer ?? String.Empty,
                        Notiz = "Umbuchung",
                        Kostenstelle = 14980,
                        MaxMenge = Input.Menge
                    };

                    await fbController.StartTransactionAsync();

                    try
                    {
                        int abgangsnummer = await lagerService.CreateAbgangAsync(abgang, Mitarbeiter.PersonalNummer, fbController);
                        await fbController.CommitChangesAsync();
                    }
                    catch (Exception ex)
                    {
                        await fbController.RollbackChangesAsync();
                        ShowAlerts.Add(new AlertBox { AlertType = AlertType.Warning, Message = $"Fehler beim Abgang buchen. Fehler: {ex}" });
                    }


                    RechnungBuchenInput zugang = new RechnungBuchenInput(false)
                    {
                        LieferscheinDatum = alterZugang.ZUGA_D_LS_DATUM,
                        LieferscheinNummer = alterZugang.ZUGA_A_LS_NR ?? String.Empty,
                        Rechnungsdatum = alterZugang.ZUGA_D_RE_DATUM,
                        Rechnungsnummer = alterZugang.ZUGA_A_RE_NR ?? String.Empty,
                        Zusatzkosten = 0,
                        GesamtbetragNetto = charge.CHAR_N_EKPREIS * Input.Menge,
                        NettoGesamtRechnung = charge.CHAR_N_EKPREIS * Input.Menge,
                        TeilRechnung = alterZugang.WK5_ZUGA_L_TEILZUGANG,
                        EcoDmsDocId = alterZugang.WK5_ZUGA_N_ECO_DOCID,
                        Zugangsdatum = DateTime.Now,
                        Personalnummer = Mitarbeiter.PersonalNummer,
                        Notiz = "Umbuchung",
                        RmaNummerVerknüpfung = alterZugang.RmaNummerVerknüpfung,
                        MwstBeiBearbeitung = alterZugang.ZUGA_L_MWST,
                        Zollkosten = 0
                    };

                    PositionBuchenInput pos = new PositionBuchenInput(seriennummer is not null, Input.Menge)
                    {
                        Artikelnummer = Input.NeueArtikelnummer,
                        ChargenNotiz = "Umbuchung",
                        Menge = Input.Menge,
                        Preis = charge.CHAR_N_EKPREIS,
                        MwstSatz = charge.CHAR_N_STEUERSATZ,
                        Bestellnummer = charge.CHAR_N_BESTNR,
                        Auftragsnummer = charge.CHAR_N_AB_NR,
                        Gebrauchtware = charge.CHAR_L_GEBRAUCHT
                    };

                    if (seriennummer is not null)
                    {
                        if (pos.Seriennummern.Length > 0)
                        {
                            pos.Seriennummern[0].Seriennummer = seriennummer.Nummer;
                        }
                    }

                    zugang.Positionen.Add(pos);

                    await fbController.StartTransactionAsync();

                    try
                    {
                        await lagerService.CreateZugangAsync(fbController, Mitarbeiter.PersonalNummer, zugang, lieferant);
                        await lagerService.UpdateZugangAsync(fbController, zugang, lieferant);
                        await fbController.CommitChangesAsync();
                    }
                    catch (Exception ex)
                    {
                        await fbController.RollbackChangesAsync();
                        ShowAlerts.Add(new AlertBox { AlertType = AlertType.Warning, Message = $"Fehler beim Zugang buchen. Fehler: {ex}" });
                    }

                    await AddAlertAsync(new AlertBox { AlertType = AlertType.Success, Message = $"Umbuchung wurde erfolgreich abgeschlossen!" });

                    navigationManager.NavigateTo($"/Artikel/{Artikelnummer}");


                }
            }
        }

        private Task OnChargenModalClosed()
        {
            if (Input.Charge is 0)
            {
                navigationManager.NavigateTo("/Artikel");
            }

            return Task.CompletedTask;
        }

        private Task OnSeriennummerModalClosed()
        {
            if (Input.Charge is 0 || String.IsNullOrWhiteSpace(Input.Seriennummer))
            {
                navigationManager.NavigateTo("/Artikel");
            }

            return Task.CompletedTask;
        }
    }
}
