using System.Text.Json;
using System.Windows;
using AxCopilot.SDK;
using AxCopilot.Themes;

namespace AxCopilot.Handlers;

/// <summary>
/// JSON 검증/포맷 핸들러. "json" 프리픽스로 사용합니다.
/// 예: json           → 클립보드의 JSON을 파싱하여 미리보기 표시
///     json {"a":1}   → 인라인 JSON 파싱 + 미리보기
///     json minify    → 클립보드 JSON 미니파이 → 클립보드 복사
///     json format    → 클립보드 JSON 예쁘게 포맷 → 클립보드 복사
/// </summary>
public class JsonHandler : IActionHandler
{
    public string? Prefix => "json";

    public PluginMetadata Metadata => new(
        "JsonFormatter",
        "JSON 검증/포맷 — json 뒤에 내용 또는 명령 입력",
        "1.0",
        "AX");

    private static readonly JsonSerializerOptions _prettyOpts = new() { WriteIndented = true };
    private static readonly JsonSerializerOptions _compactOpts = new() { WriteIndented = false };

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

        // ─── 빈 쿼리 or format/minify: 클립보드에서 JSON 읽기 ─────────────────
        if (string.IsNullOrWhiteSpace(q) || q.Equals("format", StringComparison.OrdinalIgnoreCase)
                                         || q.Equals("minify", StringComparison.OrdinalIgnoreCase)
                                         || q.Equals("min", StringComparison.OrdinalIgnoreCase))
        {
            string clipText = "";
            try { clipText = Clipboard.GetText(); } catch (Exception) { }

            if (string.IsNullOrWhiteSpace(clipText))
                return Task.FromResult<IEnumerable<LauncherItem>>(
                [
                    new LauncherItem(
                        "클립보드가 비어 있습니다",
                        "클립보드에 JSON 텍스트를 복사한 뒤 실행하세요",
                        null, null, Symbol: Symbols.Clipboard)
                ]);

            return Task.FromResult(BuildItems(clipText,
                isMinify: q.StartsWith("min", StringComparison.OrdinalIgnoreCase)));
        }

        // ─── 인라인 JSON ──────────────────────────────────────────────────────
        return Task.FromResult(BuildItems(q, isMinify: false));
    }

    private static IEnumerable<LauncherItem> BuildItems(string input, bool isMinify)
    {
        try
        {
            using var doc = JsonDocument.Parse(input, new JsonDocumentOptions
            {
                AllowTrailingCommas = true,
                CommentHandling = JsonCommentHandling.Skip
            });

            // 포맷된 버전
            var pretty = JsonSerializer.Serialize(doc.RootElement, _prettyOpts);
            var compact = JsonSerializer.Serialize(doc.RootElement, _compactOpts);

            // 루트 타입 정보
            var rootType = doc.RootElement.ValueKind switch
            {
                JsonValueKind.Object => $"Object ({doc.RootElement.EnumerateObject().Count()}개 키)",
                JsonValueKind.Array  => $"Array ({doc.RootElement.GetArrayLength()}개 항목)",
                _                   => doc.RootElement.ValueKind.ToString()
            };

            var targetText = isMinify ? compact : pretty;
            var actionLabel = isMinify ? "미니파이" : "포맷";

            // 미리보기 (처음 100자)
            var preview = compact.Length > 100 ? compact[..97] + "…" : compact;

            return
            [
                new LauncherItem(
                    $"✅ 유효한 JSON — {rootType}",
                    $"{preview}  ·  Enter로 {actionLabel} 결과 클립보드 복사",
                    null,
                    targetText,
                    Symbol: Symbols.JsonValid),

                new LauncherItem(
                    "포맷 (Pretty Print) 복사",
                    $"{pretty.Length}자  ·  들여쓰기 2스페이스",
                    null,
                    pretty,
                    Symbol: Symbols.JsonFormat),

                new LauncherItem(
                    "미니파이 (Minify) 복사",
                    $"{compact.Length}자  ·  공백 제거",
                    null,
                    compact,
                    Symbol: Symbols.JsonMinify),
            ];
        }
        catch (JsonException ex)
        {
            var msg = ex.Message.Length > 100 ? ex.Message[..97] + "…" : ex.Message;
            return
            [
                new LauncherItem(
                    "❌ JSON 오류",
                    msg,
                    null,
                    null,
                    Symbol: Symbols.Error)
            ];
        }
    }

    public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
    {
        if (item.Data is string text)
        {
            try { Clipboard.SetText(text); } catch (Exception) { }
        }
        return Task.CompletedTask;
    }
}
