using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace CtrEditor.PopUps
{
    public partial class ScaleConfigWindow : Window
    {
        public ScaleConfigWindow(float currentScale, MainViewModel mainViewModel)
        {
            InitializeComponent();
            DataContext = new ScaleConfigViewModel(currentScale, this, mainViewModel);
        }

        public float NewScale => ((ScaleConfigViewModel)DataContext).NewScale;
    }

    public partial class ScaleConfigViewModel : ObservableObject
    {
        private readonly ScaleConfigWindow _window;
        private readonly MainViewModel _mainViewModel;
        private float _originalScale;
        private DispatcherTimer _autoApplyTimer;

        [ObservableProperty]
        private float currentScale;

        [ObservableProperty]
        private float newScale;

        public ICommand SetPresetCommand { get; }
        public ICommand AcceptCommand { get; }
        public ICommand CancelCommand { get; }
        public ICommand ApplyCommand { get; }

        public ScaleConfigViewModel(float currentScale, ScaleConfigWindow window, MainViewModel mainViewModel)
        {
            _window = window;
            _mainViewModel = mainViewModel;
            _originalScale = currentScale;
            CurrentScale = currentScale;
            NewScale = currentScale;

            // Inicializar timer para aplicación automática
            _autoApplyTimer = new DispatcherTimer
            {
                Interval = TimeSpan.FromMilliseconds(500) // 500ms de delay
            };
            _autoApplyTimer.Tick += (s, e) =>
            {
                _autoApplyTimer.Stop();
                if (NewScale > 0 && NewScale != CurrentScale)
                {
                    Apply();
                }
            };

            SetPresetCommand = new RelayCommand<object>(SetPreset);
            AcceptCommand = new RelayCommand(Accept, CanAccept);
            CancelCommand = new RelayCommand(Cancel);
            ApplyCommand = new RelayCommand(Apply, CanAccept);
        }

        private void SetPreset(object parameter)
        {
            if (parameter != null && float.TryParse(parameter.ToString(),
                System.Globalization.NumberStyles.Float,
                System.Globalization.CultureInfo.InvariantCulture,
                out float presetValue))
            {
                NewScale = presetValue;
            }
        }

        private bool CanAccept()
        {
            return NewScale > 0;  // Solo verificar que sea positivo
        }

        private void Accept()
        {
            if (NewScale <= 0)
            {
                MessageBox.Show("La escala debe ser un valor positivo mayor que cero.",
                               "Error de Validación",
                               MessageBoxButton.OK,
                               MessageBoxImage.Warning);
                return;
            }

            // Aplicar la escala una última vez antes de cerrar
            Apply();

            // Cerrar la ventana
            _window.Close();
        }

        private void Apply()
        {
            if (NewScale <= 0)
            {
                MessageBox.Show("La escala debe ser un valor positivo mayor que cero.",
                               "Error de Validación",
                               MessageBoxButton.OK,
                               MessageBoxImage.Warning);
                return;
            }

            // Aplicar la escala inmediatamente
            _mainViewModel.ApplyScale(NewScale);

            // Actualizar la escala actual para reflejar el cambio
            CurrentScale = NewScale;
        }

        private void Cancel()
        {
            // Restaurar la escala original
            _mainViewModel.ApplyScale(_originalScale);

            // Cerrar la ventana
            _window.Close();
        }

        partial void OnNewScaleChanged(float value)
        {
            // Forzar la re-evaluación del comando Accept cuando el valor cambia
            CommandManager.InvalidateRequerySuggested();

            // Reiniciar el timer para aplicación automática (verificar que esté inicializado)
            if (_autoApplyTimer != null)
            {
                _autoApplyTimer.Stop();
                if (value > 0 && value != CurrentScale)
                {
                    _autoApplyTimer.Start();
                }
            }
        }
    }
}