using Godot;
using Mr.BrickAdventures.Autoloads;

namespace Mr.BrickAdventures.scripts.UI;

public partial class GameplaySettings : Control
{
    [Export] public HSlider DeadzoneSlider { get; set; }
    [Export] public Label DeadzoneValueLabel { get; set; }
    [Export] public HSlider SensitivitySlider { get; set; }
    [Export] public Label SensitivityValueLabel { get; set; }
    [Export] public Control GameplaySettingsControl { get; set; }

    private UIManager UIManager => UIManager.Instance;

    public override void _Ready()
    {
        DeadzoneSlider.FocusMode = Control.FocusModeEnum.All;
        SensitivitySlider.FocusMode = Control.FocusModeEnum.All;

        DeadzoneSlider.MinValue = 0.05;
        DeadzoneSlider.MaxValue = 0.5;
        DeadzoneSlider.Step = 0.05;
        DeadzoneSlider.Value = 0.2;

        SensitivitySlider.MinValue = 0.5;
        SensitivitySlider.MaxValue = 2.0;
        SensitivitySlider.Step = 0.1;
        SensitivitySlider.Value = 1.0;

        LoadSettings();

        DeadzoneSlider.ValueChanged += OnDeadzoneChanged;
        SensitivitySlider.ValueChanged += OnSensitivityChanged;

        if (InputDeviceManager.Instance != null)
            InputDeviceManager.Instance.DeviceChanged += OnDeviceChanged;
        GameplaySettingsControl.VisibilityChanged += OnVisibilityChanged;
    }

    public override void _ExitTree()
    {
        if (InputDeviceManager.Instance != null)
            InputDeviceManager.Instance.DeviceChanged -= OnDeviceChanged;
        GameplaySettingsControl.VisibilityChanged -= OnVisibilityChanged;
        SaveSettings();
    }

    public override void _UnhandledInput(InputEvent @event)
    {
        if (!@event.IsActionReleased("ui_cancel")) return;
        if (!UIManager.IsScreenOnTop(GameplaySettingsControl)) return;

        SaveSettings();
        UIManager.PopScreen();
    }

    private void OnVisibilityChanged()
    {
        if (GameplaySettingsControl.IsVisibleInTree() && InputDeviceManager.Instance?.IsPointerless == true)
            GrabFirstFocus();
    }

    private void OnDeviceChanged(int device)
    {
        var d = (InputDeviceManager.InputDevice)device;
        if (d != InputDeviceManager.InputDevice.Mouse && GameplaySettingsControl.IsVisibleInTree())
            GrabFirstFocus();
    }

    private void GrabFirstFocus() => DeadzoneSlider.GrabFocus();

    private void OnDeadzoneChanged(double value)
    {
        SettingsManager.Instance.GamepadDeadzone = (float)value;
        SettingsManager.Instance.ApplyGamepadDeadzone();
        DeadzoneValueLabel.Text = $"{value:F2}";
        SaveSettings();
    }

    private void OnSensitivityChanged(double value)
    {
        SettingsManager.Instance.GamepadSensitivity = (float)value;
        SensitivityValueLabel.Text = $"{value:F2}";
        SaveSettings();
    }

    private void LoadSettings()
    {
        DeadzoneSlider.Value = SettingsManager.Instance.GamepadDeadzone;
        SensitivitySlider.Value = SettingsManager.Instance.GamepadSensitivity;
        DeadzoneValueLabel.Text = $"{SettingsManager.Instance.GamepadDeadzone:F2}";
        SensitivityValueLabel.Text = $"{SettingsManager.Instance.GamepadSensitivity:F2}";
    }

    private void SaveSettings() => SettingsManager.Instance.SaveGameplaySettings();
}
