using System.Windows;
using AxCopilot.SDK;
using AxCopilot.Services;
using AxCopilot.Themes;

namespace AxCopilot.Handlers;

/// <summary>
/// L21-4: 키보드 단축키 참조 사전 핸들러. "key" 프리픽스로 사용합니다.
///
/// 예: key                    → 앱 카테고리 목록
///     key win                → Windows 단축키
///     key vscode             → VS Code 단축키
///     key chrome             → Chrome/Edge 단축키
///     key vim                → Vim 명령
///     key excel              → Excel 단축키
///     key terminal           → Windows Terminal 단축키
///     key <키워드>           → 전체 단축키에서 키워드 검색 (예: key 찾기, key find)
/// Enter → 단축키 복사.
/// </summary>
public class KeyHandler : IActionHandler
{
    public string? Prefix => "key";

    public PluginMetadata Metadata => new(
        "Key",
        "키보드 단축키 참조 사전 — Windows·VS Code·Chrome·Vim·Excel",
        "1.0",
        "AX");

    private record Shortcut(string Keys, string Description, string App);

    private static readonly Shortcut[] All =
    [
        // Windows
        new("Win + D",          "바탕화면 보기/복원",                  "win"),
        new("Win + E",          "파일 탐색기 열기",                    "win"),
        new("Win + L",          "PC 잠금",                             "win"),
        new("Win + R",          "실행 대화상자",                       "win"),
        new("Win + S",          "Windows 검색",                        "win"),
        new("Win + V",          "클립보드 히스토리",                   "win"),
        new("Win + X",          "빠른 링크 메뉴 (전원 메뉴)",          "win"),
        new("Win + Tab",        "작업 보기(가상 데스크톱)",             "win"),
        new("Win + Ctrl + D",   "새 가상 데스크톱 추가",               "win"),
        new("Win + Ctrl + →/←", "가상 데스크톱 전환",                  "win"),
        new("Win + ↑",          "창 최대화",                           "win"),
        new("Win + ↓",          "창 최소화/복원",                      "win"),
        new("Win + ←/→",        "창 좌/우 절반 스냅",                  "win"),
        new("Win + Shift + S",  "화면 부분 캡처 (Snipping Tool)",      "win"),
        new("Alt + Tab",        "실행 중인 앱 전환",                   "win"),
        new("Alt + F4",         "현재 창 닫기",                        "win"),
        new("Ctrl + Shift + Esc", "작업 관리자 직접 열기",             "win"),
        new("Ctrl + Alt + Del", "보안 옵션 화면",                      "win"),
        new("F2",               "선택 항목 이름 변경",                 "win"),
        new("F5",               "새로고침",                            "win"),
        new("F11",              "전체화면 토글",                       "win"),
        new("Win + . (점)",     "이모지 피커",                         "win"),
        new("Win + P",          "프로젝션 모드 선택 (다중 모니터)",    "win"),
        new("Win + I",          "Windows 설정",                        "win"),
        new("PrtSc",            "전체 화면 캡처 → 클립보드",           "win"),
        new("Alt + PrtSc",      "현재 창 캡처 → 클립보드",             "win"),

        // VS Code
        new("Ctrl + P",         "파일 빠른 열기",                      "vscode"),
        new("Ctrl + Shift + P", "명령 팔레트",                         "vscode"),
        new("Ctrl + `",         "통합 터미널 열기/닫기",               "vscode"),
        new("Ctrl + B",         "사이드바 토글",                       "vscode"),
        new("Ctrl + J",         "패널 토글(터미널·출력)",              "vscode"),
        new("Ctrl + F",         "파일 내 찾기",                        "vscode"),
        new("Ctrl + H",         "파일 내 찾아 바꾸기",                 "vscode"),
        new("Ctrl + Shift + F", "전체 검색",                           "vscode"),
        new("Ctrl + Shift + H", "전체 찾아 바꾸기",                    "vscode"),
        new("Ctrl + G",         "줄 이동",                             "vscode"),
        new("Ctrl + /",         "줄 주석 토글",                        "vscode"),
        new("Alt + ↑/↓",        "현재 줄 위/아래 이동",               "vscode"),
        new("Alt + Shift + ↑/↓","현재 줄 위/아래 복사",               "vscode"),
        new("Ctrl + D",         "다음 동일 단어 선택",                 "vscode"),
        new("Ctrl + Shift + L", "동일 단어 모두 선택",                 "vscode"),
        new("Ctrl + Shift + K", "현재 줄 삭제",                        "vscode"),
        new("Ctrl + Enter",     "아래에 새 줄 추가",                   "vscode"),
        new("Ctrl + Shift + Enter", "위에 새 줄 추가",                 "vscode"),
        new("F12",              "정의로 이동",                         "vscode"),
        new("Alt + F12",        "정의 미리보기",                       "vscode"),
        new("Shift + F12",      "모든 참조 찾기",                      "vscode"),
        new("F2",               "기호 이름 변경(리팩터링)",             "vscode"),
        new("Ctrl + .",         "빠른 수정 (Quick Fix)",               "vscode"),
        new("Ctrl + K Ctrl + F","선택 영역 포맷",                      "vscode"),
        new("Shift + Alt + F",  "전체 파일 포맷",                      "vscode"),
        new("Ctrl + Z / Y",     "실행 취소 / 다시 실행",               "vscode"),
        new("Ctrl + W",         "현재 탭 닫기",                        "vscode"),
        new("Ctrl + Tab",       "에디터 탭 전환",                      "vscode"),
        new("Ctrl + \\",        "에디터 분할",                         "vscode"),
        new("Ctrl + 1/2/3",     "에디터 그룹 포커스",                  "vscode"),

        // Chrome / Edge
        new("Ctrl + T",         "새 탭 열기",                          "chrome"),
        new("Ctrl + W",         "현재 탭 닫기",                        "chrome"),
        new("Ctrl + Shift + T", "닫은 탭 다시 열기",                   "chrome"),
        new("Ctrl + Tab",       "다음 탭으로 이동",                    "chrome"),
        new("Ctrl + Shift + Tab","이전 탭으로 이동",                   "chrome"),
        new("Ctrl + 1~8",       "번호로 탭 이동",                      "chrome"),
        new("Ctrl + L",         "주소창 포커스",                       "chrome"),
        new("Ctrl + D",         "현재 페이지 북마크",                  "chrome"),
        new("Ctrl + F",         "페이지 내 찾기",                      "chrome"),
        new("Ctrl + H",         "방문 기록",                           "chrome"),
        new("Ctrl + J",         "다운로드 목록",                       "chrome"),
        new("Ctrl + Shift + J", "개발자 도구 콘솔",                    "chrome"),
        new("F12",              "개발자 도구 토글",                    "chrome"),
        new("F5 / Ctrl + R",    "페이지 새로고침",                     "chrome"),
        new("Ctrl + Shift + R", "캐시 무시 새로고침",                  "chrome"),
        new("Ctrl + +/-",       "페이지 확대/축소",                    "chrome"),
        new("Ctrl + 0",         "확대/축소 기본값 복원",               "chrome"),
        new("Alt + ← / →",      "뒤로/앞으로",                         "chrome"),
        new("Ctrl + N",         "새 창 열기",                          "chrome"),
        new("Ctrl + Shift + N", "시크릿 창",                           "chrome"),
        new("Ctrl + Shift + B", "북마크 바 토글",                      "chrome"),
        new("Ctrl + U",         "페이지 소스 보기",                    "chrome"),

        // Vim
        new("i",                "삽입 모드 진입",                      "vim"),
        new("Esc",              "노멀 모드로 복귀",                    "vim"),
        new(":w",               "저장",                                "vim"),
        new(":q",               "종료",                                "vim"),
        new(":wq / :x",         "저장 후 종료",                        "vim"),
        new(":q!",              "저장 없이 강제 종료",                 "vim"),
        new("h/j/k/l",          "좌/하/상/우 이동",                    "vim"),
        new("w / b",            "단어 앞/뒤로 이동",                   "vim"),
        new("gg / G",           "파일 처음 / 끝으로 이동",             "vim"),
        new("0 / $",            "줄 처음 / 끝으로 이동",               "vim"),
        new("dd",               "현재 줄 삭제",                        "vim"),
        new("yy",               "현재 줄 복사(yank)",                  "vim"),
        new("p / P",            "붙여넣기 (다음/현재 위치)",            "vim"),
        new("u / Ctrl + R",     "실행 취소 / 다시 실행",               "vim"),
        new("/keyword",         "앞으로 검색",                         "vim"),
        new("n / N",            "다음/이전 검색 결과",                 "vim"),
        new(":%s/old/new/g",    "전체 치환",                           "vim"),
        new("v / V",            "비주얼 모드 (문자/줄)",               "vim"),
        new("Ctrl + V",         "비주얼 블록 모드",                    "vim"),
        new(":split / :vsplit",  "수평/수직 창 분할",                   "vim"),
        new("Ctrl + W + W",     "다음 창으로 포커스 이동",             "vim"),
        new(":noh",             "검색 하이라이트 제거",                "vim"),
        new(">>  / <<",         "들여쓰기 추가/제거",                  "vim"),

        // Excel
        new("Ctrl + Arrow",     "데이터 끝으로 이동",                  "excel"),
        new("Ctrl + Shift + Arrow","데이터 끝까지 선택",               "excel"),
        new("Ctrl + Home / End","셀 A1 / 마지막 셀로 이동",            "excel"),
        new("Ctrl + Space",     "열 전체 선택",                        "excel"),
        new("Shift + Space",    "행 전체 선택",                        "excel"),
        new("Ctrl + Shift + +", "행/열 삽입",                          "excel"),
        new("Ctrl + -",         "행/열 삭제",                          "excel"),
        new("Ctrl + D",         "아래로 채우기",                       "excel"),
        new("Ctrl + R",         "오른쪽으로 채우기",                   "excel"),
        new("Alt + =",          "SUM 자동 합계",                       "excel"),
        new("F4",               "참조 절대/상대 전환 ($)",             "excel"),
        new("Ctrl + 1",         "셀 서식 창",                          "excel"),
        new("Ctrl + ;",         "현재 날짜 입력",                      "excel"),
        new("Ctrl + Shift + ;", "현재 시간 입력",                      "excel"),
        new("F2",               "셀 편집 모드",                        "excel"),
        new("Alt + Enter",      "셀 내 줄바꿈",                        "excel"),
        new("Ctrl + Z / Y",     "실행 취소 / 다시 실행",               "excel"),
        new("Ctrl + F",         "찾기",                                "excel"),
        new("Ctrl + H",         "찾아 바꾸기",                         "excel"),
        new("Ctrl + Shift + L", "필터 자동 설정 토글",                 "excel"),

        // Windows Terminal
        new("Ctrl + Shift + T", "새 탭 열기",                          "terminal"),
        new("Ctrl + Shift + W", "탭 닫기",                             "terminal"),
        new("Ctrl + Tab",       "다음 탭 이동",                        "terminal"),
        new("Ctrl + Shift + 1~9","번호 탭으로 이동",                   "terminal"),
        new("Ctrl + Shift + D", "창 복제",                             "terminal"),
        new("Alt + Shift + D",  "창 분할 (자동 방향)",                 "terminal"),
        new("Alt + Shift + +",  "수평 분할",                           "terminal"),
        new("Alt + Shift + -",  "수직 분할",                           "terminal"),
        new("Alt + Arrow",      "분할된 창 간 포커스 이동",            "terminal"),
        new("Ctrl + +/-",       "폰트 크기 변경",                      "terminal"),
        new("Ctrl + F",         "터미널 내 텍스트 검색",               "terminal"),
        new("Ctrl + Shift + P", "명령 팔레트",                         "terminal"),
        new("Ctrl + Shift + F", "전체 화면 토글",                      "terminal"),

        // Word
        new("Ctrl + B",         "굵게",                                "word"),
        new("Ctrl + I",         "기울임꼴",                            "word"),
        new("Ctrl + U",         "밑줄",                                "word"),
        new("Ctrl + Z",         "실행 취소",                           "word"),
        new("Ctrl + Y",         "다시 실행",                           "word"),
        new("Ctrl + S",         "저장",                                "word"),
        new("Ctrl + P",         "인쇄",                                "word"),
        new("Ctrl + F",         "찾기",                                "word"),
        new("Ctrl + H",         "찾아 바꾸기",                         "word"),
        new("Ctrl + A",         "전체 선택",                           "word"),
        new("Ctrl + C / X / V", "복사 / 잘라내기 / 붙여넣기",          "word"),
        new("Ctrl + K",         "하이퍼링크 삽입",                     "word"),
        new("Ctrl + Enter",     "페이지 나누기 삽입",                  "word"),
        new("Alt + Shift + D",  "현재 날짜 삽입",                      "word"),
        new("Ctrl + Shift + >/<","글꼴 크기 늘리기/줄이기",            "word"),
        new("Ctrl + ]  / [",    "글꼴 크기 +1 / -1",                   "word"),
        new("Ctrl + L/E/R/J",   "왼쪽/가운데/오른쪽/양쪽 정렬",       "word"),
        new("Ctrl + 1 / 2 / 5", "줄 간격 1 / 2 / 1.5배",              "word"),
        new("Ctrl + Alt + 1/2/3","제목1 / 제목2 / 제목3 스타일",       "word"),
        new("Ctrl + Shift + N", "기본 스타일 적용",                    "word"),
        new("F7",               "맞춤법 및 문법 검사",                 "word"),
        new("Ctrl + Shift + C", "서식 복사",                           "word"),
        new("Ctrl + Shift + V", "서식 붙여넣기",                       "word"),
        new("Shift + F3",       "대/소문자 전환",                      "word"),
        new("Ctrl + Home / End","문서 처음 / 끝으로 이동",             "word"),

        // PowerPoint
        new("F5",               "처음부터 슬라이드 쇼 시작",           "ppt"),
        new("Shift + F5",       "현재 슬라이드부터 시작",              "ppt"),
        new("Esc",              "슬라이드 쇼 종료",                    "ppt"),
        new("B",                "슬라이드 쇼 중 화면 검정",            "ppt"),
        new("W",                "슬라이드 쇼 중 화면 흰색",            "ppt"),
        new("Ctrl + M",         "새 슬라이드 삽입",                    "ppt"),
        new("Ctrl + D",         "슬라이드 복제",                       "ppt"),
        new("Ctrl + Z / Y",     "실행 취소 / 다시 실행",               "ppt"),
        new("Ctrl + S",         "저장",                                "ppt"),
        new("Ctrl + G",         "개체 그룹화",                         "ppt"),
        new("Ctrl + Shift + G", "그룹 해제",                           "ppt"),
        new("Tab",              "다음 개체로 포커스 이동",             "ppt"),
        new("Shift + Tab",      "이전 개체로 포커스 이동",             "ppt"),
        new("Ctrl + A",         "모든 개체 선택",                      "ppt"),
        new("Alt + Shift + ←/→","슬라이드 내 개체 정렬 (왼쪽/오른쪽)","ppt"),
        new("Ctrl + Shift + >/<","글꼴 크기 늘리기/줄이기",            "ppt"),
        new("Arrow Keys",       "슬라이드 쇼 중 다음/이전",           "ppt"),
        new("숫자 + Enter",     "슬라이드 쇼 중 특정 슬라이드로 이동", "ppt"),

        // Teams
        new("Ctrl + E",         "검색창 포커스",                       "teams"),
        new("Ctrl + /",         "명령 팔레트 열기",                    "teams"),
        new("Ctrl + N",         "새 채팅 시작",                        "teams"),
        new("Ctrl + Shift + M", "오디오 뮤트 토글",                    "teams"),
        new("Ctrl + Shift + O", "비디오 카메라 토글",                  "teams"),
        new("Ctrl + Shift + H", "회의 종료",                           "teams"),
        new("Ctrl + Shift + K", "손 들기/내리기",                      "teams"),
        new("Ctrl + Shift + B", "배경 흐림 토글",                      "teams"),
        new("Ctrl + Shift + F", "전체 화면 토글",                      "teams"),
        new("Ctrl + Shift + A", "팀 활동 피드 열기",                   "teams"),
        new("Ctrl + 1",         "활동 탭",                             "teams"),
        new("Ctrl + 2",         "채팅 탭",                             "teams"),
        new("Ctrl + 3",         "팀 탭",                               "teams"),
        new("Ctrl + 4",         "캘린더 탭",                           "teams"),
        new("Ctrl + 5",         "통화 탭",                             "teams"),
        new("Alt + ↑/↓",        "채널 목록 위/아래 이동",              "teams"),
        new("Ctrl + R",         "메시지에 답장",                       "teams"),
        new("Enter",            "회의 참가 (알림에서)",                "teams"),

        // Outlook
        new("Ctrl + N",         "새 이메일 작성",                      "outlook"),
        new("Ctrl + R",         "답장",                                "outlook"),
        new("Ctrl + Shift + R", "전체 답장",                           "outlook"),
        new("Ctrl + F",         "이메일 전달",                         "outlook"),
        new("Ctrl + Enter",     "이메일 전송",                         "outlook"),
        new("Ctrl + S",         "초안 저장",                           "outlook"),
        new("Delete",           "이메일 삭제",                         "outlook"),
        new("Ctrl + Z",         "실행 취소",                           "outlook"),
        new("Ctrl + 1",         "메일 보기",                           "outlook"),
        new("Ctrl + 2",         "일정 보기",                           "outlook"),
        new("Ctrl + 3",         "연락처 보기",                         "outlook"),
        new("Ctrl + 4",         "작업 보기",                           "outlook"),
        new("F9",               "모든 계정 보내기/받기",               "outlook"),
        new("Ctrl + Shift + I", "받은 편지함으로 이동",                "outlook"),
        new("Ctrl + Shift + V", "이메일 이동",                         "outlook"),
        new("Ctrl + Shift + G", "플래그 설정",                         "outlook"),
        new("Ctrl + Q",         "읽음 표시",                           "outlook"),
        new("Ctrl + U",         "읽지 않음 표시",                      "outlook"),
        new("Ctrl + Shift + J", "정크 메일 처리",                      "outlook"),
        new("Ctrl + K",         "이름 확인 (주소 자동 완성)",          "outlook"),
        new("Alt + S",          "이메일 보내기",                       "outlook"),
    ];

