using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Mvc;
using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WK5.Core;
using WK5.Core.Basis;
using WK5.Core.Email;
using WK5.Core.Models;
using WK5.Core.Models.Tools.Lagerregal;
using WK5.Core.PageModels.Lagerregal;
using WK5.Core.PageModels.Tools.Regalfinder;

namespace WK5_Blazor.Pages.Lagerregal
{
    public partial class ArtikelAnsicht
    {
        private decimal _buchungsMenge = 1;

#nullable disable
        [CascadingParameter] public AppMitarbeiter Mitarbeiter { get; set; }
#nullable enable
        [Parameter] public int Belegnummer { get; set; }
        [Parameter] public int PosId { get; set; }
        [Parameter] public string? StklPosId { get; set; }
        public PackAuftrag? Auftrag { get; set; }
        public PackBelegposition? Position { get; set; }

        private RegalFinderInput _regalFinderInput = new RegalFinderInput();

        public string Image { get; set; } = String.Empty;

        #region Modals

        private bool showKundendetailsModal;
        private bool showArtikelOptionenModal;
        private bool showFalscherLagerbestandInfoModal;        

        private FalscherLagerbestandInfoModel falscherLagerbestandInfoModel = new FalscherLagerbestandInfoModel();
        #endregion

        private bool sperreButtonFalscherLagerbestand = false;
        public List<decimal> ScanbareMengen { get; set; } = new List<decimal>();



        public string LagerbestandText => Position?.Bestand > 0 ? $"{Position.Bestand} an Lager" : "Nicht an Lager";

        private string _artikelnummer = String.Empty;
        [BindProperty]
        public string Artikelnummer
        {
            get => _artikelnummer.ToUpper();
            set
            {
                _artikelnummer = value.ToUpper();
            }
        }
        [BindProperty]
        public string? Seriennummer { get; set; }

        public List<string> Seriennummern { get; set; } = new List<string>();

