using System;
using System.Collections.Generic;
using Dalamud.Game.ClientState.GamePad;
using Dalamud.Game.ClientState.Keys;
using Dalamud.Plugin.Services;
using HSUI.Config;
using HSUI.Interface.GeneralElements;

namespace HSUI.Helpers
{
    /// <summary>Polls controller bar keybinds and executes slots when keys/buttons are pressed. Supports combinations (e.g. L2+South).</summary>
    public static class ControllerBarKeybindExecutor
    {
        private static readonly Dictionary<string, bool> _triggerWasDown = new Dictionary<string, bool>();

        public static void Process(IFramework framework)
        {
            try
            {
                if (!ControllerHotbarsConfig.GetEffectiveControllerHotbarsEnabled())
                    return;

                var keybindsConfig = ConfigurationManager.Instance?.GetConfigObject<ControllerBarKeybindsConfig>();
                if (keybindsConfig == null)
                    return;

                if (ActionBarsManager.Instance == null)
                    return;

                for (int bar = 1; bar <= ControllerBarKeybindsConfig.Bars; bar++)
                {
                    for (int slot = 0; slot < ControllerBarKeybindsConfig.SlotsPerBar; slot++)
                    {
                        string binding = keybindsConfig.GetKeybind(bar, slot);
                        if (string.IsNullOrEmpty(binding)) continue;

                        bool triggered = IsKeybindTriggered(binding);
                        if (triggered)
                            ActionBarsManager.Instance.ExecuteControllerSlot(bar, slot);
                    }
                }
            }
            catch (Exception ex)
            {
                Plugin.Logger?.Warning($"[HSUI ControllerBarKeybinds] Process: {ex.Message}");
            }
        }

        /// <summary>True when all modifiers are held and the trigger key/button was just pressed (edge).</summary>
        private static bool IsKeybindTriggered(string binding)
        {
            if (string.IsNullOrEmpty(binding)) return false;

            string[] parts = binding.Split('+');
            for (int i = 0; i < parts.Length; i++)
                parts[i] = parts[i].Trim();

            if (parts.Length == 0) return false;
            if (parts.Length == 1)
            {
                bool down = IsSingleKeybindDown(parts[0]);
                if (!_triggerWasDown.TryGetValue(binding, out bool wasDown)) wasDown = false;
                _triggerWasDown[binding] = down;
                return down && !wasDown;
            }

            string triggerPart = parts[parts.Length - 1];
            for (int i = 0; i < parts.Length - 1; i++)
            {
                if (!IsSingleKeybindDown(parts[i]))
                    return false;
            }
            bool triggerDown = IsSingleKeybindDown(triggerPart);
            if (!_triggerWasDown.TryGetValue(binding, out bool triggerWasDown))
                triggerWasDown = false;
            _triggerWasDown[binding] = triggerDown;
            return triggerDown && !triggerWasDown;
        }

        private static bool IsSingleKeybindDown(string part)
        {
            if (string.IsNullOrEmpty(part)) return false;

            if (part.StartsWith("Key:", StringComparison.OrdinalIgnoreCase))
            {
                string vkStr = part.Substring(4).Trim();
                if (Plugin.KeyState == null) return false;
                if (Enum.TryParse<VirtualKey>(vkStr, true, out var vk)
                    && Plugin.KeyState.IsVirtualKeyValid((int)vk))
                    return Plugin.KeyState[vk];
                return false;
            }

            if (part.StartsWith("Pad:", StringComparison.OrdinalIgnoreCase))
            {
                string padStr = part.Substring(4).Trim();
                if (Plugin.GamepadState == null) return false;
                if (Enum.TryParse<GamepadButtons>(padStr, true, out var btn))
                    return Plugin.GamepadState.Raw(btn) > 0.5f;
                return false;
            }

            return false;
        }
    }
}
