using MbeSoap;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc;
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.Drucken.Lieferscheine;
using WK5.Core.Drucken.Rechnungen;
using WK5.Core.Email;
using WK5.Core.Models;
using WK5.Core.Models.Tools.Lagerregal;
using WK5.Core.Models.Versand;
using WK5.Core.OnlineShop;
using WK5.Core.PageModels;
using WK5.Core.PageModels.Tools.Versand;

namespace WK5_Blazor.Components.Modals
{
    public partial class VersandModal
    {
        private bool _Show { get; set; }
        private RecipientType? _recipient = null;
        private decimal _belegGewicht = 0m;
        private bool _sperrSendenButton = false;

#nullable disable
        [CascadingParameter] public AppMitarbeiter Mitarbeiter { get; set; }
#nullable enable
        private string ModalSizeClass => ModalSize switch
        {
            ModalSize.Default => "modal-dialog",
            ModalSize.SM => "modal-dialog modal-sm",
            ModalSize.LG => "modal-dialog modal-lg",
            ModalSize.XL => "modal-dialog modal-xl",
            _ => "modal-dialog"
        };

        [Parameter]
        public ModalSize ModalSize { get; set; } = ModalSize.Default;

#nullable disable
        [Parameter] public Beleg Beleg { get; set; }
#nullable enable
        [BindProperty] private VersandModalInput Input { get; set; } = new VersandModalInput();

        private bool _istTeillieferung = false;
        private string _bestellnummer = String.Empty;

        private int _auslandMaxPakete = 1;

        public void Show()
        {
            _Show = !_Show;
            StateHasChanged();
        }

        private async Task PaketeErstellen()
        {
            _sperrSendenButton = true;


            if (Mitarbeiter.PersonalNummer > 0)
            {

                List<ItemType> pakete = new List<ItemType>();
                foreach (var paket in Input.Pakete)
                {
                    pakete.Add(new ItemType
                    {
                        Weight = paket.Gewicht,
                        Dimensions = new DimensionsType { Height = 0, Lenght = 0, Width = 0 }
                    });
                }

                using FbController2 fbController = new FbController2();

                try
                {
                    var (erfolgreich, successResponses, alerts) = await versandService.PaketeEintragen(
                        beleg: Beleg,
                        lieferanschrift: await Beleg.ToRecipientTypeAsync(fbController),
                        pakete: pakete,
                        versandOption: new VersandOption(Beleg),
                        personalNummer: Mitarbeiter.PersonalNummer
                    );

                    foreach (var alert in alerts)
                    {
                        await AddAlertAsync(alert);
                    }

                    if (Input.MailSenden)
                    {
                        await SendeMail(successResponses, Mitarbeiter.PersonalNummer, fbController);
                    }

                    // Wir brauchen ggf. noch zusätzliche Lieferscheine
                    if (Input.AnzahlPakete > 1)
                    {

                        Lieferschein? lieferschein = await Lieferschein.GetLieferscheinAsync(Beleg.LieferscheinnummerVerknüpfung, fbController);
                        if (lieferschein is not null)
                        {

                            string printerName = GlobalConfig.GetDocumentPrinterLager();
                            if (!lieferschein.NeutralerVersender)
                            {
                                PrintLieferschein printLieferschein = await PrintLieferschein.CreateAsync(lieferschein, new PrintLieferscheinRegelsatz { ShowHeader = true, ShowFooter = true });
                                string filenameLieferscheinPdf = printLieferschein.Print(GlobalConfig.Configuration.OutputPfad);
                                for (int i = 1; i < Input.AnzahlPakete; i++)
                                {
                                    await Printer.PrintAsync(filenameLieferscheinPdf, printerName);
                                }
                            }
                            else if (lieferschein.NeutralerLieferschein.Length > 0)
                            {
                                string filenameNeutralerLieferschein = Path.Combine(GlobalConfig.Configuration.OutputPfad, $"LS_{lieferschein.Belegnummer}.pdf");
                                await File.WriteAllBytesAsync(filenameNeutralerLieferschein, lieferschein.NeutralerLieferschein);
                                await Printer.PrintAsync(filenameNeutralerLieferschein, printerName);
                            }
                        }
                    }

                    // Ist es eine Online Bestellung? Wenn ja, dann muss online der Status upgedatet werden
                    if (_bestellnummer?.StartsWith("KL-", StringComparison.OrdinalIgnoreCase) == true && int.TryParse(_bestellnummer[3..], out int order_id))
                    {

                        string trackingnummern = String.Join(", ", successResponses.Select(x => x.CourierMasterTrk));
                        try
                        {
                            ShopHelper shopHelper = new ShopHelper();
                            await shopHelper.AddOrderHistoryAsync(
                                order_id: order_id,
                                newStatus: OrderStatus.Versendet,
                                comment: $"Sendungsverfolgungsnummern: {trackingnummern}"
                            );
                            if (_istTeillieferung)
                            {
                                await shopHelper.UpdateOrderStatusAsync(order_id, OrderStatus.Versendet);
                            }
                            else
                            {
                                await shopHelper.AddOrderHistoryAsync(order_id, OrderStatus.Abgeschlossen, "");
                                await shopHelper.UpdateOrderStatusAsync(order_id, OrderStatus.Abgeschlossen);
                            }
                        }
                        catch (Exception ex)
                        {
                            await EmailController.FehlerMailSendenAsync(
                                betreff: "WK5_Blazor_VersandModal_ShopUpdate - Fehler beim ändern des Online Status",
                                body: $"Für {Beleg.Belegtyp}-{Beleg.Belegnummer} konnte im Onlineshop nicht der Status upgedatet werden. Bitte manuell hinterlegen und wenn es sich um keine Teillieferung handelt, den Auftrag auf Abgeschlossen stellen.<br /><br />Tackingnummern:{trackingnummern}<br />OrderId:{order_id}<br /><br />Fehlermeldung: <br /> {ex.Message}",
                                empfänger: "info@karley.eu;software@karley.eu"
                            );
                        }

                    }
                }
                catch (VersandNotPossibleException)
                {
                    await AddAlertAsync(new AlertBox
                    {
                        AlertType = AlertType.Warning,
                        Message = "Es können keine Pakete erstellt werden, da die Lieferbedingung keinen Versand/Abholung erfordert."
                    });

                    await EmailController.FehlerMailSendenAsync(
                        betreff: $"WK5_Blazor_VersandNotPossible - {Beleg.Belegtyp}-{Beleg.Belegnummer}",
                        body: "Der Beleg wurde über das Lagerregal gepackt. Bitte prüfen und dem Kunden ggf. manuell informieren und die Rechnung zukommen lassen.",
                        empfänger: GlobalConfig.Configuration.FirmenDaten.Email
                    );

                }
            }
            else
            {
                await AddAlertAsync(new AlertBox { AlertType = AlertType.Danger, Message = "Sie besitzen keine gültige Personalnummer. Bitte wenden Sie sich an die Programmierung." });
            }

            navigationManager.NavigateTo("/Lagerregal");
            _sperrSendenButton = false;

        }

