using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WK5.Core;
using WK5.Core.Basis;
using WK5.Core.Basis.Erweiterungen;
using WK5.Core.Drucken.Bestellungen;
using WK5.Core.Drucken.Warenbegleitscheine;
using WK5.Core.Email;
using WK5.Core.Models;
using WK5.Core.Models.Bestellungen;

namespace WK5_Blazor.Pages.Bestellungen
{
    public partial class AuftragBestellen : IPipeline<AuftragBestellenController>
    {
        [Parameter] public int Auftragsnummer { get; set; }
#nullable disable
        [CascadingParameter] public AppMitarbeiter Mitarbeiter { get; set; }
#nullable enable
        private AuftragBestellenBestellung? SelectedBestellung { get; set; }
        private AuftragBestellenController? Controller { get; set; }
        public Pipeline<AuftragBestellenController> Pipeline { get; set; } = new Pipeline<AuftragBestellenController>();

        private bool showNichtVerfügbareArtikelModal;
        private bool submitting;
        
        private AuftragBestellenPosition? _currentPos;
        private EditForm? _form;
        private List<AuftragBestellenBestellung> _mindestbestellsummeNichtErreicht = new List<AuftragBestellenBestellung>();
        private bool _showMindestbestellsummeModal;
        protected override async Task OnParametersSetAsync()
        {
            using FbController2 fbController = new FbController2();
            var auftrag = await Auftrag.GetAuftragAsync(Auftragsnummer, fbController);

            if (auftrag is not null)
            {
                Bestellung? bestellung = await auftrag.GetBestellungenAsync(fbController).FirstOrDefaultAsync();
                Controller = new AuftragBestellenController(auftrag, bestellung is null);
                if (bestellung is not null && !submitting)
                {
                    await ExitWithErrorAsync($"Für den Auftrag {auftrag.Belegnummer} kann keine Bestellung durch den ShopImport erstellt werden, da für diesen bereits eine Bestellung gefunden wurde.", $"/Bestellungen/{bestellung.Bestellnummer}");
                }
            }
            else
            {
                await ExitWithErrorAsync($"Der Auftrag {Auftragsnummer} konnte nicht gefunden werden");
            }

            await SetupPipelineAsync();
        }

        private async Task SubmitAsync()
        {
            if(_form is null || _form.EditContext is null || Controller is null)
            {
                return;
            }

            if (_form.EditContext.Validate())
            {
                Pipeline.Reset();
                await Pipeline.RunUntilFailureAsync(Controller);
            }
        }
        private async Task ExitWithErrorAsync(string message, string redirect = "/Bestellungen")
        {
            await AddAlertAsync(new AlertBox(
                message: message,
                alertType: AlertType.Danger)
            );

            navigationManager.NavigateTo(redirect);
        }
        private async Task SaveAsync()
        {
            if (Mitarbeiter is null)
            {
                return;
            }
            submitting = true;

            if (Controller is not null)
            {
                
                using FbController2 fbController = new FbController2(Mitarbeiter.PersonalNummer);
                await fbController.StartTransactionAsync();
                List<int> bestellnummern = new List<int>();
                try
                {
                    foreach (var bestellung in Controller.Bestellungen)
                    {
                        var bestellnummer = await bestellService.CreateBestellungAsync(fbController, bestellung, Controller.Auftrag, Mitarbeiter.PersonalNummer);
                        bestellnummern.Add(bestellnummer);

                        var gesamtNetto = bestellung.Positionen.Sum(x => x.Menge * x.PreisMitRabatt);
                        decimal mindestbestellwert = bestellung.Lieferant?.Mindestbestellwert ?? 0;

                        if(gesamtNetto < mindestbestellwert)
                        {
                            await BelegChange.InsertBelegChangeAsync(fbController, new BelegChange
                            {
                                BCNG_A_BELEGTYP = "BE",
                                BCNG_N_BELEGNR = bestellnummer.ToString(),
                                BCNG_N_ART = 140,
                                BCNG_A_WERTALT = "Bestätigt durch:",
                                BCNG_A_WERTNEU = Mitarbeiter.Username
                            });
                        }
                        
                        
                        // Mails Generieren
                        await SendMail(fbController, bestellnummer, bestellung.Lieferant!.Land, Mitarbeiter);
                    }
                    await fbController.CommitChangesAsync();

                    if (bestellnummern.Count is 1)
                    {
                        await AddAlertAsync(new AlertBox
                        {
                            AlertType = AlertType.Success,
                            Message = $"Bestellung {bestellnummern[0]} wurde angelegt.",
                            DecayTime = 10
                        });

                        navigationManager.NavigateTo($"/Bestellungen/{bestellnummern[0]}");
                    }
                    else
                    {
                        await AddAlertAsync(new AlertBox
                        {
                            AlertType = AlertType.Success,
                            Message = $"Bestellungen {String.Join(", ", bestellnummern)} wurden erfolgreich angelegt.",
                            DecayTime = 10
                        });

                        navigationManager.NavigateTo("/Bestellungen");
                    }
                }
                catch (Exception ex)
                {
                    await fbController.RollbackChangesAsync();
                    throw;
                }
            }


        }

