using KarleyLibrary.Erweiterungen;
using MbeSoap;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using WK5.Core;
using WK5.Core.Basis;
using WK5.Core.Basis.Erweiterungen;
using WK5.Core.Basis.Filter;
using WK5.Core.Drucken.Briefe;
using WK5.Core.Drucken.RMAS.KundeVersandAnforderung;
using WK5.Core.Drucken.RMAS.KundeWareneingangsbestätigung;
using WK5.Core.Drucken.RMAS.RmaAnfrageLieferant;
using WK5.Core.Drucken.RMAS.RmaVersandbelegKunde;
using WK5.Core.Drucken.RMAS.RmaVersandbelegLieferant;
using WK5.Core.Models;
using WK5.Core.Models.Lager;
using WK5.Core.PageModels.Verkauf.RMAS;
using WK5.Core.Validators.Verkauf.RMAS;
using WK5.Core.Email;
using System.Threading;
using WK5.Core.PageModels.Stammdaten.Kunden;
using WK5_Blazor.CoreExtensions;
using Toolbelt.Blazor.HotKeys;

namespace WK5_Blazor.Pages.Verkauf.RMAS
{
    public partial class RmaForm : IEditPage, IPipeline<Rma>, ITabPage<RmaTabs>
    {
        [Parameter] public int RmaNummer { get; set; }
        public Rma Input { get; set; } = new Rma();
        public Rma StartCopy { get; set; } = new Rma();
        public Pipeline<Rma> Pipeline { get; set; } = new Pipeline<Rma>();
        public ZeitenFilter FilterZeiten { get; set; } = new ZeitenFilter
        {
            Option = ZeitenFilterOption.RMA
        };
        public BelegFilter FilterLieferschein { get; set; } = new BelegFilter
        {
            BelegTyp = BelegTyp.Lieferschein
        };

        public RmaVerlaufFilter FilterRmaVerlauf { get; set; } = new RmaVerlaufFilter
        {

        };

        public Lieferschein? SelectedLieferschein { get; set; }
        public Belegposition? Position { get; set; }
        public Belegcharge? SelectedBelegCharge { get; set; }
        public Zugang? SelectedZugang { get; set; }
        public Kunde? SelectedKunde { get; set; }
        public Lieferant? SelectedLieferant { get; set; }
        public RmaTabs ActiveTab { get; set; } = RmaTabs.Allgemein;
        public bool IstErledigt { get; set; }
        public RmaAustauschSchritt AustauschSchritt { get; set; } = RmaAustauschSchritt.EigenGarantie;

        private bool _showLieferscheinSuche;
        private bool _showSeriennummerModal;
        private bool _showChargenModal;
        private bool _showZeiterfassungModal;
        private bool _showAustauschModal;
        private bool _showEigenGarantieDeclinedModal;
        private bool _showVersandModal;        
        public Lieferanschrift? LieferanschriftKunde { get; set; }
        public LieferantenAnschrift? LieferanschriftLieferant { get; set; }
        public Ansprechpartner? AnsprechpartnerKunde { get; set; }
        public AnsprechpartnerLieferant? AnsprechpartnerLieferant { get; set; }
        private List<Belegcharge> _belegchargen = new List<Belegcharge>();
        private RmaValidator _validator = new RmaValidator();
        private List<Lieferanschrift> _lieferanschriften = new List<Lieferanschrift>();
        private List<LieferantenAnschrift> _lieferantenAnschriften = new List<LieferantenAnschrift>();
        private List<Ansprechpartner> _ansprechpartner = new List<Ansprechpartner>();
        private List<AnsprechpartnerLieferant> _ansprechpartnerLieferant = new List<AnsprechpartnerLieferant>();
        private List<(string belegtyp, int belegnummer)> _rmaBelege = new List<(string belegtyp, int belegnummer)>();
        private EditForm? _editForm;
        private bool _isDownloading;
        private bool _mailIsLoading;
        private List<BelegChangeAnsicht> _historie = new List<BelegChangeAnsicht>();
        private bool _lädtHistorie;
        private bool _showKundenkontakte;
        
        private string? _selectedKundennummer;
#nullable disable
        [CascadingParameter] public AppMitarbeiter Mitarbeiter { get; set; }
#nullable enable

        protected override async Task OnParametersSetAsync()
        {
            if (RmaNummer > 0)
            {
                await LadeEditModeAsync();
                FilterZeiten.Suchbegriff = RmaNummer.ToString();
                FilterZeiten.Kundennummer = Input.Kundennummer;
                FilterRmaVerlauf.RmaNummer = RmaNummer;
            }


            await SetupPipelineAsync();

            StartCopy = Input.DeepCopy();

            if (Input.LieferscheinNummer <= 0)
            {
                _showLieferscheinSuche = true;
            }



            await SetAlerts();
        }

        public async Task SetupPipelineAsync()
        {
            Pipeline = new Pipeline<Rma>();
            await Pipeline.HardReset();

            Pipeline.Add(async (input) =>
            {
                await SaveAsync();
                return true;
            });
        }

        private async Task SaveAsync()
        {
            using FbController2 fbController = new FbController2(Mitarbeiter.PersonalNummer);
            if (Modus is EditMode.Anlage)
            {
                await rmaService.CreateAsync(Input, fbController);
                await AddAlertAsync(new AlertBox
                {
                    AlertType = AlertType.Success,
                    Message = $"RMA-{Input.Id} wurde erfolgreich angelegt",
                    DecayTime = 10
                });
            }
            else
            {
                await rmaService.UpdateAsync(Input, fbController);
                await AddAlertAsync(new AlertBox
                {
                    AlertType = AlertType.Success,
                    Message = $"RMA-{Input.Id} wurde erfolgreich gespeichert",
                    DecayTime = 10
                });
            }

            if(Modus is EditMode.Anlage)
            {
                navigationManager.NavigateTo($"/RMAS/{Input.Id}");
            }
            else
            {
                await OnParametersSetAsync();
            }
        }

        private async Task SubmitAsync()
        {
            if (IstErledigt || SperreDurchAnderenUser || !Input.HasBeenModified(StartCopy))
            {
                return;
            }

            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }

            if (_editForm.EditContext.Validate())
            {

                Pipeline.Reset();
                await Pipeline.RunUntilFailureAsync(Input);

            }
        }
        private Task LieferscheinClickedAsync(Beleg? beleg)
        {
            if (beleg is null)
            {
                Input.LieferscheinNummer = 0;
                _lieferanschriften = new List<Lieferanschrift>();
                SelectedLieferschein = null;
                Position = null;
                SelectedKunde = null;
                SelectedZugang = null;
                LieferanschriftKunde = null;
                LieferanschriftLieferant = null;
                SelectedLieferant = null;
                Input.ResetPosition();
            }
            else
            {
                SelectedLieferschein = (Lieferschein)beleg;
                Input.LieferscheinNummer = SelectedLieferschein.Belegnummer;
                Input.Kundennummer = SelectedLieferschein.Kundennummer;
            }

            return Task.CompletedTask;

        }

        private async Task SelectPositionAsync(Belegposition? pos)
        {
            Position = pos;

            if (pos is null)
            {
                Input.ResetPosition();
                _validator.MaxMenge = 0;
            }
            else
            {
                Input.BelegposId = pos.PosId;
                Input.StücklistenPositionsId = pos.StücklistenPositionsId;
                Input.Artikelnummer = pos.Artikelnummer;
                _belegchargen = await Belegcharge.GetPositionsChargenAsync(pos.PosId, pos.StücklistenPositionsId).ToListAsync();

                if (pos.Seriennummern.Any())
                {
                    _showSeriennummerModal = true;
                }
                else
                {
                    if (_belegchargen.Count == 1)
                    {
                        await SelectBelegchargeAsync(_belegchargen.FirstOrDefault());
                    }
                    else
                    {
                        _showChargenModal = true;
                    }
                }
            }

        }

        private async Task SelectSeriennummerAsync(string seriennummer)
        {
            Input.Seriennummer = seriennummer;
            Input.Menge = 1;

            // Wir brauchen noch die Belegcharge
            using FbController2 fbController = new FbController2();
            BelegSeriennummer? tmp = await BelegSeriennummer.GetBelegSeriennummernAsync(Input.BelegposId, Input.StücklistenPositionsId, fbController).FirstOrDefaultAsync(x => x.BSNR_A_SN == Input.Seriennummer);

            if (tmp is not null)
            {
                await SelectBelegchargeAsync(_belegchargen.FirstOrDefault(x => x.BCHA_N_CHARGE == tmp.BSNR_N_CHARGE));
            }

            await CloseLieferscheinSucheModalAsync();
        }

        private async Task LadeHistorieAsync()
        {
            _historie.Clear();
            _lädtHistorie = true;
            await foreach (var item in BelegChangeAnsicht.GetHistorieAsync("RM", RmaNummer.ToString()))
            {
                _historie.Add(item);
                StateHasChanged();
            }
            _lädtHistorie = false;
        }
        private async Task LadeDatenAsync()
        {
            using FbController2 fbController = new FbController2();
            SelectedKunde = await Kunde.GetKundeAsync(Input.Kundennummer);
            SelectedLieferant = await Lieferant.GetLieferantAsync(Input.LieferantId);
            _lieferanschriften = await Lieferanschrift.GetLieferanschriftenAsync(Input.Kundennummer).ToListAsync();
            _lieferantenAnschriften = await LieferantenAnschrift.GetAnschriftenAsync(Input.LieferantId).ToListAsync();
            _ansprechpartner = await Ansprechpartner.GetAnsprechpartnerAsync(Input.Kundennummer).ToListAsync();
            _ansprechpartnerLieferant = await AnsprechpartnerLieferant.GetAnsprechpartnerAsync(Input.LieferantId).ToListAsync();
            AnsprechpartnerLieferant = _ansprechpartnerLieferant.FirstOrDefault(x => x.GetName() == Input.LieferantAnsprechpartner);
            AnsprechpartnerKunde = _ansprechpartner.FirstOrDefault(x => x.GetName() == Input.KundeAnsprechpartner);
            LieferanschriftKunde = _lieferanschriften.FirstOrDefault(x => x.KULA_N_NR == Input.LieferanschriftKundeId);
            LieferanschriftLieferant = _lieferantenAnschriften.FirstOrDefault(x => x.LIRE_N_NR == Input.LieferanschriftLieferantId);

        }

        private async Task SelectBelegchargeAsync(Belegcharge? belegcharge)
        {
            SelectedBelegCharge = belegcharge;
            if (belegcharge is not null)
            {
                using FbController2 fbController = new FbController2();

                Input.BelegChargenId = belegcharge.BCHA_N_ID;
                SelectedZugang = await lagerService.GetZugangByChargenId(belegcharge.BCHA_N_CHARGE, fbController) ?? throw new NullReferenceException(nameof(SelectedZugang));
                Input.LieferantId = SelectedZugang.ZUGA_N_LIEF;

                _validator.MaxMenge = belegcharge.BCHA_N_MENGE;
            }
            else
            {
                Input.BelegChargenId = 0;
                _validator.MaxMenge = 0;
                Input.LieferantId = 0;
                _lieferantenAnschriften = new List<LieferantenAnschrift>();
            }

            await LadeDatenAsync();
            await CloseLieferscheinSucheModalAsync();
        }

        private async Task CloseLieferscheinSucheModalAsync()
        {
            if (SelectedLieferschein is null || Position is null || SelectedZugang is null || SelectedKunde is null || SelectedLieferant is null || SelectedBelegCharge is null)
            {
                await AddAlertAsync(new AlertBox
                {
                    AlertType = AlertType.Danger,
                    Message = $@"RMA konnte nicht geöffnet werden, da ein Fehler in der Zuordnung vorliegt.<br /><br />
{nameof(SelectedLieferschein)}: {SelectedLieferschein}<br />
{nameof(Position)}: {Position}<br />
{nameof(SelectedZugang)}: {SelectedZugang}<br />
{nameof(SelectedKunde)}: {SelectedKunde}<br />
{nameof(SelectedLieferant)}: {SelectedLieferant}<br />
{nameof(SelectedBelegCharge)}: {SelectedBelegCharge}"
                });
                navigationManager.NavigateTo("/RMAS");
            }
            _showSeriennummerModal = false;
            _showChargenModal = false;
            _showLieferscheinSuche = false;
        }

