using MbeSoap;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
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.Erweiterungen;
using WK5.Core.Basis.Filter;
using WK5.Core.Drucken;
using WK5.Core.Email;
using WK5.Core.Models;
using WK5.Core.Models.Versand;
using WK5.Core.PageModels.Lagerregal;
using WK5.Core.PageModels.Tools.Versand;
using WK5_Blazor.Components.Modals;

namespace WK5_Blazor.Pages.Tools
{
    public partial class Versand
    {
        private SelectedVersandTab SelectedVersandTab { get; set; } = SelectedVersandTab.Automatisch;

        private List<VersandKombi> _versandÜbersicht = new List<VersandKombi>();
        private List<VersandKombi> _versandÜbersichtNeutral = new List<VersandKombi>();
        private VersandBelegInput VersandBelegInput { get; set; } = new VersandBelegInput();
        private ManuellBelegVersandInput ManuellBelegVersandInput { get; set; } = new ManuellBelegVersandInput();
        private VersandOhneBelegInput VersandOhneBelegInput { get; set; } = new VersandOhneBelegInput();

        private bool _sperreManuellenSendenButton = false;
        private bool _sperreBelegSendenButton = false;
        private bool _sperreVersandOhneBelegButton = false;

        public VersandFilter Filter { get; set; } = new VersandFilter();

#nullable disable
        [CascadingParameter] public AppMitarbeiter Mitarbeiter { get; set; }
#nullable enable

        #region Modals

#nullable disable
        private LabelModal _labelModal;
        private bool _showDeleteModal;
#nullable enable



        private VersandKombi? _selectedVersandKombi;
        private void ShowLabelModal(ShipmentFullInfoType shipment)
        {
            _labelModal.SetLabel(shipment.TrackingInfo.Labels[0].Stream);
            _labelModal.Show();
        }

        private void ShowDeleteModal(VersandKombi shipment)
        {
            _selectedVersandKombi = shipment;
            _showDeleteModal = true;
        }

        private async Task DeleteShipment()
        {
            if (_selectedVersandKombi is null)
            {
                return;
            }

            var result = await versandService.PaketLöschen(_selectedVersandKombi);

            switch (result.RequestContainer.Status)
            {
                case StatusType.OK:
                    await jsRuntime.ShowToast(ToastType.success, "Sendung erfolgreich gelöscht");
                    if (_selectedVersandKombi.IstNeutralerAccount)
                    {
                        _versandÜbersichtNeutral.Remove(_selectedVersandKombi);
                    }
                    else
                    {
                        _versandÜbersicht.Remove(_selectedVersandKombi);
                    }

                    StateHasChanged();
                    break;
                case StatusType.ERROR:
                    await jsRuntime.ShowToast(ToastType.error, "Fehler beim löschen der Sendung.");
                    break;
                default:
                    break;
            }
        }
        #endregion

