using Billing.Languages;
using Billing.Models;
using Billing.Themes;
using Billing.UI;
using Microcharts;
using SkiaSharp;
using SkiaSharp.Views.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;

namespace Billing.Views
{
    public partial class RankPage : BillingPage
    {
        private static readonly BindableProperty ChartProperty = Helper.Create<Chart, RankPage>(nameof(Chart));
        private static readonly BindableProperty TopBillsProperty = Helper.Create<IList<UIBill>, RankPage>(nameof(TopBills));

        public Chart Chart
        {
            get => (Chart)GetValue(ChartProperty);
            set => SetValue(ChartProperty, value);
        }
        public IList<UIBill> TopBills
        {
            get => (IList<UIBill>)GetValue(TopBillsProperty);
            set => SetValue(TopBillsProperty, value);
        }

        public Command LeftCommand { get; }
        public Command RightCommand { get; }
        public Command FilterCommand { get; }

        private DateTime current;
        private IEnumerable<Bill> bills;
        private CategoryType type = CategoryType.Spending;

        public RankPage()
        {
            LeftCommand = new Command(OnLeftCommand);
            RightCommand = new Command(OnRightCommand);
            InitializeComponent();
        }

        public override void OnLoaded()
        {
            SetMonth(DateTime.Today);
        }

        private void OnLeftCommand()
        {
            SetMonth(current.AddMonths(-1));
        }

        private void OnRightCommand()
        {
            SetMonth(current.AddMonths(1));
        }

        private void SetMonth(DateTime date)
        {
            current = date.AddDays(1 - date.Day);
            var end = current.AddDays(DateTime.DaysInMonth(current.Year, current.Month));

            var format = Resource.DateRangeFormat;
            Title = current.ToString(format) + " ~ " + end.AddDays(-1).ToString(format);

            bills = App.Bills.Where(b => b.CreateTime >= current && b.CreateTime <= end);

            var entries = new List<ChartEntry>();
            var primaryColor = BaseTheme.CurrentPrimaryColor.ToSKColor();
            var textColor = BaseTheme.CurrentSecondaryTextColor.ToSKColor();
            for (var day = current; day <= end; day = day.AddDays(1))
            {
                var daybills = bills.Where(b => Helper.IsSameDay(b.CreateTime, day));
                decimal amount;
                if (type == CategoryType.Income)
                {
                    amount = daybills.Where(b => b.Amount > 0).Sum(b => b.Amount);
                }
                else
                {
                    amount = daybills.Where(b => b.Amount < 0).Sum(b => -b.Amount);
                }
                if (amount > 0)
                {
                    entries.Add(new((float)amount)
                    {
                        Label = day.ToString("MM/dd"),
                        ValueLabel = amount.ToString("#,##0.##"),
                        Color = primaryColor,
                        TextColor = textColor,
                        ValueLabelColor = textColor
                    });
                }
            }

            Chart = new LineChart
            {
                BackgroundColor = SKColors.Transparent,
                LabelTextSize = 20,
                Entries = entries
            };
        }
    }
}