        #region Downloads 
        private async Task DownloadRücksendeAnforderungAsync()
        {
            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }
            if (Input.RückversandVonKundeDirektZumLieferant && String.IsNullOrWhiteSpace(Input.RmaNummerLieferant))
            {
                await jsRuntime.ShowToast(ToastType.error, $"RMA-Nummer von Lieferant ist erforderlich, da die Ware direkt zum Lieferanten verschickt werden soll");
                return;
            }

            if (!_editForm.EditContext.Validate())
            {
                await jsRuntime.ShowToast(ToastType.error, $"Download fehlgeschlagen, da die RMA aufgrund von falschen Eingaben nicht gespeichert werden konnte");
                return;
            }

            if (!Input.RücksendungAngefordert)
            {
                Input.RücksendungAngefordert = true;
            }

            if (Input.RücksendungAngefordertDatum == default)
            {
                Input.RücksendungAngefordertDatum = DateTime.Now;
            }

            await SaveAsync();

            _isDownloading = true;

            using FbController2 fbController = new FbController2();
            var rma = await DruckRma.GetDruckRmaAsync(RmaNummer, fbController);

            if (rma is not null)
            {

                PrintKundeVersandAnforderungRegelsatz printRegeln = new PrintKundeVersandAnforderungRegelsatz
                {
                    ShowFooter = true,
                    ShowHeader = true
                };

                if (Program.AppDaten.VersandMehrwertsteuer is null)
                {
                    throw new ArgumentNullException(nameof(Program.AppDaten.VersandMehrwertsteuer));
                }

                PrintKundeVersandAnforderung rmaPrinter = await PrintKundeVersandAnforderung.CreateAsync(rma, printRegeln);
                string fullFilename = rmaPrinter.Print(GlobalConfig.Configuration.OutputPfad);
                await downloadService.DownloadFile(Path.GetFileName(fullFilename), await File.ReadAllBytesAsync(fullFilename), "application/pdf");
                await downloadService.ClearBuffers();
            }

