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

namespace Elwig.Dialogs {
    public partial class DeliveryConfirmationsDialog : ContextWindow {

        public readonly int Year;

        public DeliveryConfirmationsDialog(int year) {
            InitializeComponent();
            Year = year;
            Title = $"Anlieferungsbestätigungen - Lese {Year} - Elwig";
            TextElement.Text = App.Client.TextDeliveryConfirmation;
            if (!App.Config.Debug) {
                TestButton.Visibility = Visibility.Hidden;
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs evt) {
            TestButton.IsEnabled = App.IsPrintingReady;
            ShowButton.IsEnabled = App.IsPrintingReady;
            PrintButton.IsEnabled = App.IsPrintingReady;
        }

        protected override async Task OnRenewContext() { }

        private async Task UpdateTextParameter() {
            var text = TextElement.Text;
            if (text.Length == 0) text = null;
            if (text != App.Client.TextDeliveryConfirmation) {
                App.Client.TextDeliveryConfirmation = text;
                await App.Client.UpdateValues();
            }
        }

        private async Task Generate(int mode) {

            Mouse.OverrideCursor = Cursors.AppStarting;
            await UpdateTextParameter();

            IQueryable<Member> members;
            if (AllMembersInput.IsChecked == true) {
                members = Context.Members.Where(m => m.IsActive);
            } else {
                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
                    """);
            }

            if (OrderMgNrInput.IsChecked == true) {
                members = members
                    .OrderBy(m => m.MgNr);
            } else if (OrderNameInput.IsChecked == true) {
                members = members
                    .OrderBy(m => m.FamilyName)
                    .ThenBy(m => m.GivenName)
                    .ThenBy(m => m.MgNr);
            } else if (OrderPlzInput.IsChecked == true) {
                members = members
                    .OrderBy(m => m.PostalDest.AtPlz.Plz)
                    .ThenBy(m => m.PostalDest.AtPlz.Ort.Name)
                    .ThenBy(m => m.FamilyName)
                    .ThenBy(m => m.GivenName)
                    .ThenBy(m => m.MgNr);
            }

            IEnumerable<Member> list = await members.ToListAsync();
            if (mode == 0) {
                var r = new Random().Next(0, 10);
                list = list.Where((_, n) => n % 10 == r);
            }

            var deliveries = await Context.DeliveryParts.FromSqlRaw($"""
                SELECT p.*
                FROM v_delivery v
                    JOIN delivery_part p ON (p.year, p.did, p.dpnr) = (v.year, v.did, v.dpnr)
                WHERE v.year = {Year}
                ORDER BY v.sortid, v.abgewertet ASC,
                         COALESCE(LENGTH(v.attributes), 0) ASC, attribute_prio DESC, COALESCE(v.attributes, '~'),
                         v.kmw DESC, v.lsnr, v.dpnr
                """)
                .ToListAsync();

            using var doc = await Document.Merge(list.Select(m => new DeliveryConfirmation(Context, Year, m, deliveries.Where(d => d.Delivery.MgNr == m.MgNr)))); ;
            await doc.Generate();
            Mouse.OverrideCursor = null;

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

        private async void TestButton_Click(object sender, RoutedEventArgs evt) {
            await Generate(0);
        }

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

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