        private async Task AddPositionToBestellung(AuftragBestellenBestellung bestellung)
        {
            var artikel = bestellung.GetArtikelByArtikelnummer();
            if (artikel is not null)
            {
                // Wir prüfen, ob es für den Artikel bereits eine Abrufbestellung gibt
                _currentPos = await bestellung.AddPositionAsync(artikel);
            }
        }

        private async Task LieferantIdChangedAsync(int lieferantId, AuftragBestellenBestellung bestellung)
        {
            bestellung.LieferantId = lieferantId;
            bestellung.Ansprechpartner = string.Empty;
            if (bestellung.Lieferant is not null)
            {
                bestellung.Lieferant.Ansprechpartner = await AnsprechpartnerLieferant.GetAnsprechpartnerAsync(bestellung.Lieferant.LieferantId).ToArrayAsync();
            }
        }

        private async Task SendMail(FbController2 fbController, int bestellnummer, string land, AppMitarbeiter mitarbeiter)
        {
            string pdfPfad = GlobalConfig.Configuration.OutputPfad;

            // Wir brauchen die Bestellung als PDF
            var neueBestellung = await Bestellung.GetBestellungAsync(bestellnummer, fbController) ?? throw new ArgumentNullException($"Die Bestellung {bestellnummer} konnte nicht gefunden werden.");
            

            var bestellungDruckauftrag = await PrintBestellung.CreateAsync(fbController, neueBestellung, mitarbeiter.DisplayName);
            string bestellungName = bestellungDruckauftrag.Print(pdfPfad);

            // Auch den Warenbegleitschein brauchen wir als PDF

            // Wenn wir alles haben, dann senden wir eine Mail an den Lieferanten
            string anrede = "Sehr geehrte Damen und Herren,";
            string ansprechpartnerName = String.Empty;
            string empfängerEmail = String.Empty;
            var ansprechpartner = await AnsprechpartnerLieferant.GetAnsprechpartnerByNameAsync(neueBestellung.LieferantenId, neueBestellung.BEST_A_PARTNER);

            if (ansprechpartner is not null)
            {
                if (!String.IsNullOrWhiteSpace(ansprechpartner.LIEP_A_EMAIL))
                {
                    empfängerEmail = ansprechpartner.LIEP_A_EMAIL;
                }

                anrede = ansprechpartner.LIEP_A_ANREDE ?? anrede;
                ansprechpartnerName = ansprechpartner.LIEP_A_NAME;
            }


            if (String.IsNullOrWhiteSpace(empfängerEmail))
            {
                var lieferant = await Lieferant.GetLieferantAsync(neueBestellung.LieferantenId) ?? throw new ArgumentNullException($"Lieferant {neueBestellung.LieferantenId} konnte nicht gefunden werden.");

                if (!String.IsNullOrWhiteSpace(lieferant.LIEF_A_EMAIL))
                {
                    empfängerEmail = lieferant.LIEF_A_EMAIL;
                }
            }

            if (String.IsNullOrWhiteSpace(empfängerEmail))
            {
                empfängerEmail = GlobalConfig.EmailInfoEU;
            }

            List<EmailAnhang> anhänge = new List<EmailAnhang>()
            {
                new EmailAnhang
                {
                    Name = Path.GetFileNameWithoutExtension(bestellungName),
                    Pfad = bestellungName
                }
            };


            string? warenbegleitscheinPfad = null;
            if (neueBestellung.WK5_BELE_L_DIREKTLIEFERUNG && !neueBestellung.IstAbrufbestellung)
            {
                Auftrag? auftrag = await Auftrag.GetAuftragAsync(Auftragsnummer, fbController);
                var warenbegleitscheinDruckauftrag = await PrintWarenbegleitschein.CreateAsync(neueBestellung, null, fbController);
                warenbegleitscheinPfad = warenbegleitscheinDruckauftrag.Print(pdfPfad);

                anhänge.Add(
                new EmailAnhang
                {
                    Name = Path.GetFileNameWithoutExtension(warenbegleitscheinPfad),
                    Pfad = warenbegleitscheinPfad
                });
            }


            

            KarleyBrowserInterfaceEmail email = new KarleyBrowserInterfaceEmail
            {
                Absender = GlobalConfig.EmailInfoEU,
                Empfänger = empfängerEmail,
                Content = await neueBestellung.GetEmailTextAsync(mitarbeiter.DisplayName),
                Betreff = $"Bestellung {bestellnummer}"
            };

            email.Anhänge.Add(bestellungName);

            if (warenbegleitscheinPfad is not null)
            {
                email.Anhänge.Add(warenbegleitscheinPfad);
            }

            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}");
            }
        }


        public async Task SetupPipelineAsync()
        {
            await Pipeline.HardReset();

            Pipeline.Add((input) =>
            {
                foreach (var bestellung in input.Bestellungen)
                {
                    var gesamtNetto = bestellung.Positionen.Sum(x => x.Menge * x.PreisMitRabatt);

                    decimal mindestbestellwert = bestellung.Lieferant?.Mindestbestellwert ?? 0;
                    decimal mindermengenzuschlag = bestellung.Lieferant?.Mindermengenzuschlag ?? 0;
                    
                    if(gesamtNetto < mindestbestellwert)
                    {
                        _mindestbestellsummeNichtErreicht.Add(bestellung);
                    }

                }

                _showMindestbestellsummeModal = _mindestbestellsummeNichtErreicht.Count > 0;

                return !_showMindestbestellsummeModal;
            });

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