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

namespace AxCopilot.Handlers;

/// <summary>
/// L17-4: .gitignore 생성기 핸들러. "gitignore" 프리픽스로 사용합니다.
///
/// 예: gitignore               → 지원 언어·프레임워크 목록
///     gitignore node          → Node.js .gitignore 생성
///     gitignore python        → Python .gitignore 생성
///     gitignore csharp        → C# / .NET .gitignore 생성
///     gitignore java          → Java .gitignore 생성
///     gitignore react         → React (Node 기반) .gitignore 생성
///     gitignore node python   → 여러 템플릿 병합
/// Enter → .gitignore 내용을 클립보드에 복사.
/// </summary>
public class GitignoreHandler : IActionHandler
{
    public string? Prefix => "gitignore";

    public PluginMetadata Metadata => new(
        "Gitignore",
        ".gitignore 생성기 — Node·Python·C#·Java·Go·Rust 등 내장 템플릿",
        "1.0",
        "AX");

    // ── 내장 템플릿 ──────────────────────────────────────────────────────────

    private static readonly Dictionary<string, (string[] Aliases, string Description, string Content)> Templates =
        new(StringComparer.OrdinalIgnoreCase)
        {
            ["node"] = (
                ["nodejs", "npm", "javascript", "js"],
                "Node.js / npm",
                """
                # Node.js
                node_modules/
                npm-debug.log*
                yarn-debug.log*
                yarn-error.log*
                pnpm-debug.log*
                .pnpm-store/
                .npm/
                .yarn/
                package-lock.json
                yarn.lock
                pnpm-lock.yaml
                .env
                .env.local
                .env.*.local
                dist/
                build/
                .cache/
                .parcel-cache/
                .vite/
                coverage/
                .nyc_output/
                *.log
                .DS_Store
                Thumbs.db
                """),

            ["python"] = (
                ["py", "django", "flask", "fastapi"],
                "Python",
                """
                # Python
                __pycache__/
                *.py[cod]
                *$py.class
                *.so
                .Python
                build/
                dist/
                eggs/
                .eggs/
                lib/
                lib64/
                parts/
                sdist/
                var/
                wheels/
                *.egg-info/
                .installed.cfg
                *.egg
                MANIFEST
                .env
                .venv
                env/
                venv/
                ENV/
                .pytest_cache/
                .mypy_cache/
                .ruff_cache/
                .coverage
                htmlcov/
                *.log
                .DS_Store
                """),

            ["csharp"] = (
                ["cs", "dotnet", ".net", "net", "aspnet", "aspnetcore"],
                "C# / .NET",
                """
                # C# / .NET
                bin/
                obj/
                *.user
                *.suo
                .vs/
                .vscode/
                *.userprefs
                *.pidb
                *.booproj
                *.svd
                *.userprefs
                packages/
                *.nupkg
                **/[Bb]in/
                **/[Oo]bj/
                **/[Ll]og/
                **/[Ll]ogs/
                TestResults/
                [Tt]est[Rr]esult*/
                BenchmarkDotNet.Artifacts/
                project.lock.json
                project.fragment.lock.json
                artifacts/
                *_i.c
                *_p.c
                *_h.h
                *.ilk
                *.meta
                *.obj
                *.iobj
                *.pch
                *.pdb
                *.ipdb
                *.pgc
                *.pgd
                *.rsp
                *.sbr
                *.tlb
                *.tli
                *.tlh
                *.tmp
                *.tmp_proj
                *_wpftmp.csproj
                *.log
                *.vspscc
                .DS_Store
                """),

            ["java"] = (
                ["gradle", "maven", "mvn", "spring"],
                "Java / Maven / Gradle",
                """
                # Java / Maven / Gradle
                *.class
                *.log
                *.ctxt
                .mtj.tmp/
                *.jar
                *.war
                *.nar
                *.ear
                *.zip
                *.tar.gz
                *.rar
                hs_err_pid*
                replay_pid*
                target/
                build/
                out/
                .gradle/
                .mvn/
                !.mvn/wrapper/maven-wrapper.jar
                !.mvn/wrapper/maven-wrapper.properties
                .idea/
                *.iws
                *.iml
                *.ipr
                .classpath
                .project
                .settings/
                .DS_Store
                """),

            ["go"] = (
                ["golang"],
                "Go (Golang)",
                """
                # Go
                *.exe
                *.exe~
                *.dll
                *.so
                *.dylib
                *.test
                *.out
                go.work
                go.work.sum
                vendor/
                .env
                dist/
                bin/
                .DS_Store
                """),

            ["rust"] = (
                ["cargo"],
                "Rust / Cargo",
                """
                # Rust / Cargo
                /target/
                Cargo.lock
                **/*.rs.bk
                *.pdb
                .env
                .DS_Store
                """),

            ["react"] = (
                ["nextjs", "next", "vue", "vite", "svelte"],
                "React / Next.js / Vue / Vite",
                """
                # React / Next.js / Vite
                node_modules/
                .next/
                out/
                build/
                dist/
                .env
                .env.local
                .env.development.local
                .env.test.local
                .env.production.local
                npm-debug.log*
                yarn-debug.log*
                yarn-error.log*
                .DS_Store
                Thumbs.db
                .cache/
                .parcel-cache/
                coverage/
                *.log
                """),

            ["flutter"] = (
                ["dart"],
                "Flutter / Dart",
                """
                # Flutter / Dart
                .dart_tool/
                .flutter-plugins
                .flutter-plugins-dependencies
                .packages
                .pub-cache/
                .pub/
                /build/
                flutter_*.png
                linked_*.ds
                unlinked.ds
                unlinked_spec.ds
                *.log
                .DS_Store
                """),

            ["android"] = (
                ["kotlin", "gradle-android"],
                "Android",
                """
                # Android
                *.iml
                .gradle/
                /local.properties
                /.idea/
                .DS_Store
                /build/
                /captures/
                .externalNativeBuild/
                .cxx/
                *.jks
                *.keystore
                google-services.json
                """),

            ["ios"] = (
                ["swift", "xcode", "objc", "objective-c"],
                "iOS / Swift / Xcode",
                """
                # iOS / Swift / Xcode
                build/
                DerivedData/
                .build/
                *.pbxuser
                *.mode1v3
                *.mode2v3
                *.perspectivev3
                xcuserdata/
                *.xcworkspace
                !default.xcworkspace
                .swiftpm/
                Packages/
                *.resolved
                *.xccheckout
                *.moved-aside
                *.xcuserstate
                .DS_Store
                """),

            ["unity"] = (
                [],
                "Unity",
                """
                # Unity
                /[Ll]ibrary/
                /[Tt]emp/
                /[Oo]bj/
                /[Bb]uild/
                /[Bb]uilds/
                /[Ll]ogs/
                /[Uu]ser[Ss]ettings/
                /[Mm]emoryCaptures/
                /[Rr]ecordings/
                /[Pp]rofiles/
                /[Pp]rofile[Ss]
                /[Aa]ssets/Plugins/EditorVR.meta
                /[Pp]ackages/
                !/[Pp]ackages/manifest.json
                !/[Pp]ackages/packages-lock.json
                /*.sln
                /*.csproj
                /.vs/
                .DS_Store
                """),

            ["windows"] = (
                ["win", "powershell", "ps"],
                "Windows 공통",
                """
                # Windows
                Thumbs.db
                Thumbs.db:encryptable
                ehthumbs.db
                ehthumbs_vista.db
                *.stackdump
                [Dd]esktop.ini
                $RECYCLE.BIN/
                *.cab
                *.msi
                *.msix
                *.msm
                *.msp
                *.lnk
                """),

            ["macos"] = (
                ["mac", "osx"],
                "macOS 공통",
                """
                # macOS
                .DS_Store
                .AppleDouble
                .LSOverride
                Icon
                ._*
                .DocumentRevisions-V100
                .fseventsd
                .Spotlight-V100
                .TemporaryItems
                .Trashes
                .VolumeIcon.icns
                .com.apple.timemachine.donotpresent
                .AppleDB
                .AppleDesktop
                Network Trash Folder
                Temporary Items
                .apdisk
                """),

            ["linux"] = (
                [],
                "Linux 공통",
                """
                # Linux
                *~
                .fuse_hidden*
                .directory
                .Trash-*
                .nfs*
                *.swp
                *.swo
                """),
        };

    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(".gitignore 생성기",
                "예: gitignore node  /  gitignore python  /  gitignore csharp  /  gitignore node python",
                null, null, Symbol: "\uEA3C"));
            items.Add(new LauncherItem($"── 지원 템플릿  {Templates.Count}개 ──", "", null, null, Symbol: "\uEA3C"));
            foreach (var (key, (aliases, desc, _)) in Templates.OrderBy(t => t.Key))
            {
                var aliasStr = aliases.Length > 0 ? $"  ({string.Join(", ", aliases.Take(3))})" : "";
                items.Add(new LauncherItem(key, $"{desc}{aliasStr}", null, ("gen", key), Symbol: "\uEA3C"));
            }
            return Task.FromResult<IEnumerable<LauncherItem>>(items);
        }

        // 여러 키워드 → 병합
        var keywords = q.Split(' ', StringSplitOptions.RemoveEmptyEntries);
        var matched  = new List<string>(); // 템플릿 키 목록

        foreach (var kw in keywords)
        {
            var found = FindTemplate(kw);
            if (found != null && !matched.Contains(found))
                matched.Add(found);
        }

        if (matched.Count == 0)
        {
            items.Add(new LauncherItem($"'{q}' 템플릿을 찾을 수 없습니다",
                $"지원: {string.Join(", ", Templates.Keys.Take(10))}…",
                null, null, Symbol: "\uE946"));
            return Task.FromResult<IEnumerable<LauncherItem>>(items);
        }

        // 템플릿 생성
        if (matched.Count == 1)
        {
            var key      = matched[0];
            var (_, desc, content) = Templates[key];
            var trimmed  = content.Trim();

            items.Add(new LauncherItem($".gitignore  [{key}]",
                $"{desc}  ·  {trimmed.Split('\n').Length}줄  · Enter → 복사",
                null, ("copy", trimmed), Symbol: "\uEA3C"));

            // 미리보기
            foreach (var line in trimmed.Split('\n').Take(12))
                items.Add(new LauncherItem(line, "", null, null, Symbol: "\uEA3C"));

            if (trimmed.Split('\n').Length > 12)
                items.Add(new LauncherItem($"… 외 {trimmed.Split('\n').Length - 12}줄",
                    "전체는 첫 항목 Enter로 복사", null, null, Symbol: "\uEA3C"));
        }
        else
        {
            // 다중 병합
            var sb       = new System.Text.StringBuilder();
            var totalLines = 0;
            foreach (var key in matched)
            {
                var (_, desc, content) = Templates[key];
                sb.AppendLine($"# ===== {desc} =====");
                sb.AppendLine(content.Trim());
                sb.AppendLine();
                totalLines += content.Split('\n').Length;
            }
            var merged = sb.ToString().TrimEnd();

            items.Add(new LauncherItem(
                $".gitignore 병합  [{string.Join(" + ", matched)}]",
                $"{totalLines}줄  · Enter → 복사",
                null, ("copy", merged), Symbol: "\uEA3C"));

            foreach (var key in matched)
            {
                var (_, desc, _) = Templates[key];
                items.Add(new LauncherItem($"[{key}]", desc, null, ("gen", key), Symbol: "\uEA3C"));
            }
        }

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

    public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
    {
        switch (item.Data)
        {
            case ("copy", string text):
                try
                {
                    System.Windows.Application.Current.Dispatcher.Invoke(
                        () => Clipboard.SetText(text));
                    NotificationService.Notify("Gitignore", ".gitignore 내용을 복사했습니다.");
                }
                catch { /* 비핵심 */ }
                break;

            case ("gen", string key):
                if (Templates.TryGetValue(key, out var t))
                {
                    try
                    {
                        System.Windows.Application.Current.Dispatcher.Invoke(
                            () => Clipboard.SetText(t.Content.Trim()));
                        NotificationService.Notify("Gitignore", $"[{key}] .gitignore 복사됨");
                    }
                    catch { /* 비핵심 */ }
                }
                break;
        }
        return Task.CompletedTask;
    }

    // ── 헬퍼 ─────────────────────────────────────────────────────────────────

    private static string? FindTemplate(string keyword)
    {
        // 직접 키 일치
        if (Templates.ContainsKey(keyword)) return keyword;

        // 별칭 검색
        foreach (var (key, (aliases, _, _)) in Templates)
        {
            if (aliases.Any(a => a.Equals(keyword, StringComparison.OrdinalIgnoreCase)))
                return key;
        }

        // 부분 일치
        var partial = Templates.Keys
            .FirstOrDefault(k => k.Contains(keyword, StringComparison.OrdinalIgnoreCase));
        return partial;
    }
}