    public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
    {
        var q     = query.Trim();
        var items = new List<LauncherItem>();

        if (string.IsNullOrWhiteSpace(q))
        {
            items.Add(new LauncherItem("키보드 단축키 참조 사전",
                "key win / vscode / chrome / vim / excel / terminal / word / ppt / teams / outlook  /  key <키워드 검색>",
                null, null, Symbol: "\uE92E"));
            AddAppOverview(items);
            return Task.FromResult<IEnumerable<LauncherItem>>(items);
        }

        var parts = q.Split(' ', StringSplitOptions.RemoveEmptyEntries);
        var sub   = parts[0].ToLowerInvariant();

        // 앱 카테고리 조회
        var catKeys = new Dictionary<string, string[]>
        {
            ["win"]      = ["win", "windows"],
            ["vscode"]   = ["vscode", "code", "vs"],
            ["chrome"]   = ["chrome", "edge", "browser"],
            ["vim"]      = ["vim", "vi", "neovim"],
            ["excel"]    = ["excel", "spreadsheet"],
            ["terminal"] = ["terminal", "wt"],
            ["word"]     = ["word", "워드"],
            ["ppt"]      = ["ppt", "powerpoint", "파워포인트", "프레젠테이션"],
            ["teams"]    = ["teams", "팀즈"],
            ["outlook"]  = ["outlook", "아웃룩", "mail"],
        };

        foreach (var (cat, aliases) in catKeys)
        {
            if (aliases.Contains(sub))
            {
                var catItems = All.Where(s => s.App == cat).ToList();
                var catName  = cat switch
                {
                    "win"      => "Windows",
                    "vscode"   => "VS Code",
                    "chrome"   => "Chrome / Edge",
                    "vim"      => "Vim",
                    "excel"    => "Excel",
                    "terminal" => "Windows Terminal",
                    "word"     => "Word",
                    "ppt"      => "PowerPoint",
                    "teams"    => "Teams",
                    "outlook"  => "Outlook",
                    _          => cat
                };
                items.Add(new LauncherItem($"{catName} 단축키  {catItems.Count}개", "", null, null, Symbol: "\uE92E"));
                foreach (var s in catItems)
                    items.Add(new LauncherItem(s.Keys, s.Description, null, ("copy", s.Keys), Symbol: "\uE92E"));
                return Task.FromResult<IEnumerable<LauncherItem>>(items);
            }
        }

        // 키워드 검색 (전체)
        var keyword = string.Join(" ", parts);
        var found   = All.Where(s =>
            s.Keys.Contains(keyword, StringComparison.OrdinalIgnoreCase) ||
            s.Description.Contains(keyword, StringComparison.OrdinalIgnoreCase)).ToList();

        if (found.Count > 0)
        {
            items.Add(new LauncherItem($"'{keyword}' 검색 결과: {found.Count}개", "", null, null, Symbol: "\uE92E"));
            foreach (var s in found)
            {
                var appLabel = s.App.ToUpperInvariant();
                items.Add(new LauncherItem(s.Keys, $"[{appLabel}]  {s.Description}",
                    null, ("copy", s.Keys), Symbol: "\uE92E"));
            }
        }
        else
        {
            items.Add(new LauncherItem($"'{keyword}' 결과 없음",
                "key win / vscode / chrome / vim / excel / terminal / word / ppt / teams / outlook",
                null, null, Symbol: "\uE783"));
            AddAppOverview(items);
        }

        return Task.FromResult<IEnumerable<LauncherItem>>(items);
    }