        private async Task LadeÜbersicht(bool istNeutral = false)
        {
            try
            {
                if (istNeutral)
                {
                    _versandÜbersichtNeutral = new List<VersandKombi>();
                    await foreach (var item in versandService.GetVersendetePaketeAsync(Filter, true))
                    {
                        if (!(item is null))
                        {
                            _versandÜbersichtNeutral.Add(item);
                            StateHasChanged();
                        }
                    }
                }
                else
                {
                    _versandÜbersicht = new List<VersandKombi>();
                    await foreach (var item in versandService.GetVersendetePaketeAsync(Filter))
                    {
                        if (!(item is null))
                        {
                            _versandÜbersicht.Add(item);
                            StateHasChanged();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"MBE Fehler_1: {ex.Message}");
            }


        }
        private async Task ManuellerBelegVersand()
        {
            _sperreManuellenSendenButton = true;

            using FbController2 fbController = new FbController2();
            Beleg? beleg = await Beleg.GetBelegAsync(ManuellBelegVersandInput.BelegTyp, ManuellBelegVersandInput.Belegnummer, fbController);

            if (beleg is null)
            {
                await jsRuntime.ShowToast(ToastType.error, $"{ManuellBelegVersandInput.BelegTyp} {ManuellBelegVersandInput.Belegnummer} konnte nicht gefunden werden.", 3000);
            }
            else
            {
                if (Mitarbeiter.PersonalNummer < 1)
                {
                    await jsRuntime.ShowToast(ToastType.error, $"Sie verfügen über keine gültige Personalnummer. Bitte wenden Sie sich an die Programmierung.", 6000);
                }
                else
                {
                    VersandOption option = new VersandOption(ManuellBelegVersandInput.Courier, CourierArt.MANUELL);

                    List<string> trackingnummern = ManuellBelegVersandInput.Pakete.Select(x => x.Trackingnummer).ToList();

                    trackingnummern.RemoveAll(x => x.Equals("OHNE"));

                    VersandMailer versandMailer = await VersandMailer.CreateAsync(beleg, trackingnummern, option, Mitarbeiter.PersonalNummer, fbController);

                    var result = await versandMailer.EmailSendenAsync();

                    if (result.Where(x => !x.Success).Any())
                    {
                        await jsRuntime.ShowToast(ToastType.error, $"Fehler beim senden der Email. Fehler wurde an die info@karley.eu gesendet!", 5000);
                    }

                    foreach (var response in result.Where(x => x.Success && x.Status is not EmailVersandState.OK or EmailVersandState.NEUTRAL))
                    {
                        await jsRuntime.ShowToast(ToastType.success, response.Message ?? String.Empty);
                        if (response.Status is EmailVersandState.REDRUCK)
                        {
                            string filenamePdfAnhang = String.Empty;
                            PrintBase? basePrinter = await EnumHelper.PrintBeleg(beleg, fbController);

                            if (basePrinter is not null)
                            {
                                filenamePdfAnhang = basePrinter.Print(GlobalConfig.Configuration.OutputPfad);
                            }



                            if (!String.IsNullOrWhiteSpace(filenamePdfAnhang) && File.Exists(filenamePdfAnhang))
                            {
                                List<EmailAnhang> anhänge = new List<EmailAnhang>{
                                    new EmailAnhang
                                    {
                                        Name = Path.GetFileName(filenamePdfAnhang),
                                        Pfad = filenamePdfAnhang
                                    }
                                };
                                await EmailController.FehlerMailSendenAsync("Rechnung per HybridMail versenden", @$"<h1>Rechnung per HybridMail versenden</h1>
<p>Der Beleg <a href=""{EnumHelper.GetBelegUrl(beleg.Belegtyp, beleg.Belegnummer)}"" target=""_blank"">{beleg.Belegtyp}-{beleg.Belegnummer}</a> wurde manuell versendet.</p>
<p>Der <a href=""/Kunden/{beleg.Kundennummer}"">Kunde ({beleg.Kundennummer})</a> hat als Merkmal Rechnungsdruck hinterlegt. Versende also bitte den Beleg aus dem Anhang per Hybridmail an den Kunden.</p>", "info@karley.eu", anhänge);
                            }
                            else
                            {
                                await EmailController.FehlerMailSendenAsync("Rechnung per HybridMail versenden", @$"<h1>Rechnung per HybridMail versenden</h1>
<p>Der Beleg <a href=""{EnumHelper.GetBelegUrl(beleg.Belegtyp, beleg.Belegnummer)}"" target=""_blank"">{beleg.Belegtyp}-{beleg.Belegnummer}</a> wurde manuell versendet.</p>
<p>Der <a href=""/Kunden/{beleg.Kundennummer}"">Kunde ({beleg.Kundennummer})</a> hat als Merkmal Rechnungsdruck hinterlegt. Versende also bitte den Beleg per HybridMail an den Kunden.</p>", "info@karley.eu");
                            }


                        }
                    }



                    RecipientType emp = await beleg.ToRecipientTypeAsync(fbController);
                    foreach (var paket in ManuellBelegVersandInput.Pakete)
                    {
                        await versandService.PaketInW4EintragenAsync(beleg, paket.Trackingnummer, emp, paket.Gewicht);
                    }

                    //Scholz - 23.09.2020: Speichert in der Datenbank welche Belege Manuell versendet wurden, ist für uns übersichtlicher
                    await ManuellVersand.CreateAsync(beleg.Belegtyp, beleg.Belegnummer, true, false, Mitarbeiter.PersonalNummer);

                    await jsRuntime.ShowToast(ToastType.success, $"Sendung wurde erfolgreich eingetragen.", 3000);

                    ManuellBelegVersandInput = new ManuellBelegVersandInput();
                }
            }

            _sperreManuellenSendenButton = false;
        }
        private async Task BelegVersand()
        {
            _sperreBelegSendenButton = true;
            using FbController2 fbController = new FbController2();
            Beleg? beleg = await Beleg.GetBelegAsync(VersandBelegInput.BelegTyp, VersandBelegInput.Belegnummer, fbController);

            if (beleg is null)
            {
                await jsRuntime.ShowToast(ToastType.error, $"{VersandBelegInput.BelegTyp} {VersandBelegInput.Belegnummer} konnte nicht gefunden werden.", 3000);
            }
            else
            {
                if (Mitarbeiter.PersonalNummer < 1)
                {
                    await jsRuntime.ShowToast(ToastType.error, $"Sie verfügen über keine gültige Personalnummer. Bitte wenden Sie sich an die Programmierung.", 6000);
                }
                else
                {
                    VersandOption option = new VersandOption(Courier.UPS, VersandBelegInput.CourierArt);
                    RecipientType lieferanschrift = await beleg.ToRecipientTypeAsync(fbController);
                    List<ItemType> pakete = new List<ItemType>();
                    foreach (var paket in VersandBelegInput.Pakete)
                    {
                        pakete.Add(new ItemType
                        {
                            Weight = paket.Gewicht,
                            Dimensions = new DimensionsType { Height = 0, Lenght = 0, Width = 0 }
                        });
                    }

                    var (erfolgreich, successResponses, alerts) = await versandService.PaketeEintragen(beleg, lieferanschrift, pakete, option, Mitarbeiter.PersonalNummer);

                    if (VersandBelegInput.MailSenden)
                    {
                        VersandMailer versandMailer = await VersandMailer.CreateAsync(beleg, successResponses.Select(x => x.CourierMasterTrk).ToList(), option, Mitarbeiter.PersonalNummer, fbController);

                        var result = await versandMailer.EmailSendenAsync();

                        foreach (var response in result.Where(x => x.Success && x.Status is not EmailVersandState.OK or EmailVersandState.NEUTRAL))
                        {
                            await jsRuntime.ShowToast(ToastType.success, response.Message ?? String.Empty);
                        }
                    }

                    //Scholz - 23.09.2020: Speichert in der Datenbank welche Belege Manuell versendet wurden, ist für uns übersichtlicher
                    await ManuellVersand.CreateAsync(beleg.Belegtyp, beleg.Belegnummer, VersandBelegInput.MailSenden, true, Mitarbeiter.PersonalNummer);

                    if (erfolgreich)
                    {
                        await jsRuntime.ShowToast(ToastType.success, $"Sendung wurde erfolgreich eingetragen.", 3000);
                    }
                    else
                    {
                        await jsRuntime.ShowToast(ToastType.error, $"Fehler beim eintragen der Pakete. Es wurde ein Fehlerbericht an den Vertrieb gesendet.", 5000);
                    }

                    VersandBelegInput = new VersandBelegInput();
                }
            }
            _sperreBelegSendenButton = false;
        }
        

        private async Task VersandOhneBeleg()
        {
            _sperreVersandOhneBelegButton = true;

            dynamic? zuordnung = null;
            switch (VersandOhneBelegInput.Zuordnung)
            {
                case VersandZuordnungsTyp.Kunde:
                    zuordnung = await Kunde.GetKundeAsync(VersandOhneBelegInput.Zuordnungsnummer.ToString());
                    break;
                case VersandZuordnungsTyp.Lieferant:
                    zuordnung = await Lieferant.GetLieferantAsync(VersandOhneBelegInput.Zuordnungsnummer);
                    break;
                default:
                    break;
            }
            if (zuordnung is null)
            {
                await jsRuntime.ShowToast(ToastType.error, $"{VersandOhneBelegInput.Zuordnung} {VersandOhneBelegInput.Zuordnungsnummer} konnte nicht gefunden werden.", 3000);
            }
            else
            {
                if (Mitarbeiter.PersonalNummer < 1)
                {
                    await jsRuntime.ShowToast(ToastType.error, $"Sie verfügen über keine gültige Personalnummer. Bitte wenden Sie sich an die Programmierung.", 6000);
                }
                else
                {

                    var (erfolgreich, _, alerts) = await versandService.PaketOhneBeleg(
                        account: VersandOhneBelegInput.Account,
                        zuordnungsTyp: VersandOhneBelegInput.Zuordnung,
                        zuordnungsnummer: VersandOhneBelegInput.Zuordnungsnummer,
                        lieferanschrift: VersandOhneBelegInput.ToRecipientType(),
                        shipment: VersandOhneBelegInput.ToShipmentType(),
                        pakete: VersandOhneBelegInput.PaketeToItemType(),
                        personalNummer: Mitarbeiter.PersonalNummer
                    );

                    if (erfolgreich)
                    {
                        await jsRuntime.ShowToast(ToastType.success, $"Sendung wurde erfolgreich eingetragen.", 3000);
                    }
                    else
                    {
                        await jsRuntime.ShowToast(ToastType.error, $"Fehler beim eintragen der Pakete. Es wurde ein Fehlerbericht an den Vertrieb gesendet.", 5000);
                    }

                    VersandOhneBelegInput = new VersandOhneBelegInput();
                }
            }



            _sperreVersandOhneBelegButton = false;
        }

        private async Task OnZuordnungsnummerFocusOut(FocusEventArgs e)
        {
            if (VersandOhneBelegInput.Zuordnungsnummer > 0)
            {
                switch (VersandOhneBelegInput.Zuordnung)
                {
                    case VersandZuordnungsTyp.Kunde:
                        Kunde? k = await Kunde.GetKundeAsync(VersandOhneBelegInput.Zuordnungsnummer.ToString());

                        if (k is not null)
                        {
                            VersandOhneBelegInput.Firmenname = k.KUND_A_NAME1;
                            VersandOhneBelegInput.Adresse1 = k.KUND_A_STRASSE ?? String.Empty;
                            VersandOhneBelegInput.Postleitzahl = k.KUND_A_PLZ ?? String.Empty;
                            VersandOhneBelegInput.Ort = k.KUND_A_ORT ?? String.Empty;
                            VersandOhneBelegInput.Telefonnummer = k.KUND_A_TEL1 ?? String.Empty;
                            VersandOhneBelegInput.Email = k.KUND_A_EMAIL ?? String.Empty;
                            VersandOhneBelegInput.Land = k.KUND_A_LAND;
                        }
                        break;
                    case VersandZuordnungsTyp.Lieferant:
                        Lieferant? lieferant = await Lieferant.GetLieferantAsync(VersandOhneBelegInput.Zuordnungsnummer);


                        if (!(lieferant is null))
                        {
                            VersandOhneBelegInput.Firmenname = lieferant.LIEF_A_NAME1;
                            VersandOhneBelegInput.Adresse1 = lieferant.LIEF_A_STR ?? String.Empty;
                            VersandOhneBelegInput.Postleitzahl = lieferant.LIEF_A_PLZ ?? String.Empty;
                            VersandOhneBelegInput.Ort = lieferant.LIEF_A_ORT ?? String.Empty;
                            VersandOhneBelegInput.Telefonnummer = lieferant.LIEF_A_TEL1 ?? String.Empty;
                            VersandOhneBelegInput.Email = lieferant.LIEF_A_EMAIL ?? String.Empty;
                            VersandOhneBelegInput.Land = lieferant.LIEF_A_LAND;
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        protected override async Task OnInitializedAsync()
        {
            await LadeÜbersicht();
            await LadeÜbersicht(true);
            await base.OnInitializedAsync();
        }


        private string GetNavListClass(bool active) => active ? "nav-link active edit-page-nav-link" : "nav-link edit-page-nav-link";
        private string GetTabClass(bool active) => active ? "tab-pane fade active show" : "tab-pane fade";

    }
}
