using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using WK5.Core;
using WK5.Core.Models;

namespace WK5_Blazor.Pages.Tools
{
    public partial class ArtikelBedarf
    {
        [Parameter]
        public string Artikelnummer { get; set; } = String.Empty;

        public Dictionary<Beleg, decimal> Belege { get; set; } = new Dictionary<Beleg, decimal>();

        protected override async Task OnParametersSetAsync()
        {
            Belege = await GetArtikelBedarfProBelegAsync(Artikelnummer, "AU");
        }

        private async Task<Dictionary<Beleg, decimal>> GetArtikelBedarfProBelegAsync(string ARTI_A_NR, string BELE_A_TYP)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@ARTINR", ARTI_A_NR);
            fbController.AddParameter("@TYP", BELE_A_TYP);
            var bposData = await fbController.SelectDataAsync("SELECT BPOS_N_MENGE, BPOS_N_NR, BPOS_A_TYP, BPOS_N_MENGEGELIEF FROM BELEGPOS LEFT JOIN BELEGE ON BPOS_N_NR = BELE_N_NR AND BPOS_A_TYP = BELE_A_TYP WHERE BPOS_A_ARTIKELNR = @ARTINR AND BPOS_A_TYP = @TYP AND BELE_L_ERLEDIGT = 'N'");


            Dictionary<Beleg, decimal> returnValue = new Dictionary<Beleg, decimal>();
            // Belege holen wo der Artikel in der Belegposition ist
            foreach (DataRow row in bposData.Rows)
            {
                string? typ = row["BPOS_A_TYP"].ToString();
                int BPOS_N_NR = row.Field<int>("BPOS_N_NR");
                decimal BPOS_N_MENGE = row.Field<decimal>("BPOS_N_MENGE");
                decimal BPOS_N_MENGEGELIEF = row.Field<decimal>("BPOS_N_MENGEGELIEF");

                if (typ is null)
                {
                    throw new NullReferenceException(nameof(typ));
                }

                Beleg? beleg = await Beleg.GetBelegAsync(EnumHelper.GetBelegTyp(typ), BPOS_N_NR, fbController);

                if (beleg is null)
                {
                    continue;
                }

                if (returnValue.ContainsKey(beleg))
                {
                    returnValue[beleg] += BPOS_N_MENGE - BPOS_N_MENGEGELIEF;
                }
                else
                {
                    returnValue[beleg] = BPOS_N_MENGE - BPOS_N_MENGEGELIEF;
                }
            }


            Dictionary<string, int> stücklisten = await GetStücklistenMitArtikelAsync(ARTI_A_NR);

            foreach (KeyValuePair<string, int> stückliste in stücklisten)
            {
                fbController.AddParameter("@ARTINR", stückliste.Key);
                fbController.AddParameter("@TYP", BELE_A_TYP);
                var belege = await fbController.SelectDataAsync("SELECT BPOS_N_MENGE, BPOS_N_NR, BPOS_A_TYP, BPOS_N_MENGEGELIEF FROM BELEGPOS LEFT JOIN BELEGE ON BPOS_N_NR = BELE_N_NR AND BPOS_A_TYP = BELE_A_TYP WHERE BPOS_A_ARTIKELNR = @ARTINR AND BPOS_A_TYP = @TYP AND BELE_L_ERLEDIGT = 'N'");

                List<Beleg> tmpBelege = new List<Beleg>();

                foreach (DataRow row in belege.Rows)
                {
                    string? typ = row["BPOS_A_TYP"].ToString();
                    _ = int.TryParse(row["BPOS_N_NR"].ToString(), out int BPOS_N_NR);
                    _ = int.TryParse(row["BPOS_N_MENGE"].ToString(), out int BPOS_N_MENGE);
                    _ = int.TryParse(row["BPOS_N_MENGEGELIEF"].ToString(), out int BPOS_N_MENGEGELIEF);

                    Beleg? beleg = await Beleg.GetBelegAsync(EnumHelper.GetBelegTyp(typ), BPOS_N_NR, fbController);

                    if (returnValue.ContainsKey(beleg))
                    {
                        returnValue[beleg] += (BPOS_N_MENGE * stückliste.Value) - (BPOS_N_MENGEGELIEF * stückliste.Value);
                    }
                    else
                    {
                        returnValue[beleg] = (BPOS_N_MENGE * stückliste.Value) - (BPOS_N_MENGEGELIEF * stückliste.Value);
                    }
                }
            }

            return returnValue;
        }

        private async Task<Dictionary<string, int>> GetStücklistenMitArtikelAsync(string ARTI_A_NR)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@ARTINR", ARTI_A_NR);
            var stkl = await fbController.SelectDataAsync("SELECT ARST_A_HAUPTARTI, ARST_N_MENGE FROM ARTIKELSTUECKLISTE WHERE ARST_A_UNTERARTI = @ARTINR");

            Dictionary<string, int> stücklistenArtikel = new Dictionary<string, int>();
            //Alle Stücklisten die den Artikel enthalten
            foreach (DataRow row in stkl.Rows)
            {
                string? ARST_A_HAUPTARTI = row.Field<string>("ARST_A_HAUPTARTI");
                Int32.TryParse(row["ARST_N_MENGE"].ToString(), out int ARST_N_MENGE);

                if (ARST_A_HAUPTARTI is null)
                {
                    continue;
                }

                if (stücklistenArtikel.ContainsKey(ARST_A_HAUPTARTI))
                {
                    stücklistenArtikel[ARST_A_HAUPTARTI] += ARST_N_MENGE;
                }
                else
                {
                    stücklistenArtikel[ARST_A_HAUPTARTI] = ARST_N_MENGE;
                }
            }

            Dictionary<string, int> workDict = stücklistenArtikel.ToDictionary(entry => entry.Key, entry => entry.Value);

            foreach (KeyValuePair<string, int> stückliste in workDict)
            {
                Dictionary<string, int> parentStückliste = await GetStücklistenMitArtikelAsync(stückliste.Key);

                foreach (KeyValuePair<string, int> parent in parentStückliste)
                {
                    if (stücklistenArtikel.ContainsKey(parent.Key))
                    {
                        stücklistenArtikel[parent.Key] += parent.Value * stückliste.Value;
                    }
                    else
                    {
                        stücklistenArtikel[parent.Key] = parent.Value * stückliste.Value;
                    }
                }
            }

            return stücklistenArtikel;
        }


    }
}
