using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Sonex.Client.Controls.Filters;
using Sonex.Client.Helpers;
using Sonex.Client.Views;
using Sonex.Data.Records;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace Sonex.Client.Pages.Warehouse;

public sealed partial class Products : Page
{
    private CancellationTokenSource? _loadProductsCts;
    private bool _isUnloaded;

    public Products()
    {
        InitializeComponent();

        DataGrid.HeaderHeight = 25;
        DataGrid.RowsHeight = 21;
        DetailsTabView.ItemType = typeof(ProductRecord);
        RootFilter.SetColumns(BuildProductFilterColumns(), BuildProductDefaultFilters());
        RootFilter.FilterChanged += RootFilter_FilterChanged;
        DataGrid.Loaded += DataGrid_Loaded;
        Unloaded += Products_Unloaded;
    }

    private async void DataGrid_Loaded(object sender, RoutedEventArgs e)
    {
        await LoadProducts();
    }

    private async void RootFilter_FilterChanged(object? sender, EventArgs e)
    {
        if (_isUnloaded)
        {
            return;
        }

        await LoadProducts();
    }

    private async Task LoadProducts()
    {
        _isUnloaded = false;
        _loadProductsCts?.Cancel();
        _loadProductsCts?.Dispose();
        _loadProductsCts = new CancellationTokenSource();
        var ct = _loadProductsCts.Token;

        DataGrid.LoadingRing = true;
        DataGrid.ItemsType = typeof(ProductRecord);

        try
        {
            var filter = RootFilter.BuildSql();
            var r = await ProductRecord.GetAll(
                100000,
                filter.WhereSql,
                filter.Parameters,
                ct);

            if (ct.IsCancellationRequested || _isUnloaded)
            {
                return;
            }

            Debug.WriteLine(r.ErrorData ?? "no error");
            DataGrid.ItemsSource = r.Items;
        }
        finally
        {
            if (!ct.IsCancellationRequested && !_isUnloaded)
            {
                DataGrid.LoadingRing = false;
            }
        }
    }

    private void Products_Unloaded(object sender, RoutedEventArgs e)
    {
        _isUnloaded = true;
        _loadProductsCts?.Cancel();
        _loadProductsCts?.Dispose();
        _loadProductsCts = null;

        DataGrid.LoadingRing = false;
        DataGrid.ItemsSource = null;
        DataGrid.ItemsType = null;
        DetailsTabView.Load(null);
    }

    private void DataGrid_OnChangeActiveRow(object sender, Controls.DataGridView.DataGridView.DataGridStateChangedEventArgs e)
    {
        try
        {
            if (e.Row is ProductRecord row)
            {
                DetailsTabView.Load(row);
            }
            else
            {
                DetailsTabView.Load(null);
            }
        }
        finally
        {

        }
    }

    private static IReadOnlyList<SqlFilterColumn> BuildProductFilterColumns()
    {
        return
        [
            new("Article Number", "artnr", typeof(string)),
            new("Article Name", "article_name", typeof(string)),
            new("SU EAN", "su_eans", typeof(string)),
            new("Category", "category", typeof(string)),
            new("Sales Class", "sales_class", typeof(string)),
            new("DC Group", "dc_group", typeof(string)),
            new("Web Cluster", "web_cluster", typeof(string)),
            new("Web Sales Class", "web_sales_class", typeof(string)),
            new("Web Sales Share", "web_sales_share", typeof(double?)),
            new("Price NL", "price_nl", typeof(decimal?)),
            new("Price DE", "price_de", typeof(decimal?)),
            new("Price HC", "price_hc", typeof(decimal?)),
            new("Archival", "archival", typeof(bool)),
            new("Packsize", "packsize", typeof(bool)),
            new("Ship Unit", "ship_unit", typeof(bool)),
            new("BK", "bk", typeof(bool?)),
            new("DPD", "dpd", typeof(bool?)),
            new("Last Received", "last_received", typeof(DateTime?)),
            new("Dimensions Checked", "article_dimensions_checked", typeof(DateTime?))
        ];
    }

    private static IReadOnlyList<SqlFilterDefaultRule> BuildProductDefaultFilters()
    {
        return
        [
            new("artnr", SqlFilterComparison.Contains),
            new("article_name", SqlFilterComparison.Contains),
            new("su_eans", SqlFilterComparison.Contains)
        ];
    }
}