            _isDownloading = false;
        }
        private async Task DownloadEingangsbelegAsync()
        {
            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }

            if (!_editForm.EditContext.Validate())
            {
                await jsRuntime.ShowToast(ToastType.error, $"Download fehlgeschlagen, da die RMA aufgrund von falschen Eingaben nicht gespeichert werden konnte");
                return;
            }

            if (!Input.Eingangsbeleg)
            {
                Input.Eingangsbeleg = true;
            }

            if (Input.EingangsbelegDatum == default)
            {
                Input.EingangsbelegDatum = DateTime.Now;
            }

            await SaveAsync();

            _isDownloading = true;

            using FbController2 fbController = new FbController2();
            var rma = await DruckRma.GetDruckRmaAsync(RmaNummer, fbController);

            if (rma is not null)
            {

                BriefRegelsatz printRegeln = new BriefRegelsatz
                {
                    ShowFooter = true,
                    ShowHeader = true
                };

                if (Program.AppDaten.VersandMehrwertsteuer is null)
                {
                    throw new ArgumentNullException(nameof(Program.AppDaten.VersandMehrwertsteuer));
                }

                PrintKundeWareneingangsbestätigung rmaPrinter = await PrintKundeWareneingangsbestätigung.CreateAsync(rma, printRegeln);
                string fullFilename = rmaPrinter.Print(GlobalConfig.Configuration.OutputPfad);
                await downloadService.DownloadFile(Path.GetFileName(fullFilename), await File.ReadAllBytesAsync(fullFilename), "application/pdf");
                await downloadService.ClearBuffers();
            }

            _isDownloading = false;
        }
        private async Task DownloadRmaAnfrageLieferantAsync()
        {
            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }

            if (String.IsNullOrWhiteSpace(Input.FehlerangabeLieferant))
            {
                await jsRuntime.ShowToast(ToastType.error, $"Bitte geben Sie einer Fehlerbezeichnung für den Lieferanten ein");
                return;
            }

            if (!_editForm.EditContext.Validate())
            {
                await jsRuntime.ShowToast(ToastType.error, $"Download fehlgeschlagen, da die RMA aufgrund von falschen Eingaben nicht gespeichert werden konnte");
                return;
            }

            if (!Input.AnfrageLieferant)
            {
                Input.AnfrageLieferant = true;
            }

            if (Input.AnfrageLieferantDatum == default)
            {
                Input.AnfrageLieferantDatum = DateTime.Now;
            }

            await SaveAsync();

            _isDownloading = true;

            using FbController2 fbController = new FbController2();
            var rma = await DruckRma.GetDruckRmaAsync(RmaNummer, fbController);

            if (rma is not null)
            {

                BriefRegelsatz printRegeln = new BriefRegelsatz
                {
                    ShowFooter = true,
                    ShowHeader = true
                };

                if (Program.AppDaten.VersandMehrwertsteuer is null)
                {
                    throw new ArgumentNullException(nameof(Program.AppDaten.VersandMehrwertsteuer));
                }

                PrintRmaAnfrageLieferant rmaPrinter = await PrintRmaAnfrageLieferant.CreateAsync(rma, printRegeln);
                string fullFilename = rmaPrinter.Print(GlobalConfig.Configuration.OutputPfad);
                await downloadService.DownloadFile(Path.GetFileName(fullFilename), await File.ReadAllBytesAsync(fullFilename), "application/pdf");
                await downloadService.ClearBuffers();
            }

            _isDownloading = false;
        }
        private async Task DownloadRücksendebelegLieferantAsync()
        {
            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }

            if (String.IsNullOrWhiteSpace(Input.FehlerangabeLieferant))
            {
                await jsRuntime.ShowToast(ToastType.error, $"Bitte geben Sie einer Fehlerbezeichnung für den Lieferanten ein");
                return;
            }

            if (String.IsNullOrWhiteSpace(Input.RmaNummerLieferant))
            {
                await jsRuntime.ShowToast(ToastType.error, $"Bitte geben Sie einer RMA-Nummer vom Lieferanten an");
                return;
            }

            if (!_editForm.EditContext.Validate())
            {
                await jsRuntime.ShowToast(ToastType.error, $"Download fehlgeschlagen, da die RMA aufgrund von falschen Eingaben nicht gespeichert werden konnte");
                return;
            }

            if (!Input.RücksendungAnLieferant)
            {
                Input.RücksendungAnLieferant = true;
            }

            if (Input.RücksendungAnLieferantDatum == default)
            {
                Input.RücksendungAnLieferantDatum = DateTime.Now;
            }

            await SaveAsync();

            _isDownloading = true;

            using FbController2 fbController = new FbController2();
            var rma = await DruckRma.GetDruckRmaAsync(RmaNummer, fbController);

            if (rma is not null)
            {

                BriefRegelsatz printRegeln = new BriefRegelsatz
                {
                    ShowFooter = true,
                    ShowHeader = true
                };

                if (Program.AppDaten.VersandMehrwertsteuer is null)
                {
                    throw new ArgumentNullException(nameof(Program.AppDaten.VersandMehrwertsteuer));
                }

                PrintRmaVersandbelegLieferant rmaPrinter = await PrintRmaVersandbelegLieferant.CreateAsync(rma, printRegeln);
                string fullFilename = rmaPrinter.Print(GlobalConfig.Configuration.OutputPfad);
                await downloadService.DownloadFile(Path.GetFileName(fullFilename), await File.ReadAllBytesAsync(fullFilename), "application/pdf");
                await downloadService.ClearBuffers();
            }

            _isDownloading = false;
        }
        private async Task DownloadRücksendebelegKundeAsync()
        {
            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }

            if (String.IsNullOrWhiteSpace(Input.RücklieferInfo))
            {
                await jsRuntime.ShowToast(ToastType.error, $"Bitte geben Sie Rücklieferinfo für den Kunden ein");
                return;
            }

            if (!_editForm.EditContext.Validate())
            {
                await jsRuntime.ShowToast(ToastType.error, $"Download fehlgeschlagen, da die RMA aufgrund von falschen Eingaben nicht gespeichert werden konnte");
                return;
            }

            if (!Input.ZurückAnKunde)
            {
                Input.ZurückAnKunde = true;
            }

            if (Input.ZurückAnKundeDatum == default)
            {
                Input.ZurückAnKundeDatum = DateTime.Now;
            }

            await SaveAsync();

            _isDownloading = true;

            using FbController2 fbController = new FbController2();
            var rma = await DruckRma.GetDruckRmaAsync(RmaNummer, fbController);

            if (rma is not null)
            {

                BriefRegelsatz printRegeln = new BriefRegelsatz
                {
                    ShowFooter = true,
                    ShowHeader = true
                };

                if (Program.AppDaten.VersandMehrwertsteuer is null)
                {
                    throw new ArgumentNullException(nameof(Program.AppDaten.VersandMehrwertsteuer));
                }

                PrintRmaVersandbelegKunde rmaPrinter = await PrintRmaVersandbelegKunde.CreateAsync(rma, printRegeln);
                string fullFilename = rmaPrinter.Print(GlobalConfig.Configuration.OutputPfad);
                await downloadService.DownloadFile(Path.GetFileName(fullFilename), await File.ReadAllBytesAsync(fullFilename), "application/pdf");
                await downloadService.ClearBuffers();
            }

            _isDownloading = false;
        }
        #endregion
        #region Mails 
        private async Task MailRücksendeAnforderungAsync()
        {
            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }
            if (Input.RückversandVonKundeDirektZumLieferant && String.IsNullOrWhiteSpace(Input.RmaNummerLieferant))
            {
                await jsRuntime.ShowToast(ToastType.error, $"RMA-Nummer von Lieferant ist erforderlich, da die Ware direkt zum Lieferanten verschickt werden soll");
                return;
            }

            if (!_editForm.EditContext.Validate())
            {
                await jsRuntime.ShowToast(ToastType.error, $"Download fehlgeschlagen, da die RMA aufgrund von falschen Eingaben nicht gespeichert werden konnte");
                return;
            }

            if (!Input.RücksendungAngefordert)
            {
                Input.RücksendungAngefordert = true;
            }

            if (Input.RücksendungAngefordertDatum == default)
            {
                Input.RücksendungAngefordertDatum = DateTime.Now;
            }

            await SaveAsync();

            _mailIsLoading = true;

            using FbController2 fbController = new FbController2();
            var rma = await DruckRma.GetDruckRmaAsync(RmaNummer, fbController);

            if (rma is not null)
            {
                string empfängerEmail = rma.KundeEmail;

                if (!String.IsNullOrWhiteSpace(rma.KundeLieferanschriftEmail))
                {
                    empfängerEmail = rma.KundeLieferanschriftEmail;
                }

                if (!String.IsNullOrWhiteSpace(rma.KundeAnsprechpartnerEmail))
                {
                    empfängerEmail = rma.KundeAnsprechpartnerEmail;
                }

                KarleyBrowserInterfaceEmail email = new KarleyBrowserInterfaceEmail
                {
                    Absender = GlobalConfig.EmailInfoEU,
                    Empfänger = empfängerEmail,
                    Content = String.Empty,
                    Betreff = $"RMA {RmaNummer}"
                };

                PrintKundeVersandAnforderungRegelsatz printRegeln = new PrintKundeVersandAnforderungRegelsatz
                {
                    ShowFooter = true,
                    ShowHeader = true
                };


                PrintKundeVersandAnforderung rmaPrinter = await PrintKundeVersandAnforderung.CreateAsync(rma, printRegeln);
                string fullFilename = rmaPrinter.Print(GlobalConfig.Configuration.OutputPfad);
                email.Anhänge.Add(fullFilename);

                var (success, data, _) = KarleyLibrary.Serialization.XMLWriter.Serialize(email);
                if (success)
                {
                    string xmlFilename = $"{email.GetHashCode()}.xml";
                    await File.WriteAllTextAsync(Path.Combine(GlobalConfig.Configuration.OutputPfad, xmlFilename), data);
                    await jsRuntime.OpenNewTab($"karley:davidMail;{xmlFilename}");
                }
            }

            _mailIsLoading = false;
        }
        private async Task MailEingangsbelegAsync()
        {
            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }

            if (!_editForm.EditContext.Validate())
            {
                await jsRuntime.ShowToast(ToastType.error, $"Download fehlgeschlagen, da die RMA aufgrund von falschen Eingaben nicht gespeichert werden konnte");
                return;
            }

            if (!Input.Eingangsbeleg)
            {
                Input.Eingangsbeleg = true;
            }

            if (Input.EingangsbelegDatum == default)
            {
                Input.EingangsbelegDatum = DateTime.Now;
            }

            await SaveAsync();

            _mailIsLoading = true;

            using FbController2 fbController = new FbController2();
            var rma = await DruckRma.GetDruckRmaAsync(RmaNummer, fbController);

            if (rma is not null)
            {
                string empfängerEmail = rma.KundeEmail;

                if (!String.IsNullOrWhiteSpace(rma.KundeLieferanschriftEmail))
                {
                    empfängerEmail = rma.KundeLieferanschriftEmail;
                }

                if (!String.IsNullOrWhiteSpace(rma.KundeAnsprechpartnerEmail))
                {
                    empfängerEmail = rma.KundeAnsprechpartnerEmail;
                }

                BriefRegelsatz printRegeln = new BriefRegelsatz
                {
                    ShowFooter = true,
                    ShowHeader = true
                };

                KarleyBrowserInterfaceEmail email = new KarleyBrowserInterfaceEmail
                {
                    Absender = GlobalConfig.EmailInfoEU,
                    Empfänger = empfängerEmail,
                    Content = String.Empty,
                    Betreff = $"Wareneingangsbestätigung RMA-{RmaNummer} KD:{SelectedKunde?.KUND_A_NR}"
                };

                PrintKundeWareneingangsbestätigung rmaPrinter = await PrintKundeWareneingangsbestätigung.CreateAsync(rma, printRegeln);
                string fullFilename = rmaPrinter.Print(GlobalConfig.Configuration.OutputPfad);
                email.Anhänge.Add(fullFilename);

                var (success, data, _) = KarleyLibrary.Serialization.XMLWriter.Serialize(email);
                if (success)
                {
                    string xmlFilename = $"{email.GetHashCode()}.xml";
                    await File.WriteAllTextAsync(Path.Combine(GlobalConfig.Configuration.OutputPfad, xmlFilename), data);
                    await jsRuntime.OpenNewTab($"karley:davidMail;{xmlFilename}");
                }
            }

            _mailIsLoading = false;
        }
        private async Task MailRmaAnfrageLieferantAsync()
        {
            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }

            if (String.IsNullOrWhiteSpace(Input.FehlerangabeLieferant))
            {
                await jsRuntime.ShowToast(ToastType.error, $"Bitte geben Sie einer Fehlerbezeichnung für den Lieferanten ein");
                return;
            }

            if (!_editForm.EditContext.Validate())
            {
                await jsRuntime.ShowToast(ToastType.error, $"Download fehlgeschlagen, da die RMA aufgrund von falschen Eingaben nicht gespeichert werden konnte");
                return;
            }

            if (!Input.AnfrageLieferant)
            {
                Input.AnfrageLieferant = true;
            }

            if (Input.AnfrageLieferantDatum == default)
            {
                Input.AnfrageLieferantDatum = DateTime.Now;
            }

            await SaveAsync();

            _mailIsLoading = true;

            using FbController2 fbController = new FbController2();
            var rma = await DruckRma.GetDruckRmaAsync(RmaNummer, fbController);

            if (rma is not null)
            {
                string empfängerEmail = rma.LieferantEmail;

                if (!String.IsNullOrWhiteSpace(rma.LieferantAnsprechpartnerEmail))
                {
                    empfängerEmail = rma.LieferantAnsprechpartnerEmail;
                }

                // MK: Mit Technik besprochen, diese Mail soll niemals an die Lieferanschrift des Lieferanten gehen
                /*
                if (!String.IsNullOrWhiteSpace(rma.LieferantLieferanschriftEmail))
                {
                    empfängerEmail = rma.LieferantLieferanschriftEmail;
                }*/

                KarleyBrowserInterfaceEmail email = new KarleyBrowserInterfaceEmail
                {
                    Absender = GlobalConfig.EmailInfoEU,
                    Empfänger = empfängerEmail,
                    Content = String.Empty,
                    Betreff = $"RMA-Anfrage {RmaNummer}"
                };

                BriefRegelsatz printRegeln = new BriefRegelsatz
                {
                    ShowFooter = true,
                    ShowHeader = true
                };



                PrintRmaAnfrageLieferant rmaPrinter = await PrintRmaAnfrageLieferant.CreateAsync(rma, printRegeln);
                string fullFilename = rmaPrinter.Print(GlobalConfig.Configuration.OutputPfad);
                email.Anhänge.Add(fullFilename);

                var (success, data, _) = KarleyLibrary.Serialization.XMLWriter.Serialize(email);
                if (success)
                {
                    string xmlFilename = $"{email.GetHashCode()}.xml";
                    await File.WriteAllTextAsync(Path.Combine(GlobalConfig.Configuration.OutputPfad, xmlFilename), data);
                    await jsRuntime.OpenNewTab($"karley:davidMail;{xmlFilename}");
                }
            }

            _mailIsLoading = false;
        }
        private async Task MailRücksendebelegLieferantAsync()
        {
            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }

            if (String.IsNullOrWhiteSpace(Input.FehlerangabeLieferant))
            {
                await jsRuntime.ShowToast(ToastType.error, $"Bitte geben Sie einer Fehlerbezeichnung für den Lieferanten ein");
                return;
            }

            if (String.IsNullOrWhiteSpace(Input.RmaNummerLieferant))
            {
                await jsRuntime.ShowToast(ToastType.error, $"Bitte geben Sie einer RMA-Nummer vom Lieferanten an");
                return;
            }

            if (!_editForm.EditContext.Validate())
            {
                await jsRuntime.ShowToast(ToastType.error, $"Download fehlgeschlagen, da die RMA aufgrund von falschen Eingaben nicht gespeichert werden konnte");
                return;
            }

            if (!Input.RücksendungAnLieferant)
            {
                Input.RücksendungAnLieferant = true;
            }

            if (Input.RücksendungAnLieferantDatum == default)
            {
                Input.RücksendungAnLieferantDatum = DateTime.Now;
            }

            await SaveAsync();

            _mailIsLoading = true;

            using FbController2 fbController = new FbController2();
            var rma = await DruckRma.GetDruckRmaAsync(RmaNummer, fbController);

            if (rma is not null)
            {

                string empfängerEmail = rma.LieferantEmail;

                if (!String.IsNullOrWhiteSpace(rma.LieferantAnsprechpartnerEmail))
                {
                    empfängerEmail = rma.LieferantAnsprechpartnerEmail;
                }


                if (!String.IsNullOrWhiteSpace(rma.LieferantLieferanschriftEmail))
                {
                    empfängerEmail = rma.LieferantLieferanschriftEmail;
                }

                KarleyBrowserInterfaceEmail email = new KarleyBrowserInterfaceEmail
                {
                    Absender = GlobalConfig.EmailInfoEU,
                    Empfänger = empfängerEmail,
                    Content = String.Empty,
                    Betreff = $"Rücksendung von RMA {rma.RmaNummerLieferant} (Unsere RMA-Nr: {RmaNummer})"
                };

                BriefRegelsatz printRegeln = new BriefRegelsatz
                {
                    ShowFooter = true,
                    ShowHeader = true
                };

                PrintRmaVersandbelegLieferant rmaPrinter = await PrintRmaVersandbelegLieferant.CreateAsync(rma, printRegeln);
                string fullFilename = rmaPrinter.Print(GlobalConfig.Configuration.OutputPfad);
                email.Anhänge.Add(fullFilename);

                var (success, data, _) = KarleyLibrary.Serialization.XMLWriter.Serialize(email);
                if (success)
                {
                    string xmlFilename = $"{email.GetHashCode()}.xml";
                    await File.WriteAllTextAsync(Path.Combine(GlobalConfig.Configuration.OutputPfad, xmlFilename), data);
                    await jsRuntime.OpenNewTab($"karley:davidMail;{xmlFilename}");
                }
            }

            _mailIsLoading = false;
        }
        private async Task MailRücksendebelegKundeAsync()
        {
            if (_editForm is null || _editForm.EditContext is null)
            {
                return;
            }

            if (String.IsNullOrWhiteSpace(Input.RücklieferInfo))
            {
                await jsRuntime.ShowToast(ToastType.error, $"Bitte geben Sie Rücklieferinfo für den Kunden ein");
                return;
            }

            if (!_editForm.EditContext.Validate())
            {
                await jsRuntime.ShowToast(ToastType.error, $"Download fehlgeschlagen, da die RMA aufgrund von falschen Eingaben nicht gespeichert werden konnte");
                return;
            }

            if (!Input.ZurückAnKunde)
            {
                Input.ZurückAnKunde = true;
            }

            if (Input.ZurückAnKundeDatum == default)
            {
                Input.ZurückAnKundeDatum = DateTime.Now;
            }

            await SaveAsync();

            _mailIsLoading = true;

            using FbController2 fbController = new FbController2();
            var rma = await DruckRma.GetDruckRmaAsync(RmaNummer, fbController);

            if (rma is not null)
            {
                string empfängerEmail = rma.KundeEmail;

                if (!String.IsNullOrWhiteSpace(rma.KundeLieferanschriftEmail))
                {
                    empfängerEmail = rma.KundeLieferanschriftEmail;
                }

                if (!String.IsNullOrWhiteSpace(rma.KundeAnsprechpartnerEmail))
                {
                    empfängerEmail = rma.KundeAnsprechpartnerEmail;
                }

                KarleyBrowserInterfaceEmail email = new KarleyBrowserInterfaceEmail
                {
                    Absender = GlobalConfig.EmailInfoEU,
                    Empfänger = empfängerEmail,
                    Content = String.Empty,
                    Betreff = $"Rücksendung von RMA {RmaNummer} KD:{SelectedKunde?.KUND_A_NR}"
                };

                BriefRegelsatz printRegeln = new BriefRegelsatz
                {
                    ShowFooter = true,
                    ShowHeader = true
                };


                PrintRmaVersandbelegKunde rmaPrinter = await PrintRmaVersandbelegKunde.CreateAsync(rma, printRegeln);
                string fullFilename = rmaPrinter.Print(GlobalConfig.Configuration.OutputPfad);
                email.Anhänge.Add(fullFilename);

                var (success, data, _) = KarleyLibrary.Serialization.XMLWriter.Serialize(email);
                if (success)
                {
                    string xmlFilename = $"{email.GetHashCode()}.xml";
                    await File.WriteAllTextAsync(Path.Combine(GlobalConfig.Configuration.OutputPfad, xmlFilename), data);
                    await jsRuntime.OpenNewTab($"karley:davidMail;{xmlFilename}");
                }
            }

            _mailIsLoading = false;
        }
        #endregion
        #region Autocomplete
        private Task AnfrageLieferantChangedAsync(bool newValue)
        {
            Input.AnfrageLieferant = newValue;
            if (Input.AnfrageLieferant)
            {
                Input.AnfrageLieferantDatum = DateTime.Now;
            }
            else
            {
                Input.AnfrageLieferantDatum = new DateTime();
            }
            return Task.CompletedTask;
        }

        private Task EingangsbelegChangedAsync(bool newValue)
        {
            Input.Eingangsbeleg = newValue;
            if (Input.Eingangsbeleg)
            {
                Input.EingangsbelegDatum = DateTime.Now;
            }
            else
            {
                Input.EingangsbelegDatum = new DateTime();
            }
            return Task.CompletedTask;
        }

        private Task ZurückVonLieferantChangedAsync(bool newValue)
        {
            Input.ZurückVonLieferant = newValue;
            if (Input.ZurückVonLieferant)
            {
                Input.ZurückVonLieferantDatum = DateTime.Now;
            }
            else
            {
                Input.ZurückVonLieferantDatum = new DateTime();
            }
            return Task.CompletedTask;
        }

        private Task ZurückVonKundeChangedAsync(bool newValue)
        {
            Input.ZurückAnKunde = newValue;
            if (Input.ZurückAnKunde)
            {
                Input.ZurückAnKundeDatum = DateTime.Now;
            }
            else
            {
                Input.ZurückAnKundeDatum = new DateTime();
            }
            return Task.CompletedTask;
        }

        private Task RücksendungAngefordertChangedAsync(bool newValue)
        {
            Input.RücksendungAngefordert = newValue;
            if (Input.RücksendungAngefordert)
            {
                Input.RücksendungAngefordertDatum = DateTime.Now;
            }
            else
            {
                Input.RücksendungAngefordertDatum = new DateTime();
            }
            return Task.CompletedTask;
        }

        private Task RücksendungAnLieferantChangedAsync(bool newValue)
        {
            Input.RücksendungAnLieferant = newValue;
            if (Input.RücksendungAnLieferant)
            {
                Input.RücksendungAnLieferantDatum = DateTime.Now;
            }
            else
            {
                Input.RücksendungAnLieferantDatum = new DateTime();
            }
            return Task.CompletedTask;
        }

        private Task LieferantenbelastungChangedAsync(bool newValue)
        {
            Input.Lieferantenbelastung = newValue;
            if (Input.Lieferantenbelastung)
            {
                Input.LieferantenbelastungDatum = DateTime.Now;
            }
            else
            {
                Input.LieferantenbelastungDatum = new DateTime();
            }
            return Task.CompletedTask;
        }

        private Task LieferanschriftKundeChangedAsync(int anschriftId)
        {
            Input.LieferanschriftKundeId = anschriftId;
            LieferanschriftKunde = _lieferanschriften.FirstOrDefault(x => x.KULA_N_NR == anschriftId);
            return Task.CompletedTask;
        }

        private Task LieferanschriftLieferantChangedAsync(int anschriftId)
        {
            Input.LieferanschriftLieferantId = anschriftId;
            LieferanschriftLieferant = _lieferantenAnschriften.FirstOrDefault(x => x.LIRE_N_NR == anschriftId);
            return Task.CompletedTask;
        }

        private Task KundeAnsprechpartnerChangedAsync(string partner)
        {
            Input.KundeAnsprechpartner = partner;

            Ansprechpartner? ansprechpartner = _ansprechpartner.Where(x => x.GetName() == partner).FirstOrDefault();
            Input.KundeAnsprechpartnerEmail = ansprechpartner?.PART_A_EMAIL ?? string.Empty;

            return Task.CompletedTask;
        }

        private Task LieferantAnsprechpartnerChangedAsync(string partner)
        {
            Input.LieferantAnsprechpartner = partner;

            AnsprechpartnerLieferant? ansprechpartner = _ansprechpartnerLieferant.Where(x => x.GetName() == partner).FirstOrDefault();
            Input.LieferantAnsprechpartnerEmail = ansprechpartner?.LIEP_A_EMAIL ?? string.Empty;

            return Task.CompletedTask;
        }
        private async Task LadeRmaBelegeAsync()
        {
            using FbController2 fbController = new FbController2();
            _rmaBelege = await rmaService.GetRmaBelegeAsync(RmaNummer, fbController).ToListAsync();
        }
        #endregion
        #region IEditPage
        public string ActivePageName => Modus switch
        {
            EditMode.Anlage => "Neue RMA",
            EditMode.Bearbeiten => $"RMA-{RmaNummer}",
            _ => "Unbekannt"
        };
        public string FinalBreadcrumbItemName => Modus switch
        {
            EditMode.Anlage => "Neu",
            EditMode.Bearbeiten => $"{RmaNummer}",
            _ => "Unbekannt"
        };
        public EditMode Modus { get; set; } = EditMode.Anlage;
        public List<RmaTabs> EditOnlyTabs { get; set; } = new List<RmaTabs>
        {
            RmaTabs.Belege,
            RmaTabs.Dokumentenablage,
            RmaTabs.Verlauf,
            RmaTabs.Historie
        };
        public List<RmaTabs> AdminOnlyTabs { get; set; } = new List<RmaTabs>();

        public string GetNavListClass(bool active) => active ? "nav-link active" : "nav-link";
        public string GetTabClass(bool active) => active ? "tab-pane fade active show" : "tab-pane fade";
        public string GetSubNavListClass(bool active) => active ? "list-group-item list-group-item-action active" : "list-group-item list-group-item-action";

        public async Task LadeEditModeAsync()
        {
            using FbController2 fbController = new FbController2();
            Rma? rma = await rmaService.GetAsync(RmaNummer, fbController);
            if (rma is not null)
            {
                Input = rma;
                await LadeDatenAsync();

                SelectedLieferschein = await Lieferschein.GetLieferscheinAsync(Input.LieferscheinNummer, fbController);
                await SelectPositionAsync(SelectedLieferschein.GetEndPositionen().FirstOrDefault(x => x.PosId == Input.BelegposId && x.StücklistenPositionsId == Input.StücklistenPositionsId));
                await SelectBelegchargeAsync(await Belegcharge.GetBelegchargeAsync(Input.BelegChargenId));
                IstErledigt = Input.Erledigt;
                Modus = EditMode.Bearbeiten;
            }

            if (!_isDisposed)
            {
                await CheckActivePageAsync();
            }
        }

        #endregion
        #region Austausch
        private Task Button_AustauschDurchführenAsync()
        {
            if (Input.Austauschtyp is 0)
            {
                AustauschSchritt = RmaAustauschSchritt.EigenGarantie;
                _showAustauschModal = true;
            }
            return Task.CompletedTask;
        }

        private Task Button_WareEinlagernAsync()
        {
            if (Input.NewZugangId is 0)
            {
                navigationManager.NavigateTo($"/Zugang/Neu/{RmaNummer}");
            }
            return Task.CompletedTask;
        }
        private async Task ConfirmEigenGarantieAsync()
        {
            Input.Garantie = true;
            await SaveAsync();
            AustauschSchritt = RmaAustauschSchritt.EigenAustausch;
        }

        private async Task DeclineEigenGarantieAsync()
        {
            Input.Garantie = false;
            await SaveAsync();
            AustauschSchritt = RmaAustauschSchritt.EigenGarantie;

            _showAustauschModal = false;
            _showEigenGarantieDeclinedModal = true;
        }

        private async Task ConfirmEigenAustauschAsync()
        {
            Input.Austauschtyp = 1;
            await SaveAsync();
            navigationManager.NavigateTo($"/Lieferscheine/Neu/{RmaNummer}/1");
        }

        private async Task DeclineEigenAustauschAsync()
        {
            AustauschSchritt = RmaAustauschSchritt.LieferantenGarantie;
        }

        private async Task ConfirmLieferantenGarantieAsync()
        {
            Input.GarantieLieferant = true;
            await SaveAsync();
            AustauschSchritt = RmaAustauschSchritt.LieferantenAustausch;
        }

        private async Task DeclineLieferantenGarantieAsync()
        {
            Input.GarantieLieferant = false;
            await SaveAsync();
            AustauschSchritt = RmaAustauschSchritt.EigenGarantie;
            _showAustauschModal = false;
        }

        private async Task ConfirmLieferantenAustauschAsync()
        {
            Input.Austauschtyp = 2;
            await SaveAsync();
            navigationManager.NavigateTo($"/Zugang/Neu/{RmaNummer}/true");
        }

        private async Task DeclineLieferantenAustauschAsync()
        {
            Input.Austauschtyp = 3;
            Input.Lieferantenbelastung = true;
            Input.LieferantenbelastungDatum = DateTime.Now;
            await SaveAsync();
            _showAustauschModal = false;
        }

        #endregion

        private Task ShowKundenKontakte(string kundennummer)
        {
            _selectedKundennummer = kundennummer;
            _showKundenkontakte = true;
            return Task.CompletedTask;
            
        }
        public override async Task CheckActivePageAsync()
        {
            var (success, page) = ActivePages.AddActivePage(new ActivePage(PageType.RMA, RmaNummer.ToString(), Mitarbeiter.PersonalNummer));

            if (success)
            {
                Page = page;
            }
            else
            {
                await AddAlertAsync(new AlertBox
                {
                    AlertType = AlertType.Danger,
                    Message = $"Die RMA wird zurzeit durch {Program.AppDaten.GetMitarbeiterName(page.UserId)} bearbeitet."
                });

                SperreDurchAnderenUser = true;
            }
        }

        public override ValueTask DisposeAsync()
        {
            return base.DisposeAsync();
        }

        public async Task OnTabChange(RmaTabs newActiveTab)
        {
            switch (newActiveTab)
            {
                case RmaTabs.Belege:
                    await LadeRmaBelegeAsync();
                    break;
                case RmaTabs.Historie:
                    await LadeHistorieAsync();
                    break;
                default:
                    break;
            }
        }

        public override void AddHotKeys(HotKeysContext context)
        {
            context
                .Add(ModKeys.Alt, Keys.S, SubmitAsync, "Speichert die RMA", Exclude.Default)
                .Add(ModKeys.Alt, Keys.Z, () => { _showZeiterfassungModal = true; StateHasChanged(); }, "Öffnet die Zeiterfassung", Exclude.Default)
                .Add(ModKeys.Alt, Keys.Right, NextTab, "Wechselt zum nächsten Tab", Exclude.Default)
                .Add(ModKeys.Alt, Keys.Left, PrevTab, "Wechselt zum vorherigen Tab", Exclude.Default)
                ;
        }

        public Task NextTab()
        {
            bool found = false;
            int tabIndex = ((int)ActiveTab + 1) % Enum.GetValues(typeof(RmaTabs)).Length;
            while (!found)
            {
                RmaTabs tab = (RmaTabs)tabIndex;
                if (EditOnlyTabs.Contains(tab) && Modus != EditMode.Bearbeiten)
                {
                    tabIndex = (tabIndex + 1) % Enum.GetValues(typeof(RmaTabs)).Length;
                    continue;
                }

                if (AdminOnlyTabs.Contains(tab) && !Mitarbeiter.IsAdmin)
                {
                    tabIndex = (tabIndex + 1) % Enum.GetValues(typeof(RmaTabs)).Length;
                    continue;
                }

                found = true;
            }

            ActiveTab = (RmaTabs)tabIndex;
            StateHasChanged();
            return Task.CompletedTask;
        }

        public Task PrevTab()
        {
            bool found = false;
            int tabIndex = (int)ActiveTab - 1 < 0 ? Enum.GetValues(typeof(RmaTabs)).Length - 1 : (int)ActiveTab - 1;
            while (!found)
            {
                RmaTabs tab = (RmaTabs)tabIndex;
                if (EditOnlyTabs.Contains(tab) && Modus != EditMode.Bearbeiten)
                {
                    tabIndex = tabIndex - 1 < 0 ? Enum.GetValues(typeof(RmaTabs)).Length - 1 : tabIndex - 1;
                    continue;
                }

                if (AdminOnlyTabs.Contains(tab) && !Mitarbeiter.IsAdmin)
                {
                    tabIndex = tabIndex - 1 < 0 ? Enum.GetValues(typeof(RmaTabs)).Length - 1 : tabIndex - 1;
                    continue;
                }

                found = true;
            }

            ActiveTab = (RmaTabs)tabIndex;
            StateHasChanged();
            return Task.CompletedTask;
        }
    }
}
