using Microsoft.UI.Xaml;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;


namespace Sonex.Client.Controls.DataGridView;

// Odpowiedzialnosc pliku: definicja DependencyProperty i reakcje na zmiany danych/rozmiarow.

public sealed partial class DataGridView
{
    /// <summary>
    /// Źródło danych dla kontrolki <see cref="DataGridView"/>.
    /// </summary>
    /// <remarks>
    /// Właściwość oczekuje kolekcji typu <see cref="List{Object}"/>.
    /// Dane są przypisywane bezpośrednio do wewnętrznego cache’u,
    /// bez dodatkowych konwersji i enumeracji, co poprawia wydajność.
    /// Zmiana wartości powoduje ponowne renderowanie kontrolki.
    /// </remarks>
    public Type? ItemsType
    {
        get => (Type?)GetValue(ItemsTypeProperty);
        set => SetValue(ItemsTypeProperty, value);
    }
    public static readonly DependencyProperty ItemsTypeProperty =
        DependencyProperty.Register(
            nameof(ItemsType),
            typeof(Type),
            typeof(DataGridView),
            new PropertyMetadata(null, OnItemsTypeChanged));

    private Type? _itemType; // cache strony

    private static void OnItemsTypeChanged(
        DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        var grid = (DataGridView)d;
        grid._itemType = (Type?)e.NewValue;
        grid.SetFilter(grid.Filter);
        grid.Restart();
    }

    /// <summary>
    /// Źródło danych dla kontrolki <see cref="DataGridView"/>.
    /// </summary>
    /// <remarks>
    /// Właściwość akceptuje dowolną kolekcję implementującą <see cref="IList"/> (np. <see cref="List{T}"/>, tablice).
    /// Dane są przechowywane jako referencja (bez kopiowania i enumeracji), co poprawia wydajność.
    /// Zmiana wartości powoduje ponowne renderowanie kontrolki.
    /// </remarks>
    public IList? ItemsSource
    {
        get => (IList?)GetValue(ItemsSourceProperty);
        set => SetValue(ItemsSourceProperty, value);
    }

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register(
            nameof(ItemsSource),
            typeof(IList),
            typeof(DataGridView),
            new PropertyMetadata(null, OnItemsSourceChanged));

    private IList? _ItemsSourceFiltred;
    private IList? _ItemsSource;

    private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var grid = (DataGridView)d;
        grid._ItemsSource = (IList?)e.NewValue;

        var count = grid._ItemsSource?.Count ?? 0;
        grid._FooterText1.Text = $"Rows: {0:N0}/{count:N0}";
        grid.SetFilter(grid.Filter);
        grid.Restart();
            grid.Focus(FocusState.Pointer);
    }




    /// <summary>
    /// Wysokość nagłówków kolumn w jednostkach DIP (device-independent pixels).
    /// </summary>
    /// <value>
    /// Zwraca lub ustawia wartość typu <see cref="double"/> określającą wysokość nagłówków w DIP.
    /// Wartość domyślna to 32.0.
    /// </value>
    public double HeaderHeight
    {
        get => (double)GetValue(HeaderHeightProperty);
        set => SetValue(HeaderHeightProperty, value);
    }

    private float _HeaderHeight = 22f;

    public static readonly DependencyProperty HeaderHeightProperty =
        DependencyProperty.Register(
            nameof(HeaderHeight),
            typeof(double),
            typeof(DataGridView),
            new PropertyMetadata(22d, OnHeaderHeightChanged));

    private static void OnHeaderHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var grid = (DataGridView)d;
        var value = (double)e.NewValue;

        if (double.IsNaN(value) || double.IsInfinity(value) || value < 0)
        {
            grid.SetValue(HeaderHeightProperty, 22d);
            return;
        }

        grid._HeaderHeight = (float)value;
        grid._NeedCalcVerticalScroll = true;
        //grid.InvalidateMeasure(); // informuje layout engine WinUI, że rozmiar kontrolki może się zmienić i trzeba przeliczyć układ.
        grid.RequestRender();     // prosi kontrolkę o ponowne wyrenderowanie się z nową wartością.
    }


    /// <summary>
    /// Pokazuje progress ring ładowania danych
    /// </summary>
    /// <value>
    /// ustawia wartość typu <see cref="bool"/> który wyświetla lub chowa progress ring
    /// Wartość domyślna to false.
    /// </value>
    public bool LoadingRing
    {
        get => (bool)GetValue(LoadingRingProperty);
        set => SetValue(LoadingRingProperty, value);
    }

    public static readonly DependencyProperty LoadingRingProperty =
        DependencyProperty.Register(
            nameof(LoadingRing),
            typeof(bool),
            typeof(DataGridView),
            new PropertyMetadata(false, OnLoadingRingChanged));

    private static void OnLoadingRingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var value = (bool)e.NewValue;
        var grid = (DataGridView)d;

        grid._ProgressRing.IsActive = (bool)value;
        grid.IsEnabled = !(bool)value;
        if ((bool)value)
        {
            //BadgeNotificationManager.Current.SetBadgeAsGlyph(BadgeNotificationGlyph.Activity);
        }
        else
        {
            //BadgeNotificationManager.Current.ClearBadge();
        }
        grid.RequestRender();     // prosi kontrolkę o ponowne wyrenderowanie się z nową wartością.

    }



    /// <summary>
    /// Wysokość wierszy z danych w jednostkach DIP (device-independent pixels).
    /// </summary>
    /// <value>
    /// Zwraca lub ustawia wartość typu <see cref="double"/> określającą wysokość wierszy w DIP.
    /// Wartość domyślna to 32.0.
    /// </value>

    public double RowsHeight
    {
        get => (double)GetValue(RowsHeightProperty);
        set => SetValue(RowsHeightProperty, value);
    }

    private float _RowsHeight = 20;

    public static readonly DependencyProperty RowsHeightProperty =
        DependencyProperty.Register(
            nameof(RowsHeight),
            typeof(double),
            typeof(DataGridView),
            new PropertyMetadata(24d, OnRowsHeightChanged));

    private static void OnRowsHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var grid = (DataGridView)d;
        var value = (double)e.NewValue;

        if (double.IsNaN(value) || double.IsInfinity(value) || value < 0)
        {
            grid.SetValue(RowsHeightProperty, 20d);
            return;
        }

        grid._RowsHeight = (float)value;
        grid._NeedCalcVerticalScroll = true;
        //grid.InvalidateMeasure(); // informuje layout engine WinUI, że rozmiar kontrolki może się zmienić i trzeba przeliczyć układ.
        grid.RequestRender();     // prosi kontrolkę o ponowne wyrenderowanie się z nową wartością.
    }
}
