using ChartJs.Blazor.Common;
using ChartJs.Blazor.Common.Enums;
using ChartJs.Blazor.LineChart;
using ChartJs.Blazor.Util;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using WK5.Core;
using WK5.Core.Models;
using WK5.Core.Services;
using WK5_Blazor.Components.Charts;

namespace WK5_Blazor.Components
{
    public partial class ArtikelVerbrauchsdaten
    {
        private const int JahreRückwärtsDefault = 4;

        [Parameter] public List<int> Jahre { get; set; } = new List<int>();
        [Parameter] public Dictionary<int, bool> EditableYears { get; set; } = new Dictionary<int, bool>();
        [Parameter] public bool LastOneEditable { get; set; } = false;

        [Parameter]
        public ArtikelVerbrauchsdatenModus Modus { get; set; } = ArtikelVerbrauchsdatenModus.Menge;

#nullable disable
        [Parameter]
        public Artikel Artikel
        {
            get; set;
        }
#nullable enable

        [Parameter] public bool ShowChart { get; set; } = true;
        [Parameter] public bool ShowTable { get; set; } = true;
        [Parameter] public bool OnlyTotals { get; set; } = false;
        [Parameter] public bool ShowAppendix { get; set; } = true;
        [Parameter] public bool Show { get; set; } = true;

        public bool LoadingDone { get; set; } = false;

        private Dictionary<int, List<Verbrauchsdaten>> Verbrauchsdaten = new Dictionary<int, List<Verbrauchsdaten>>();

        private string Appendix
        {
            get
            {
                if (!ShowAppendix)
                {
                    return "";
                }

                return Modus switch
                {
                    ArtikelVerbrauchsdatenModus.Menge => " Stck.",
                    ArtikelVerbrauchsdatenModus.Ertrag => "€",
                    ArtikelVerbrauchsdatenModus.Umsatz => "€",
                    _ => ""
                };
            }
        }


        public string ValueFormat
        {
            get
            {
                return Modus switch
                {
                    ArtikelVerbrauchsdatenModus.Menge => "{0}" + (ShowAppendix ? $" {Appendix}" : String.Empty),
                    ArtikelVerbrauchsdatenModus.Umsatz => (ShowAppendix ? "{0:C2}" : String.Empty),
                    ArtikelVerbrauchsdatenModus.Ertrag => (ShowAppendix ? "{0:C2}" : String.Empty),
                    _ => "{0}"
                };
            }
        }

        public string LabelText
        {
            get
            {
                return Modus switch
                {
                    ArtikelVerbrauchsdatenModus.Menge => "Menge in {0}",
                    ArtikelVerbrauchsdatenModus.Umsatz => "Umsatz in {0}",
                    ArtikelVerbrauchsdatenModus.Ertrag => "Ertrag in {0}",
                    _ => "{0}"
                };
            }
        }

        private bool IsEditable(int jahr)
        {
            if (jahr == Jahre.Last() && LastOneEditable)
            {
                return true;
            }

            if (EditableYears.TryGetValue(jahr, out bool isEditable))
            {
                return isEditable;
            }
            else
            {
                return false;
            }
        }

        protected override async Task OnParametersSetAsync()
        {
            if (Artikel is not null && Show)
            {
                if (Jahre.Count <= 0)
                {
                    for (int i = 0; i < JahreRückwärtsDefault; i++)
                    {
                        Jahre.Add(DateTime.Now.Year - i);
                    }
                }

                await PopulateVerbrauchsdaten();
                LoadingDone = true;

                await InvokeAsync(StateHasChanged);
            }

            if (LoadingDone)
            {
                if (Artikel is not null && ShowChart)
                {
                }
            }
        }

        private decimal? GetValue(int jahr, int monat)
        {
            if (Verbrauchsdaten.TryGetValue(jahr, out List<Verbrauchsdaten> daten))
            {
                var datensatz = daten.Where(x => x.Monat == monat).First();
                return Modus switch
                {
                    ArtikelVerbrauchsdatenModus.Ertrag => datensatz.Gewinn,
                    ArtikelVerbrauchsdatenModus.Umsatz => datensatz.Umsatz,
                    ArtikelVerbrauchsdatenModus.Menge => datensatz.Menge,
                    _ => datensatz.Menge
                };
            }
            else
            {
                return null;
            }
        }

        private decimal? GetTotal(int jahr)
        {
            if (Verbrauchsdaten.TryGetValue(jahr, out List<Verbrauchsdaten> daten))
            {
                return Modus switch
                {
                    ArtikelVerbrauchsdatenModus.Ertrag => daten.Sum(x => x.Gewinn),
                    ArtikelVerbrauchsdatenModus.Umsatz => daten.Sum(x => x.Umsatz),
                    ArtikelVerbrauchsdatenModus.Menge => daten.Sum(x => x.Menge),
                    _ => daten.Sum(x => x.Menge)
                };
            }
            else
            {
                return null;
            }
        }

        private IEnumerable<VerbrauchsDatenDataItem> ToDataItem(int jahr)
        {
            for (int i = 1; i <= 12; i++)
            {
                yield return new VerbrauchsDatenDataItem
                {
                    Monat = i,
                    Wert = GetValue(jahr, i) ?? 0.0m
                };
            }
        }

        private async Task PopulateVerbrauchsdaten()
        {
            foreach (int jahr in Jahre)
            {
                if (!Verbrauchsdaten.ContainsKey(jahr))
                {
                    Verbrauchsdaten.TryAdd(jahr, await artikelService.GetArtikelVerbrauchsdaten(Artikel.Artikelnummer, jahr).ToListAsync());
                }
            }
            await InvokeAsync(StateHasChanged);
        }

        private async Task JahrEdited(int index, ChangeEventArgs ev)
        {
            if (index < Jahre.Count)
            {
                if (ev.Value is not null)
                {                    
                    if (Int32.TryParse(ev.Value.ToString(), out int jahr))
                    {
                        Jahre[index] = jahr;
                        await PopulateVerbrauchsdaten();
                        return;
                    }
                }
            }            
        }

        //private async Task EditJahrChanged()
        //{
        //    if (!Jahre.Contains(LastJahr))
        //    {
        //        Jahre[Jahre.Count - 1] = LastJahr;
        //        Initialized = false;
        //        await OnParametersSetAsync();
        //    }
        //}
    }

    public class VerbrauchsDatenDataItem
    {
        public int Monat { get; set; }
        public decimal Wert { get; set; }
    }
}
