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

namespace AxCopilot.Handlers;

/// <summary>
/// L22-3: Python pip 명령 생성기 핸들러. "pip" 프리픽스로 사용합니다.
///
/// 예: pip                   → 자주 쓰는 명령 목록
///     pip install           → 패키지 설치 관련 명령
///     pip list              → 목록 관련 명령
///     pip venv              → 가상환경 관련 명령
///     pip conda             → conda 관련 명령
///     pip <검색어>          → 명령 검색
/// Enter → 명령어 클립보드 복사.
/// </summary>
public class PipHandler : IActionHandler
{
    public string? Prefix => "pip";

    public PluginMetadata Metadata => new(
        "pip 명령",
        "Python pip 명령 생성기 — 설치·관리·가상환경·conda",
        "1.0",
        "AX");

    private sealed record PipCmd(
        string Pip2,
        string Pip3,
        string Description,
        string Category);

    private static readonly PipCmd[] Commands =
    [
        // ── 설치 (install) ───────────────────────────────────────────────────
        new("pip install {패키지}",           "pip3 install {패키지}",          "패키지 설치",                            "install"),
        new("pip install {패키지}=={버전}",   "pip3 install {패키지}=={버전}",  "특정 버전 설치 (예: requests==2.31.0)",  "install"),
        new("pip install -r requirements.txt","pip3 install -r requirements.txt","requirements.txt 일괄 설치",            "install"),
        new("pip install --upgrade {패키지}", "pip3 install --upgrade {패키지}","패키지 업그레이드",                      "install"),
        new("pip install --upgrade pip",      "pip3 install --upgrade pip",     "pip 자체 업그레이드",                    "install"),
        new("pip install --user {패키지}",    "pip3 install --user {패키지}",   "사용자 홈에 설치 (관리자 권한 불필요)", "install"),
        new("pip install -e .",               "pip3 install -e .",              "현재 폴더 패키지를 개발 모드로 설치",    "install"),
        new("pip download {패키지}",          "pip3 download {패키지}",         "오프라인 설치를 위한 패키지 다운로드",   "install"),

        // ── 제거 (uninstall) ─────────────────────────────────────────────────
        new("pip uninstall {패키지}",         "pip3 uninstall {패키지}",        "패키지 제거",                            "uninstall"),
        new("pip uninstall -y {패키지}",      "pip3 uninstall -y {패키지}",     "확인 없이 패키지 제거",                  "uninstall"),
        new("pip uninstall -r requirements.txt -y","pip3 uninstall -r requirements.txt -y","requirements.txt 패키지 일괄 제거", "uninstall"),

        // ── 목록·정보 (list) ─────────────────────────────────────────────────
        new("pip list",                       "pip3 list",                      "설치된 패키지 목록",                     "list"),
        new("pip list --outdated",            "pip3 list --outdated",           "업데이트 가능한 패키지 목록",            "list"),
        new("pip show {패키지}",              "pip3 show {패키지}",             "패키지 상세 정보 (버전·위치·의존성)",    "list"),
        new("pip freeze",                     "pip3 freeze",                    "설치 패키지 버전 고정 출력",             "list"),
        new("pip freeze > requirements.txt",  "pip3 freeze > requirements.txt", "requirements.txt 파일 생성",             "list"),
        new("pip check",                      "pip3 check",                     "의존성 충돌 검사",                       "list"),

        // ── 검색·캐시 (search) ───────────────────────────────────────────────
        new("pip cache list",                 "pip3 cache list",                "캐시 목록 확인",                         "search"),
        new("pip cache purge",                "pip3 cache purge",               "캐시 전체 삭제",                         "search"),
        new("pip index versions {패키지}",    "pip3 index versions {패키지}",   "PyPI에서 사용 가능한 버전 목록 조회",    "search"),
        new("pip config list",                "pip3 config list",               "pip 설정 목록",                          "search"),
        new("pip config set global.index-url {URL}","pip3 config set global.index-url {URL}","사내 PyPI 미러 설정", "search"),

        // ── 가상환경 (venv) ──────────────────────────────────────────────────
        new("python -m venv .venv",           "python3 -m venv .venv",          "가상환경 생성 (.venv 폴더)",             "venv"),
        new(".venv\\Scripts\\activate",       "source .venv/bin/activate",      "가상환경 활성화 (Win / Mac·Linux)",      "venv"),
        new("deactivate",                     "deactivate",                     "가상환경 비활성화",                      "venv"),
        new("python -m venv .venv --clear",   "python3 -m venv .venv --clear",  "가상환경 초기화 (재생성)",               "venv"),
        new("pip list --local",               "pip3 list --local",              "현재 가상환경 패키지만 목록",            "venv"),
        new("python -m site --user-site",     "python3 -m site --user-site",    "사용자 패키지 설치 경로 확인",           "venv"),

        // ── conda ────────────────────────────────────────────────────────────
        new("conda create -n {환경명} python={버전}","conda create -n {환경명} python={버전}","Conda 환경 생성 (버전 지정)", "conda"),
        new("conda activate {환경명}",         "conda activate {환경명}",        "Conda 환경 활성화",                      "conda"),
        new("conda deactivate",               "conda deactivate",               "Conda 환경 비활성화",                    "conda"),
        new("conda install {패키지}",         "conda install {패키지}",         "Conda로 패키지 설치",                    "conda"),
        new("conda update {패키지}",          "conda update {패키지}",          "Conda 패키지 업데이트",                  "conda"),
        new("conda list",                     "conda list",                     "현재 Conda 환경 패키지 목록",            "conda"),
        new("conda env list",                 "conda env list",                 "전체 Conda 환경 목록",                   "conda"),
        new("conda env remove -n {환경명}",   "conda env remove -n {환경명}",   "Conda 환경 삭제",                        "conda"),
        new("conda env export > env.yml",     "conda env export > env.yml",     "환경 설정을 yml 파일로 내보내기",        "conda"),
        new("conda env create -f env.yml",    "conda env create -f env.yml",    "yml 파일로 환경 복원",                   "conda"),
    ];

