using System.Runtime.InteropServices;
using System.Windows.Input;
using PersonalToolBox.Models;
using PersonalToolBox.Services;

namespace PersonalToolBox.Helpers;

/// <summary>
/// 全局快捷键管理器，使用 Win32 API RegisterHotKey / UnregisterHotKey
/// </summary>
public class HotKeyManager
{
    private IntPtr _hwnd;
    private int _nextId = 1;
    private readonly Dictionary<int, ToolItem> _hotkeyMap = new();
    private readonly ILogService _logService;
    private readonly IProcessExecutionService _processService;

    public bool IsEnabled { get; set; } = true;

    // ──────────────── Win32 API ────────────────

    private const int WM_HOTKEY = 0x0312;
    private const uint MOD_ALT = 0x0001;
    private const uint MOD_CONTROL = 0x0002;
    private const uint MOD_SHIFT = 0x0004;
    private const uint MOD_WIN = 0x0008;

    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

    // ──────────────── 构造函数 ────────────────

    public HotKeyManager(ILogService logService, IProcessExecutionService processService)
    {
        _logService = logService;
        _processService = processService;
    }

    /// <summary>
    /// 设置窗口句柄（在 MainWindow.OnSourceInitialized 中调用）
    /// </summary>
    public void Initialize(IntPtr hwnd)
    {
        _hwnd = hwnd;
    }

    // ──────────────── 注册/注销 ────────────────

    /// <summary>
    /// 批量注册所有工具的快捷键
    /// </summary>
    public void RegisterAll(IEnumerable<ToolItem> tools)
    {
        UnregisterAll();
        foreach (var tool in tools.Where(t => !string.IsNullOrWhiteSpace(t.HotKey)))
            Register(tool);
    }

    /// <summary>
    /// 为单个工具注册快捷键
    /// </summary>
    public void Register(ToolItem tool)
    {
        if (_hwnd == IntPtr.Zero) return;
        if (string.IsNullOrWhiteSpace(tool.HotKey)) return;

        if (!TryParseHotKey(tool.HotKey, out uint modifiers, out uint vk))
        {
            _logService.Warning($"快捷键格式无效: {tool.HotKey}");
            return;
        }

        int id = _nextId++;
        if (RegisterHotKey(_hwnd, id, modifiers, vk))
        {
            _hotkeyMap[id] = tool;
            _logService.Info($"已注册快捷键: {tool.HotKey} → {tool.Name}");
        }
        else
        {
            int err = Marshal.GetLastWin32Error();
            _logService.Error($"快捷键注册失败: {tool.HotKey} (错误码: {err}，可能与其他程序冲突)");
        }
    }

    /// <summary>
    /// 注销所有已注册的快捷键
    /// </summary>
    private void UnregisterAll()
    {
        foreach (var kvp in _hotkeyMap)
            UnregisterHotKey(_hwnd, kvp.Key);
        _hotkeyMap.Clear();
    }

    // ──────────────── 消息处理 ────────────────

    /// <summary>
    /// 由 WndProc 钩子调用，处理 WM_HOTKEY 消息
    /// </summary>
    public bool TryHandleMessage(int msg, IntPtr wParam, IntPtr lParam)
    {
        if (msg != WM_HOTKEY) return false;
        if (!IsEnabled) return true;

        int id = wParam.ToInt32();
        if (_hotkeyMap.TryGetValue(id, out var tool))
        {
            _logService.Info($"通过快捷键启动: {tool.Name}");
            _ = _processService.ExecuteAsync(tool);
        }
        return true;
    }

    // ──────────────── 快捷键解析 ────────────────

    /// <summary>
    /// 解析快捷键字符串（如 "Ctrl+Alt+T"）为修饰键和虚拟键码
    /// </summary>
    public static bool TryParseHotKey(string hotkey, out uint modifiers, out uint vk)
    {
        modifiers = 0;
        vk = 0;

        if (string.IsNullOrWhiteSpace(hotkey)) return false;

        var parts = hotkey.Split('+', StringSplitOptions.TrimEntries);
        if (parts.Length < 2) return false;

        // 解析修饰键（最后一段之前的部分）
        foreach (var part in parts.Take(parts.Length - 1))
        {
            uint mod = part.ToUpperInvariant() switch
            {
                "CTRL" or "CONTROL" => MOD_CONTROL,
                "ALT" => MOD_ALT,
                "SHIFT" => MOD_SHIFT,
                "WIN" or "WINDOWS" => MOD_WIN,
                _ => 0
            };

            if (mod == 0) return false;
            modifiers |= mod;
        }

        if (modifiers == 0) return false;

        // 解析按键（最后一段）
        var keyStr = parts.Last();
        if (keyStr.Length == 1)
        {
            vk = char.ToUpperInvariant(keyStr[0]);
        }
        else if (Enum.TryParse<Key>(keyStr, true, out var key))
        {
            vk = (uint)KeyInterop.VirtualKeyFromKey(key);
        }
        else
        {
            return false;
        }

        return true;
    }

    /// <summary>
    /// 程序退出时清理所有快捷键
    /// </summary>
    public void Dispose()
    {
        UnregisterAll();
    }
}
