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

namespace AxCopilot.Handlers;

/// <summary>
/// L29-1: 오프라인 국어사전 핸들러. "dict" 프리픽스로 사용합니다.
///
/// 예: dict                → 사용법 안내
///     dict 부럽다          → "부럽다" 검색 (표제어·뜻풀이)
///     dict en hello        → 영한 사전 검색
///     dict 유의어 돕다      → 유의어 검색
/// Enter → 뜻풀이 클립보드 복사.
/// 내장 데이터 기반 (인터넷 불필요). 혼동어·유의어·반의어 중심.
/// </summary>
public class DictHandler : IActionHandler
{
    public string? Prefix => "dict";

    public PluginMetadata Metadata => new(
        "국어사전",
        "오프라인 국어·영한 사전 — 뜻풀이·유의어·혼동어",
        "1.0",
        "AX");

    // ─── 내장 국어 사전 데이터 ────────────────────────────────────────────────
    private sealed record KorEntry(string Word, string Pos, string Def, string? Synonym = null, string? Antonym = null, string? Note = null);

    private static readonly KorEntry[] KorDict =
    [
        // ── 혼동어 ────────────────────────────────────────────────────────────
        new("가르치다", "동사", "지식·기술을 알려 주다", Note: "'가리키다'와 혼동 주의. 가리키다=손가락으로 방향을 보여 주다"),
        new("가리키다", "동사", "손가락 등으로 방향이나 대상을 보여 주다", Note: "'가르치다'와 혼동 주의"),
        new("다르다",   "형용사", "비교 대상이 같지 아니하다", Synonym: "상이하다", Antonym: "같다", Note: "'틀리다'와 혼동 주의. 틀리다=옳지 않다"),
        new("틀리다",   "동사", "사실이나 이치에 맞지 아니하다, 잘못되다", Synonym: "그르다", Antonym: "맞다", Note: "'다르다'와 혼동 주의"),
        new("바라다",   "동사", "생각대로 되기를 기대하다", Note: "'바래다(햇볕에 색이 변하다)'와 혼동 주의"),
        new("바래다",   "동사", "1. 햇볕·비에 색이 변하다  2. 어떤 곳까지 배웅하다"),
        new("늘이다",   "동사", "길이를 길게 하다 (고무줄을 늘이다)", Note: "'늘리다'와 혼동 주의. 늘리다=수량·범위를 크게 하다"),
        new("늘리다",   "동사", "수량·범위·세력을 크게 하다 (매출을 늘리다)", Note: "'늘이다'와 혼동 주의. 늘이다=길이를 길게 하다"),
        new("부치다",   "동사", "1. 편지를 보내다  2. 부침개를 만들다  3. 세금을 매기다"),
        new("붙이다",   "동사", "1. 떨어지지 않게 접합하다  2. 이름을 정하다  3. 조건을 달다"),
        new("맞추다",   "동사", "1. 서로 대어 비교하다  2. 정답을 알아 내다", Note: "'맞히다(맞다의 사동사)'와 혼동 주의"),
        new("맞히다",   "동사", "'맞다'의 사동사. 1. 적중시키다  2. 정답을 고르게 하다"),
        new("받치다",   "동사", "1. 밑에서 떠받치다  2. 감정이 치밀다", Note: "'바치다(드리다)'와 혼동 주의"),
        new("바치다",   "동사", "웃어른에게 물건이나 정성을 드리다"),
        new("반듯이",   "부사", "모양이 기울거나 비뚤어지지 않게", Note: "'반드시'와 혼동 주의"),
        new("반드시",   "부사", "틀림없이, 꼭", Synonym: "기필코, 필히"),
        new("어이없다", "형용사", "뜻밖에 기가 막혀 말이 나오지 않다", Note: "'어의(御醫)없다'가 아님"),
        new("설레다",   "동사", "마음이 가라앉지 아니하고 들뜨다", Note: "'설레이다'는 비표준"),
        new("깨끗이",   "부사", "깨끗하게", Note: "'-이'로 적음 (깨끗히 ×)"),
        new("일찍이",   "부사", "일찍", Note: "'-이'로 적음 (일찍히 ×)"),

        // ── 업무 용어 ─────────────────────────────────────────────────────────
        new("품의",     "명사", "윗사람에게 어떤 일의 처리를 의논하여 품함"),
        new("결재",     "명사", "윗사람이 아랫사람이 제출한 안건을 승인함", Note: "'결제(대금 지불)'와 혼동 주의"),
        new("결제",     "명사", "대금을 주고받아 거래를 끝맺음", Note: "'결재(승인)'와 혼동 주의"),
        new("수립",     "명사", "계획이나 정책을 세움", Synonym: "설정, 설립"),
        new("이관",     "명사", "관할이나 담당을 다른 곳으로 옮김"),
        new("선결",     "명사", "다른 것보다 앞서 먼저 해결함"),
        new("귀결",     "명사", "어떤 결론에 다다름"),
        new("전결",     "명사", "위임을 받아 대신 결재함"),
        new("대조",     "명사", "둘 이상을 맞대어 비교함", Synonym: "비교"),
        new("취합",     "명사", "여러 곳의 자료를 모아서 합침", Synonym: "수합"),
        new("회람",     "명사", "문서를 여러 사람이 돌려 봄"),
        new("시달",     "명사", "상급 기관이 하급 기관에 지시를 내림"),
        new("협조",     "명사", "힘을 합하여 도움", Synonym: "협력"),
        new("검토",     "명사", "자세히 살펴서 따져 봄", Synonym: "심사, 분석"),
        new("조율",     "명사", "서로 다른 의견을 맞추어 조정함", Synonym: "조정"),
        new("후속",     "명사", "앞에 한 일의 뒤를 이음"),
        new("단축",     "명사", "시간·거리를 줄임", Antonym: "연장"),
        new("지양",     "명사", "바람직하지 않은 것을 피하거나 그만둠", Note: "'지향(나아감)'과 혼동 주의"),
        new("지향",     "명사", "목표를 향하여 나아감", Note: "'지양(피함)'과 혼동 주의"),

        // ── 자주 헷갈리는 한자어 ──────────────────────────────────────────────
        new("이상",     "명사", "1. 보통 정도를 넘어선 상태 (以上)  2. 생각하는 것 중 가장 완전한 상태 (理想)"),
        new("이하",     "명사", "기준이 되는 정도에 미치지 못하는 상태", Antonym: "이상(以上)"),
        new("과반",     "명사", "절반을 넘는 수"),
        new("역할",     "명사", "자기가 마땅히 하여야 할 임무나 직책", Note: "'역활'은 비표준"),
        new("요지",     "명사", "중요한 내용의 핵심", Synonym: "골자, 핵심"),
        new("명시",     "명사", "분명하게 드러내어 보임"),
        new("고지",     "명사", "1. 알려 줌  2. 높은 곳의 땅"),
        new("기한",     "명사", "미리 정해 놓은 시한", Synonym: "시한, 마감"),
    ];