    private static readonly (string Key, string[] Aliases, string Label)[] Categories =
    [
        ("install",   ["install", "설치", "add"],       "패키지 설치"),
        ("uninstall", ["uninstall", "remove", "삭제"],  "패키지 제거"),
        ("list",      ["list", "목록", "show", "freeze"],"목록·정보"),
        ("search",    ["search", "cache", "config"],    "검색·캐시·설정"),
        ("venv",      ["venv", "env", "가상환경"],       "가상환경"),
        ("conda",     ["conda", "anaconda"],             "conda"),
    ];

    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("pip 명령 생성기",
                "카테고리: install · uninstall · list · venv · conda",
                null, null, Symbol: "\uE943"));

            foreach (var (key, _, label) in Categories)
            {
                var cnt = Commands.Count(c => c.Category == key);
                items.Add(new LauncherItem($"pip {key}", $"{label}  ({cnt}개 명령)",
                    null, ("copy", $"pip {key}"), Symbol: "\uE943"));
            }
            return Task.FromResult<IEnumerable<LauncherItem>>(items);
        }

        var kw = q.ToLowerInvariant();

        // 카테고리 일치
        var cat = Categories.FirstOrDefault(c =>
            c.Aliases.Any(a => a == kw || kw.StartsWith(a + " ")));

        if (cat.Key != null)
        {
            var list = Commands.Where(c => c.Category == cat.Key).ToList();
            items.Add(new LauncherItem($"{cat.Label} 명령 {list.Count}개",
                "pip2 / pip3 모두 표시 · Enter: pip3 명령 복사", null, null, Symbol: "\uE943"));
            foreach (var c in list) items.Add(CmdItem(c));
            return Task.FromResult<IEnumerable<LauncherItem>>(items);
        }

        // 검색
        var searched = Commands.Where(c =>
            c.Pip2.Contains(kw, StringComparison.OrdinalIgnoreCase) ||
            c.Pip3.Contains(kw, StringComparison.OrdinalIgnoreCase) ||
            c.Description.Contains(kw, StringComparison.OrdinalIgnoreCase)).ToList();

        if (searched.Count == 0)
        {
            items.Add(new LauncherItem($"'{q}' 명령을 찾을 수 없습니다",
                "카테고리: install · uninstall · list · venv · conda",
                null, null, Symbol: "\uE783"));
            return Task.FromResult<IEnumerable<LauncherItem>>(items);
        }

        items.Add(new LauncherItem($"'{q}' 검색 결과 {searched.Count}개",
            "Enter: pip3 명령 복사", null, null, Symbol: "\uE943"));
        foreach (var c in searched) items.Add(CmdItem(c));

        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("pip", "클립보드에 복사했습니다.");
            }
            catch { }
        }
        return Task.CompletedTask;
    }

    private static LauncherItem CmdItem(PipCmd c)
    {
        var title = c.Pip2 == c.Pip3
            ? c.Pip3
            : $"{c.Pip3}";
        var sub   = c.Pip2 == c.Pip3
            ? c.Description
            : $"{c.Description}  |  pip2: {c.Pip2}";
        return new LauncherItem(title, sub, null, ("copy", c.Pip3), Symbol: "\uE943");
    }
}
