using System.Collections.Specialized;
using System.ComponentModel;
using System.Reflection;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Threading;
using VisionBuilder.UI.Avalonia;
using VisionBuilder.UI.Common;
using VisionBuilder.UI.Common.Services;
using VisionBuilder.UI.Common.ViewModel;
using VisionBuilder.UI.Common.ViewModel.Classes;

namespace VisionBuilder.UI.Avalonia.Uno.Views;

public partial class MainWindow : Window
{
    private readonly MainWindowVM _mainWindowVm;
    private readonly AvaloniaUISettings _avaloniaUiSettings;
    private readonly UIConfiguration _uiConfiguration;
    private readonly IPasswordInputService _passwordInputService;
    private readonly Dictionary<string, Control> _dynamicButtonControls = new();

    public MainWindow(MainWindowVM mainWindowVm, AvaloniaUISettings avaloniaUiSettings,
        UIConfiguration uiConfiguration, IPasswordInputService passwordInputService)
    {
        _mainWindowVm = mainWindowVm;
        _avaloniaUiSettings = avaloniaUiSettings;
        _uiConfiguration = uiConfiguration;
        _passwordInputService = passwordInputService;

        InitializeComponent();

        DataContext = _mainWindowVm;

        SingleCameraView.SetViewModel(_mainWindowVm.SingleCameraVms[0]);

        BtnSettings.Click += BtnSettings_Click;
        BtnMinimize.Click += BtnMinimize_Click;
        BtnExit.Click += BtnExit_Click;

        var version = Assembly.GetExecutingAssembly().GetName().Version;
        LblVersion.Text = version != null ? $"v{version.Major}.{version.Minor}.{version.Build}" : "v0.0.0";

        _mainWindowVm.PropertyChanged += MainWindowVm_PropertyChanged;

        _mainWindowVm.DynamicButtons.CollectionChanged += DynamicButtons_CollectionChanged;
        foreach (var btn in _mainWindowVm.DynamicButtons)
            AddDynamicButton(btn);
    }

    protected override void OnOpened(EventArgs e)
    {
        base.OnOpened(e);
        _mainWindowVm.OnProgramStarted();

        if (_avaloniaUiSettings.FullScreen)
        {
            WindowState = WindowState.Maximized;
        }
    }

    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        _mainWindowVm.OnProgramClosed();
        Environment.Exit(0);
    }

    private void MainWindowVm_PropertyChanged(object? sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(_mainWindowVm.TestMode))
        {
            // Toggle accent color for test mode visual indication
            // Green background when test mode is active
            if (_mainWindowVm.TestMode)
            {
                Background = new global::Avalonia.Media.SolidColorBrush(
                    global::Avalonia.Media.Color.FromRgb(0x2E, 0x7D, 0x32)); // Green800
            }
            else
            {
                Background = new global::Avalonia.Media.SolidColorBrush(
                    global::Avalonia.Media.Colors.White);
            }
        }
    }

    private async void BtnSettings_Click(object? sender, RoutedEventArgs e)
    {
        if (_uiConfiguration.ProtectSettingsWithPassword)
        {
            var passwordOk = await _passwordInputService.GetPasswordAsync() == _uiConfiguration.AdminPassword;
            if (!passwordOk)
                return;
        }
        _mainWindowVm.SettingsCommand.Execute(null);
    }

    private void BtnMinimize_Click(object? sender, RoutedEventArgs e)
    {
        WindowState = WindowState.Minimized;
    }

    private void BtnExit_Click(object? sender, RoutedEventArgs e)
    {
        _mainWindowVm.OnProgramClosed();
        Environment.Exit(0);
    }

    private void DynamicButtons_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
    {
        Dispatcher.UIThread.Post(() =>
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    foreach (ButtonDefinition btn in e.NewItems!)
                        AddDynamicButton(btn);
                    break;
                case NotifyCollectionChangedAction.Remove:
                    foreach (ButtonDefinition btn in e.OldItems!)
                        RemoveDynamicButton(btn);
                    break;
                case NotifyCollectionChangedAction.Reset:
                    foreach (var ctrl in _dynamicButtonControls.Values)
                        BottomBarPanel.Children.Remove(ctrl);
                    _dynamicButtonControls.Clear();
                    break;
            }
        });
    }

    private void AddDynamicButton(ButtonDefinition buttonDef)
    {
        Control control;
        if (buttonDef.Type == EButtonType.Toggle)
        {
            var toggleBtn = new ToggleButton
            {
                Content = buttonDef.Title.ToUpperInvariant(),
                Width = 176,
                Height = 48,
                FontSize = 14,
                FontWeight = FontWeight.Bold,
                HorizontalContentAlignment = global::Avalonia.Layout.HorizontalAlignment.Center,
                VerticalContentAlignment = global::Avalonia.Layout.VerticalAlignment.Center,
                IsChecked = buttonDef.IsToggled,
                IsVisible = buttonDef.IsVisible,
                BorderBrush = new SolidColorBrush(Color.FromRgb(0xD3, 0x2F, 0x2F)),
                BorderThickness = new Thickness(2),
                Background = Brushes.White,
                Foreground = new SolidColorBrush(Color.FromRgb(0xD3, 0x2F, 0x2F))
            };
            toggleBtn.Click += (_, _) => buttonDef.Execute();
            buttonDef.PropertyChanged += (_, args) =>
            {
                Dispatcher.UIThread.Post(() =>
                {
                    if (args.PropertyName == nameof(ButtonDefinition.IsVisible))
                        toggleBtn.IsVisible = buttonDef.IsVisible;
                    else if (args.PropertyName == nameof(ButtonDefinition.IsToggled))
                        toggleBtn.IsChecked = buttonDef.IsToggled;
                });
            };
            control = toggleBtn;
        }
        else
        {
            var btn = new Button
            {
                Content = buttonDef.Title.ToUpperInvariant(),
                Width = 176,
                Height = 48,
                FontSize = 14,
                FontWeight = FontWeight.Bold,
                HorizontalContentAlignment = global::Avalonia.Layout.HorizontalAlignment.Center,
                VerticalContentAlignment = global::Avalonia.Layout.VerticalAlignment.Center,
                IsVisible = buttonDef.IsVisible,
                BorderBrush = new SolidColorBrush(Color.FromRgb(0xD3, 0x2F, 0x2F)),
                BorderThickness = new Thickness(2),
                Background = Brushes.White,
                Foreground = new SolidColorBrush(Color.FromRgb(0xD3, 0x2F, 0x2F))
            };
            btn.Click += (_, _) => buttonDef.Execute();
            buttonDef.PropertyChanged += (_, args) =>
            {
                Dispatcher.UIThread.Post(() =>
                {
                    if (args.PropertyName == nameof(ButtonDefinition.IsVisible))
                        btn.IsVisible = buttonDef.IsVisible;
                });
            };
            control = btn;
        }

        // Insert before BtnMinimize
        var minimizeIndex = BottomBarPanel.Children.IndexOf(BtnMinimize);
        if (minimizeIndex >= 0)
            BottomBarPanel.Children.Insert(minimizeIndex, control);
        else
            BottomBarPanel.Children.Add(control);

        _dynamicButtonControls[buttonDef.Key] = control;
    }

    private void RemoveDynamicButton(ButtonDefinition buttonDef)
    {
        if (_dynamicButtonControls.TryGetValue(buttonDef.Key, out var ctrl))
        {
            BottomBarPanel.Children.Remove(ctrl);
            _dynamicButtonControls.Remove(buttonDef.Key);
        }
    }
}