    public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
    {
        if (item.Data is ("copy", string text))
        {
            try
            {
                System.Windows.Application.Current.Dispatcher.Invoke(
                    () => Clipboard.SetText(text));
                NotificationService.Notify("Key", "클립보드에 복사했습니다.");
            }
            catch { }
        }
        return Task.CompletedTask;
    }

    private static void AddAppOverview(List<LauncherItem> items)
    {
        var apps = new (string Key, string Label, int Count)[]
        {
            ("win",      "Windows 단축키",          All.Count(s => s.App == "win")),
            ("vscode",   "VS Code 단축키",           All.Count(s => s.App == "vscode")),
            ("chrome",   "Chrome / Edge 단축키",     All.Count(s => s.App == "chrome")),
            ("vim",      "Vim 명령",                 All.Count(s => s.App == "vim")),
            ("excel",    "Excel 단축키",             All.Count(s => s.App == "excel")),
            ("terminal", "Windows Terminal 단축키",  All.Count(s => s.App == "terminal")),
            ("word",     "Word 단축키",              All.Count(s => s.App == "word")),
            ("ppt",      "PowerPoint 단축키",        All.Count(s => s.App == "ppt")),
            ("teams",    "Teams 단축키",             All.Count(s => s.App == "teams")),
            ("outlook",  "Outlook 단축키",           All.Count(s => s.App == "outlook")),
        };
        foreach (var (key, label, count) in apps)
            items.Add(new LauncherItem($"key {key}", $"{label}  ({count}개)",
                null, null, Symbol: "\uE92E"));
    }
}