        private async Task SendeMail(List<ShipmentResponseType> success, int personalNummer, FbController2 fbController)
        {

            VersandMailer mailer = await VersandMailer.CreateAsync(Beleg, success.Select(x => x.CourierMasterTrk).ToList(), new VersandOption(Beleg), personalNummer, fbController);
            var responses = await mailer.EmailSendenAsync();

            if (responses.Where(x => !x.Success).Any())
            {
                await AddAlertAsync(new AlertBox { AlertType = AlertType.Danger, Message = "Es ist ein Fehler beim Versand der Mails aufgetreten. Es wurde eine Fehlermail an den Vertrieb gesendet." });
            }

            // Es wird keine Mail bei REDRUCK versendet, die Meldung muss der Mitarbeiter sehen!
            foreach (var response in responses.Where(x => x.Success && x.Status is not EmailVersandState.OK))
            {
                await AddAlertAsync(new AlertBox
                {
                    AlertType = AlertType.Warning,
                    Message = response.Message ?? String.Empty
                });

            }
        }
        protected override async Task OnParametersSetAsync()
        {
            await BerechnePaketAnzahl();
        }

        private async Task BerechnePaketAnzahl()
        {
            if (Beleg != null)
            {
                if (_recipient is null)
                {
                    using FbController2 fbController = new FbController2();
                    _recipient = await Beleg.ToRecipientTypeAsync(fbController);
                }

                if (Input.AnzahlPakete == 0)
                {
                    // Wir können ja ungefähr sagen, wie viele Pakete wir haben
                    _belegGewicht = Beleg.GetBelegGewicht();

                    for (int i = 0; i < (int)(_belegGewicht / 30); i++)
                    {
                        Input.AddPaket();
                    }

                    if (Input.AnzahlPakete == 0)
                    {
                        Input.AddPaket();
                    }
                }

                _auslandMaxPakete = Input.AnzahlPakete;
            }
        }

        public void SetBeleg(Beleg beleg, bool istTeillieferung, string bestellnummer)
        {
            this.Beleg = beleg;
            this._istTeillieferung = istTeillieferung;
            this._bestellnummer = bestellnummer;
            BerechnePaketAnzahl();
        }
    }
}
