using System;
using System.ComponentModel;
using Marechai.App.Presentation.ViewModels;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace Marechai.App.Presentation.Views;

public sealed partial class MainPage : Page
{
    private PropertyChangedEventHandler _sidebarPropertyChangedHandler;

    public MainPage()
    {
        InitializeComponent();
        DataContextChanged += MainPage_DataContextChanged;
        Loaded             += MainPage_Loaded;
    }

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        if(DataContext is not MainViewModel viewModel) return;

        SidebarWrapper.Width = viewModel.IsSidebarOpen ? 280 : 60;

        if(_sidebarPropertyChangedHandler != null) return;

        _sidebarPropertyChangedHandler = (_, propArgs) =>
        {
            if(propArgs.PropertyName != nameof(MainViewModel.IsSidebarOpen)) return;

            AnimateSidebarWidth(((MainViewModel)DataContext).IsSidebarOpen);
        };

        ((INotifyPropertyChanged)viewModel).PropertyChanged += _sidebarPropertyChangedHandler;
    }

    void AnimateSidebarWidth(bool isOpen)
    {
        double start = SidebarColumn.Width.Value;
        double end   = isOpen ? 280 : 60;

        if(Math.Abs(start - end) < 0.1) return;

        // If expanding, show content immediately
        if(isOpen && DataContext is MainViewModel vm) vm.SidebarContentVisible = true;

        const int durationMs  = 250;
        const int fps         = 60;
        var       steps       = (int)(durationMs / (1000.0 / fps));
        var       currentStep = 0;

        var timer = new DispatcherTimer
        {
            Interval = TimeSpan.FromMilliseconds(1000.0 / fps)
        };

        timer.Tick += (_, _) =>
        {
            currentStep++;
            double t = (double)currentStep / steps;

            // Ease in-out cubic
            double eased = t < 0.5 ? 4           * t * t * t : 1 - Math.Pow(-2 * t + 2, 3) / 2;
            double value = start + (end - start) * eased;
            SidebarColumn.Width  = new GridLength(value, GridUnitType.Pixel);
            SidebarWrapper.Width = value;

            if(currentStep >= steps)
            {
                SidebarColumn.Width  = new GridLength(end, GridUnitType.Pixel);
                SidebarWrapper.Width = end;
                timer.Stop();

                // After collapse animation completes, hide sidebar content
                if(!isOpen && DataContext is MainViewModel vm) vm.SidebarContentVisible = false;
            }
        };

        timer.Start();
    }

    private void MainPage_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
    {
        if(args.NewValue is MainViewModel vm && _sidebarPropertyChangedHandler == null)
        {
            SidebarWrapper.Width = vm.IsSidebarOpen ? 280 : 60;

            _sidebarPropertyChangedHandler = (_, propArgs) =>
            {
                if(propArgs.PropertyName != nameof(MainViewModel.IsSidebarOpen)) return;
                AnimateSidebarWidth(vm.IsSidebarOpen);
            };

            ((INotifyPropertyChanged)vm).PropertyChanged += _sidebarPropertyChangedHandler;
        }
    }
}