    // ─── 내장 영한 사전 데이터 (업무 필수 영어) ────────────────────────────────
    private sealed record EngEntry(string Word, string Pos, string Kor, string? Example = null);

    private static readonly EngEntry[] EngDict =
    [
        new("agenda",      "명사", "의제, 안건",               "Let's move to the next agenda item."),
        new("align",       "동사", "맞추다, 조율하다",          "We need to align our goals."),
        new("approve",     "동사", "승인하다",                  "The manager approved the budget."),
        new("assign",      "동사", "배정하다, 할당하다",        "I'll assign this task to you."),
        new("brief",       "동사", "간략히 보고하다",           "Can you brief me on the project?"),
        new("deadline",    "명사", "마감일, 기한",              "The deadline is next Friday."),
        new("delegate",    "동사", "위임하다",                  "You should delegate this to the team."),
        new("deploy",      "동사", "배포하다, 배치하다",        "We'll deploy the update tonight."),
        new("escalate",    "동사", "상부에 보고하다, 확대하다",  "Let's escalate this issue."),
        new("feasible",    "형용사","실현 가능한",              "Is this plan feasible?"),
        new("follow-up",   "명사", "후속 조치",                 "I'll send a follow-up email."),
        new("implement",   "동사", "구현하다, 시행하다",        "We need to implement this feature."),
        new("initiative",  "명사", "주도적 행동, 계획",         "This is a company-wide initiative."),
        new("milestone",   "명사", "중요 시점, 이정표",         "We've reached a major milestone."),
        new("onboard",     "동사", "입사시키다, 적응시키다",    "We'll onboard new hires next week."),
        new("optimize",    "동사", "최적화하다",                "Let's optimize the workflow."),
        new("prioritize",  "동사", "우선순위를 정하다",         "We need to prioritize these tasks."),
        new("provisional", "형용사","잠정적인, 임시의",         "This is a provisional plan."),
        new("regarding",   "전치사","~에 관하여",               "Regarding your request..."),
        new("scope",       "명사", "범위",                      "This is out of scope."),
        new("stakeholder", "명사", "이해관계자",                "All stakeholders should attend."),
        new("sync",        "동사", "동기화하다, 맞추다",        "Let's sync on this topic."),
        new("tentative",   "형용사","잠정적인, 시험적인",       "This is a tentative schedule."),
        new("throughput",  "명사", "처리량",                    "We need to improve throughput."),
        new("viable",      "형용사","실행 가능한",              "Is this a viable option?"),
    ];

    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("국어·영한 사전",
                $"국어 {KorDict.Length}개 · 영한 {EngDict.Length}개 · dict {{단어}} / dict en {{word}}",
                null, null, Symbol: "\uE82D"));
            return Task.FromResult<IEnumerable<LauncherItem>>(items);
        }

        // ── 영한 사전 ─────────────────────────────────────────────────────────
        if (q.StartsWith("en ", StringComparison.OrdinalIgnoreCase))
        {
            var word = q[3..].Trim().ToLowerInvariant();
            if (string.IsNullOrWhiteSpace(word))
            {
                items.Add(new LauncherItem("dict en {영단어}", "예: dict en deadline", null, null, Symbol: "\uE774"));
                return Task.FromResult<IEnumerable<LauncherItem>>(items);
            }

            var found = EngDict.Where(e => e.Word.Contains(word, StringComparison.OrdinalIgnoreCase)).ToList();
            if (found.Count == 0)
            {
                items.Add(new LauncherItem($"'{word}' 검색 결과 없음",
                    "내장 업무 영어 사전에 없는 단어입니다", null, null, Symbol: "\uE783"));
            }
            else
            {
                foreach (var e in found)
                {
                    var sub = $"[{e.Pos}] {e.Kor}";
                    if (e.Example != null) sub += $"  ·  {e.Example}";
                    items.Add(new LauncherItem(e.Word, sub, null, ("copy", $"{e.Word}: {e.Kor}"), Symbol: "\uE774"));
                }
            }
            return Task.FromResult<IEnumerable<LauncherItem>>(items);
        }

        // ── 국어 사전 검색 ────────────────────────────────────────────────────
        var kw = q;
        var results = KorDict.Where(e =>
            e.Word.Contains(kw, StringComparison.OrdinalIgnoreCase) ||
            e.Def.Contains(kw, StringComparison.OrdinalIgnoreCase) ||
            (e.Synonym?.Contains(kw, StringComparison.OrdinalIgnoreCase) ?? false) ||
            (e.Note?.Contains(kw, StringComparison.OrdinalIgnoreCase) ?? false)).ToList();

        if (results.Count == 0)
        {
            items.Add(new LauncherItem($"'{kw}' 검색 결과 없음",
                "내장 국어 사전에 없는 단어입니다", null, null, Symbol: "\uE783"));
        }
        else
        {
            foreach (var e in results.Take(12))
            {
                var title = $"{e.Word}  [{e.Pos}]";
                var sub = e.Def;
                if (e.Synonym != null) sub += $"  ·  유의어: {e.Synonym}";
                if (e.Antonym != null) sub += $"  ·  반의어: {e.Antonym}";
                if (e.Note != null) sub += $"  ·  💡 {e.Note}";
                items.Add(new LauncherItem(title, sub, null, ("copy", $"{e.Word}: {e.Def}"), Symbol: "\uE82D"));
            }
        }

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

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