using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.System;
using Windows.UI;
using WinRT;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace Sonex.Client.Controls.DataGridView;

public sealed partial class DataGridView : UserControl
{
    SolidColorBrush backColor;
    SolidColorBrush HeaderBackColor;
    Color HeaderIconColor;
    Color HoverHeaderIconColor;

    SolidColorBrush textColor;
    SolidColorBrush borderColor;
    SolidColorBrush indexBackColor;
    SolidColorBrush indexTextColor;
    Color selectedIndexTextColor;
    SolidColorBrush indexBorderColor;
    SolidColorBrush ActiveCellborderColor;
    SolidColorBrush ActiveRowFillColor;
    Color SelectedCallFillColor;
    Color SelectRangeColor;
    Color UnSelectRangeColor;
    Color ActiveCellColor;
    SmoothStepScroller _ScrollMoverVertical;
    SmoothStepScroller _ScrollMoverHorizontal;
    SolidColorBrush CellBackColor;
    Color LoadingBackColor;
    public DataGridView()
    {
        InicjalizeColors();
        InitializeComponent();
        Restart();

        _Canvas.Draw += Canvas_Draw;
        _Canvas.Loaded += Canvas_Loaded;
        _Canvas.SizeChanged += Canvas_SizeChanged;
        _ScrollHorizontal.ValueChanged += _ScrollHorizontal_ValueChanged;
        _ScrollVertical.ValueChanged += _ScrollVertical_ValueChanged;
        _Canvas.PointerExited += _Canvas_PointerExited;

        //_Canvas.PreviewKeyDown += _Canvas_KeyDown;
        //_Canvas.PreviewKeyUp += _Canvas_KeyUp;

        //_ScrollHorizontal.PreviewKeyDown += _Canvas_KeyDown;
        //_ScrollHorizontal.PreviewKeyUp += _Canvas_KeyUp;

        //_ScrollVertical.PreviewKeyDown += _Canvas_KeyDown;
        //_ScrollVertical.PreviewKeyUp += _Canvas_KeyUp;
        
        GettingFocus += DataGridView_GettingFocus;
        LostFocus += DataGridView_LostFocus;


        this.ActualThemeChanged += DataGridView_ActualThemeChanged;
        
        _Canvas.PointerWheelChanged += _Canvas_PointerWheelChanged;
        _ScrollHorizontal.SmallChange = 20;
        _ScrollHorizontal.LargeChange = 1;
        _Canvas.PointerMoved += _Canvas_PointerMoved;
        _Canvas.PointerPressed += _Canvas_PointerPressed;
        _Canvas.PointerReleased += _Canvas_PointerReleased;

        _ScrollVertical.SmallChange = 1;
        _ScrollVertical.LargeChange = 1;
        Unloaded += DataGridView_Unloaded;


        _ScrollMoverVertical = new SmoothStepScroller(_ScrollVertical,step:1,intervalMs:20);
        _ScrollMoverHorizontal = new SmoothStepScroller(_ScrollHorizontal, step: 10, intervalMs: 10);



    }



    private void DataGridView_LostFocus(object sender, RoutedEventArgs e)
    {
    }

    private void DataGridView_GettingFocus(UIElement sender, GettingFocusEventArgs args)
    {
    }

    private void _ScrollHorizontal_GotFocus(object sender, RoutedEventArgs e)
    {
       
        _Canvas.Focus(FocusState.Pointer);
    }



    private void InicjalizeColors()
    {
        backColor = (SolidColorBrush)Application.Current.Resources["SolidBackgroundFillColorQuarternaryBrush"];
        HeaderBackColor = (SolidColorBrush)Application.Current.Resources["SolidBackgroundFillColorTertiaryBrush"];
        textColor = (SolidColorBrush)Application.Current.Resources["TextFillColorPrimaryBrush"];
        borderColor = (SolidColorBrush)Application.Current.Resources["SurfaceStrokeColorDefaultBrush"];
        indexBackColor = (SolidColorBrush)Application.Current.Resources["SolidBackgroundFillColorTertiaryBrush"];
        indexTextColor = (SolidColorBrush)Application.Current.Resources["TextFillColorSecondaryBrush"];
        indexBorderColor = (SolidColorBrush)Application.Current.Resources["ControlStrongStrokeColorDefaultBrush"];
        selectedIndexTextColor = (Color)Application.Current.Resources["SystemAccentColorDark3"];
        selectedIndexTextColor.A = 190;
        ActiveCellborderColor = (SolidColorBrush)Application.Current.Resources["AccentFillColorDefaultBrush"];
        ActiveRowFillColor = (SolidColorBrush)Application.Current.Resources["ControlAltFillColorSecondaryBrush"];
        SelectedCallFillColor = (Color)Application.Current.Resources["SystemAccentColorLight2"];
        SelectedCallFillColor.A = 40;
        SelectRangeColor = (Color)Application.Current.Resources["SystemAccentColorLight2"];
        SelectRangeColor.A = 30;
        UnSelectRangeColor = ((SolidColorBrush)Application.Current.Resources["SystemFillColorCriticalBrush"]).Color;
        UnSelectRangeColor.A = 20;
        ActiveCellColor = (Color)Application.Current.Resources["SystemAccentColorLight2"];
        ActiveCellColor.A = 60;
        CellBackColor = (SolidColorBrush)Application.Current.Resources["SolidBackgroundFillColorQuarternaryBrush"];
        LoadingBackColor = ((SolidColorBrush)Application.Current.Resources["SolidBackgroundFillColorQuarternaryBrush"]).Color;
        LoadingBackColor.A = 160;
        HeaderIconColor = ((SolidColorBrush)Application.Current.Resources["SurfaceStrokeColorDefaultBrush"]).Color;
        HeaderIconColor.A = 100;
        HoverHeaderIconColor = (Color)Application.Current.Resources["SystemAccentColorDark3"];
    }