        private ElementReference seriennummerSelect;
        private ElementReference _artikelnummerEingabeFeld;
        public decimal BuchungsMenge
        {
            get => _buchungsMenge; set
            {
                if (value < 0.1m)
                {
                    throw new ArgumentOutOfRangeException($"Die {nameof(BuchungsMenge)} muss >= 0,1 sein.");
                }

                _buchungsMenge = value;
            }
        }

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (!firstRender)
            {
                if (_artikelnummerEingabeFeld.Context is not null)
                {
                    await _artikelnummerEingabeFeld.FocusAsync();
                }
            }
        }
        protected override async Task OnParametersSetAsync()
        {
            // FbController wird neu erstellt, um Probleme zu umgehen, da die Methode zweimal aufgerufen wird
            using FbController2 fbController = new FbController2();
            Auftrag = await PackAuftrag.GetPackAuftragAsync(Belegnummer, fbController);
            Position = Auftrag?.GetPosition(PosId);

            if (Position is null)
            {
                navigationManager.NavigateTo("/404");
                return;
            }

            if (StklPosId != null)
            {
                string[] stklPositionenStrArr = StklPosId.Split('_');

                List<int> stklPosIds = new List<int>();

                foreach (string stklPosStr in stklPositionenStrArr)
                {
                    int.TryParse(stklPosStr, out int stklPosId);
                    if (stklPosId != 0)
                    {
                        stklPosIds.Add(stklPosId);
                    }
                }


                int stklPositionsId = stklPosIds.Last();
                Position = Auftrag?.GetPosition(Position, stklPositionsId);
                if (Position == null)
                {
                    navigationManager.NavigateTo("/404");
                    return;
                }
            }

            if (Position is null)
            {
                navigationManager.NavigateTo("/404");
                return;
            }

            if (Program.AppDaten.LiveShopDisabled)
            {
                Image = String.Empty;
            }
            else
            {
                
                ArtikelBild? bild = await ArtikelBild.GetHauptBildAsync(Position.Artikelnummer);
                
                if(bild is null)
                {
                    Image = String.Empty;
                }
                else
                {
                    Image = bild.WebImage;
                }
                
            }

            
            _regalFinderInput.Artikelnummer = Position.Artikelnummer;
            _regalFinderInput.Modus = RegalFinderModus.LagerplatzÄndern;

            Seriennummern = await Position.GetFreieSeriennummernAsync(fbController).ToListAsync();
            #region Mengen Buttons festlegen
            if (Position.MengeHatKommaStelle)
            {
                ScanbareMengen.Add(Position.Menge % 1);
            }
            ScanbareMengen.Add(1);

            if (Position.Menge >= 10)
            {
                ScanbareMengen.Add(10);
            }

            if (Position.Menge >= 100)
            {
                ScanbareMengen.Add(100);
            }

            if (Position.Vpe > 1)
            {
                ScanbareMengen.Add(Position.Vpe);
                BuchungsMenge = Position.Vpe;
            }

            if (!Position.ARTI_L_LAGERFUEHR && Position.Menge > 0)
            {
                ScanbareMengen.Add(Position.Menge);
                BuchungsMenge = Position.Menge;
            }

            if(Position.Menge >= 1000 && !ScanbareMengen.Contains(Position.Menge))
            {
                ScanbareMengen.Add(Position.Menge);
                BuchungsMenge = Position.Menge;
            }

            #endregion

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

        }
        private async Task BuchenAsync(bool direktBuchen = false)
        {
            using FbController2 fbController = new FbController2();
            if (Position is null)
            {
                return;
            }

            var result = await buchenService.BuchenAsync(
                position: Position,
                buchungsMenge: BuchungsMenge,
                eingabeArtikelnummer: direktBuchen ? Position.Artikelnummer : Artikelnummer,
                ausgewählteSeriennummer: Seriennummer,
                fbController: fbController
            );

            if (result.Success)
            {
                Seriennummer = String.Empty;
                // Gebuchte Seriennummer müssen entfernt werden, damit diese nicht nochmal ausgewählt werden können.
                if (result.Seriennummer != null)
                {
                    Seriennummern.Remove(result.Seriennummer);
                    await jsRuntime.InvokeVoidAsync("blazorHelpers.selectDefaultIndex", seriennummerSelect);
                }

                if (result.Gebucht == Position.Menge)
                {
                    if (Position.Parent is not null and PackBelegposition parent)
                    {
                        navigationManager.NavigateTo($"/Lagerregal/Auftrag/{Belegnummer}/Stueckliste/{parent.PosId}/{parent.UrlParameter}");
                    }
                    else
                    {
                        navigationManager.NavigateTo($"/Lagerregal/Auftrag/{Belegnummer}#{Position.PosId + Position.UrlParameter}");
                    }
                }
            }
            else
            {
                await jsRuntime.InvokeVoidAsync("showToast", "error", result.Message ?? String.Empty, 1500);
            }
        }
        private async Task EingabeKeyUp(KeyboardEventArgs e)
        {
            if (e.Code == "Enter" || e.Key == "Enter")
            {
                await BuchenAsync();
                Artikelnummer = "";
            }
        }



        private async Task FalscherLagerbestandVertriebInformierenAsync()
        {

            if (Position is null)
            {
                return;
            }

            sperreButtonFalscherLagerbestand = true;

            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"Der Artikel hat laut W4 einen Lagerbestand von {Position.Bestand} Stk<br /><br />");
            sb.AppendLine($"Laut Mitarbeiter {Mitarbeiter.Username} soll der tatsächliche Lagerbestand aber {falscherLagerbestandInfoModel.Lagerbestand} Stk sein.");
            EmailController emailController = new EmailController() { Html = true };
            var response = await emailController.SendenAsync(
                empfängerEmail: "info@karley.eu",
                betreff: $"Falscher Lagerbestand für Artikel {Position.Artikelnummer}",
                body: sb.ToString()
            );

            falscherLagerbestandInfoModel = new FalscherLagerbestandInfoModel();
            sperreButtonFalscherLagerbestand = false;
            showFalscherLagerbestandInfoModal = false;
        }

        public override async Task CheckActivePageAsync()
        {
            var (success, page) = ActivePages.AddActivePage(new ActivePage(PageType.Lagerregal, Belegnummer.ToString(), Mitarbeiter.PersonalNummer));

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

                SperreDurchAnderenUser = true;
                navigationManager.NavigateTo("/Lagerregal");
            }
        }
    }
}
