using Elwig.Documents;
using Elwig.Helpers;
using Elwig.Models.Dtos;
using Elwig.Models.Entities;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace Elwig.Windows {
    public partial class PaymentVariantsWindow : ContextWindow {

        public readonly int Year;

        public PaymentVariantsWindow(int year) {
            InitializeComponent();
            Year = year;
            Title = $"Auszahlungsvarianten - Lese {Year} - Elwig";
        }

        protected override async Task OnRenewContext() {
            ControlUtils.RenewItemsSource(PaymentVariantList, await Context.PaymentVariants.Where(v => v.Year == Year).OrderBy(v => v.AvNr).ToListAsync(), v => (v as PaymentVar)?.AvNr);
            Update();
        }

        private void Update() {
            if (PaymentVariantList.SelectedItem is PaymentVar v) {
                var locked = v.TransferDate != null || !v.TestVariant;
                DeleteButton.IsEnabled = !locked;
                CalculateButton.IsEnabled = !locked;
                CopyButton.IsEnabled = true;
                EditButton.IsEnabled = true;
                ShowButton.IsEnabled = true;
                PrintButton.IsEnabled = true;

                NameInput.Text = v.Name;
                CommentInput.Text = v.Comment;
            } else {
                EditButton.IsEnabled = false;
                CopyButton.IsEnabled = false;
                CalculateButton.IsEnabled = false;
                DeleteButton.IsEnabled = false;
                ShowButton.IsEnabled = false;
                PrintButton.IsEnabled = false;

                NameInput.Text = "";
                CommentInput.Text = "";
            }
        }

        private void PaymentVariantList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
            Update();
        }

        private void AddButton_Click(object sender, RoutedEventArgs evt) {

        }

        private void CopyButton_Click(object sender, RoutedEventArgs evt) {

        }

        private void DeleteButton_Click(object sender, RoutedEventArgs evt) {

        }

        private void CalculateButton_Click(object sender, RoutedEventArgs evt) {

        }

        private void EditButton_Click(object sender, RoutedEventArgs evt) {
            if (PaymentVariantList.SelectedItem is not PaymentVar v)
                return;
            App.FocusChartWindow(v.Year, v.AvNr);
        }

        private async void ShowButton_Click(object sender, RoutedEventArgs evt) {
            await Generate(1);
        }

        private async void PrintButton_Click(object sender, RoutedEventArgs evt) {
            await Generate(2);
        }

        private async Task Generate(int mode) {
            if (PaymentVariantList.SelectedItem is not PaymentVar v)
                return;

            Mouse.OverrideCursor = Cursors.AppStarting;

            var members = Context.Members.FromSqlRaw($"""
                SELECT m.*
                FROM member m
                    INNER JOIN delivery d ON d.mgnr = m.mgnr
                WHERE d.year = {Year}
                GROUP BY m.mgnr
                """);
            members = members.OrderBy(m => m.MgNr);

            IEnumerable<Member> list = await members.ToListAsync();
            var data = await CreditNoteData.ForPaymentVariant(Context.CreditNoteRows, v.Year, v.AvNr);
            var payments = await Context.MemberPayments.Where(p => p.Year == v.Year && p.AvNr == v.AvNr).ToDictionaryAsync(c => c.MgNr);
            using var doc = Document.Merge(list.Select(m =>
                new CreditNote(Context, payments[m.MgNr], data[m.MgNr])
            ));
            await doc.Generate(new Progress<double>(v => {
                ProgressBar.Value = v;
            }));
            Mouse.OverrideCursor = null;

            if (mode < 2) {
                doc.Show();
                return;
            }
            if (App.Config.Debug) {
                doc.Show();
            } else {
                await doc.Print();
            }
        }
    }
}