    private void _Canvas_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
    {
        var p = e.GetCurrentPoint(_Canvas);
        if (p == null) return;

        var now = Environment.TickCount64;
        var dt = _lastWheelTick == 0 ? 999.0 : (now - _lastWheelTick);
        _lastWheelTick = now;

        if (p.Position.Y <= HeaderHeight || e.KeyModifiers.HasFlag(VirtualKeyModifiers.Shift))
        {
            var step = ApplyWheel(ref _velH, p.Properties.MouseWheelDelta, baseStep: 5.0, dtMs: 10);

            _ScrollHorizontal.Value = Math.Clamp(
                _ScrollHorizontal.Value + step,
                _ScrollHorizontal.Minimum,
                _ScrollHorizontal.Maximum
            );
        }
        else
        {
            var step = ApplyWheel(ref _velV, p.Properties.MouseWheelDelta, baseStep: 1.0, dtMs: dt);

            _ScrollVertical.Value = Math.Clamp(
                _ScrollVertical.Value + step,
                _ScrollVertical.Minimum,
                _ScrollVertical.Maximum
            );
        }
    }
    private long _lastWheelTick;
    private double _velV; // "prędkość" pionowa
    private double _velH; // "prędkość" pozioma
    private static double SmoothMultiplier(double dtMs, double min = 1.0, double max = 10.0, double tau = 10.0)
    {
        // dt -> 0  => mult -> max
        // dt duże => mult -> min
        // tau steruje "jak szybko" rośnie (mniejszy tau = agresywniej)
        var x = Math.Exp(-dtMs / tau);          // 1..0
        return min + (max - min) * x;           // min..max
    }
    private double ApplyWheel(ref double velocity, int wheelDelta, double baseStep, double dtMs)
    {
        var dir = wheelDelta > 0 ? -1.0 : 1.0;

        var mult = SmoothMultiplier(dtMs, min: 1.0, max: 2.0, tau: 10.0);

        // impuls zależny od dt
        var impulse = dir * baseStep * mult;

        // inercja: wygładza + kumuluje szybkie kręcenie
        // dt=0..∞ => decay 0.0..1.0
        var decay = Math.Exp(-dtMs / 20.0);
        velocity = velocity * decay + impulse;

        return velocity;
    }

    private void DataGridView_ActualThemeChanged(FrameworkElement sender, object args)
    {
        InicjalizeColors();
        RequestRender();
    }
    

    private void Canvas_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        _NeedCalcHorizontalScroll = true;
        _NeedCalcVerticalScroll = true;
        _NeedCalcHeaders = true;
        RequestRender();
    }

    private void Canvas_Loaded(object sender, RoutedEventArgs e)
    {
       
    }
    private void DataGridView_Unloaded(object sender, RoutedEventArgs e)
    {
        // 1️⃣ odpinanie eventów UI (opcjonalne, ale bezpieczne)
        _Canvas.Draw -= Canvas_Draw;
        _Canvas.Loaded -= Canvas_Loaded;
        _Canvas.SizeChanged -= Canvas_SizeChanged;
        _Canvas.PointerWheelChanged -= _Canvas_PointerWheelChanged;
        _Canvas.PointerMoved -= _Canvas_PointerMoved;
        _Canvas.PointerPressed -= _Canvas_PointerPressed;
        _Canvas.PointerReleased -= _Canvas_PointerReleased;

        _ScrollHorizontal.ValueChanged -= _ScrollHorizontal_ValueChanged;
        _ScrollVertical.ValueChanged -= _ScrollVertical_ValueChanged;

        ActualThemeChanged -= DataGridView_ActualThemeChanged;

        // 2️⃣ odczepienie danych
        _ItemsSourceFiltred = null;
        _itemType = null;

        // 3️⃣ reset stanu renderingu (opcjonalnie)
        _NeedCalcHorizontalScroll = true;
        _NeedCalcVerticalScroll = true;
        _NeedCalcHeaders = true;
        GC.Collect();
    }

}
