using System;
using System.Collections.Generic;

namespace AxCopilot.Core;

public static class HotkeyParser
{
	private static readonly Dictionary<string, int> _keyMap;

	static HotkeyParser()
	{
		_keyMap = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
		{
			["Space"] = 32,
			["Enter"] = 13,
			["Return"] = 13,
			["Tab"] = 9,
			["Esc"] = 27,
			["Escape"] = 27,
			["Backspace"] = 8,
			["Back"] = 8,
			["Delete"] = 46,
			["Del"] = 46,
			["Insert"] = 45,
			["Ins"] = 45,
			["Home"] = 36,
			["End"] = 35,
			["PageUp"] = 33,
			["PgUp"] = 33,
			["PageDown"] = 34,
			["PgDn"] = 34,
			["PrintScreen"] = 44,
			["PrtSc"] = 44,
			["Snapshot"] = 44,
			["Pause"] = 19,
			["Break"] = 19,
			["ScrollLock"] = 145,
			["Left"] = 37,
			["Up"] = 38,
			["Right"] = 39,
			["Down"] = 40,
			["`"] = 192,
			["Grave"] = 192,
			["-"] = 189,
			["="] = 187,
			["["] = 219,
			["]"] = 221,
			["\\"] = 220,
			[";"] = 186,
			["'"] = 222,
			[","] = 188,
			["."] = 190,
			["/"] = 191
		};
		for (char c = 'A'; c <= 'Z'; c = (char)(c + 1))
		{
			_keyMap[c.ToString()] = c;
		}
		for (char c2 = '0'; c2 <= '9'; c2 = (char)(c2 + 1))
		{
			_keyMap[c2.ToString()] = c2;
		}
		for (int i = 1; i <= 24; i++)
		{
			_keyMap[$"F{i}"] = 111 + i;
		}
		for (int j = 0; j <= 9; j++)
		{
			_keyMap[$"Num{j}"] = 96 + j;
		}
	}

	public static bool TryParse(string hotkey, out HotkeyDefinition result)
	{
		result = default(HotkeyDefinition);
		if (string.IsNullOrWhiteSpace(hotkey))
		{
			return false;
		}
		string[] array = hotkey.Split('+', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
		bool ctrl = false;
		bool alt = false;
		bool shift = false;
		bool win = false;
		int? num = null;
		string[] array2 = array;
		foreach (string text in array2)
		{
			if (text.Equals("Ctrl", StringComparison.OrdinalIgnoreCase) || text.Equals("Control", StringComparison.OrdinalIgnoreCase))
			{
				ctrl = true;
				continue;
			}
			if (text.Equals("Alt", StringComparison.OrdinalIgnoreCase))
			{
				alt = true;
				continue;
			}
			if (text.Equals("Shift", StringComparison.OrdinalIgnoreCase))
			{
				shift = true;
				continue;
			}
			if (text.Equals("Win", StringComparison.OrdinalIgnoreCase) || text.Equals("Windows", StringComparison.OrdinalIgnoreCase))
			{
				win = true;
				continue;
			}
			if (_keyMap.TryGetValue(text, out var value))
			{
				num = value;
				continue;
			}
			return false;
		}
		if (!num.HasValue)
		{
			return false;
		}
		result = new HotkeyDefinition(num.Value, ctrl, alt, shift, win);
		return true;
	}

	public static string Format(HotkeyDefinition def)
	{
		List<string> list = new List<string>(5);
		if (def.Ctrl)
		{
			list.Add("Ctrl");
		}
		if (def.Alt)
		{
			list.Add("Alt");
		}
		if (def.Shift)
		{
			list.Add("Shift");
		}
		if (def.Win)
		{
			list.Add("Win");
		}
		list.Add(VkToName(def.VkCode));
		return string.Join("+", list);
	}

	private static string VkToName(int vk)
	{
		if (vk >= 65 && vk <= 90)
		{
			return ((char)vk).ToString();
		}
		if (vk >= 48 && vk <= 57)
		{
			return ((char)vk).ToString();
		}
		if (vk >= 112 && vk <= 135)
		{
			return $"F{vk - 111}";
		}
		if (vk >= 96 && vk <= 105)
		{
			return $"Num{vk - 96}";
		}
		string text = null;
		foreach (var (text3, num2) in _keyMap)
		{
			if (num2 == vk && (text == null || text3.Length > text.Length))
			{
				text = text3;
			}
		}
		return text ?? $"0x{vk:X2}";
	}
}
