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

namespace AxCopilot.Handlers;

/// <summary>
/// L14-4: 시스템 폰트 목록·검색 핸들러. "font" 프리픽스로 사용합니다.
///
/// 예: font                  → 설치된 폰트 전체 목록
///     font 맑은             → "맑은" 포함 폰트 검색
///     font malgun           → 영문 이름으로 검색
///     font mono             → "mono" 포함 폰트 목록
///     font nanum            → 나눔 폰트 목록
/// Enter → 폰트 이름을 클립보드에 복사.
/// </summary>
public class FontHandler : IActionHandler
{
    public string? Prefix => "font";

    public PluginMetadata Metadata => new(
        "Font",
        "시스템 폰트 목록 — 검색 · 이름 복사",
        "1.0",
        "AX");

    // 폰트 목록 캐시 (최초 1회 로드)
    private static List<string>? _fontCache;
    private static readonly object _lock = new();

    private static List<string> GetFonts()
    {
        if (_fontCache != null) return _fontCache;
        lock (_lock)
        {
            if (_fontCache != null) return _fontCache;
            try
            {
                _fontCache = Fonts.SystemFontFamilies
                    .Select(f => f.Source)
                    .OrderBy(n => n, StringComparer.OrdinalIgnoreCase)
                    .ToList();
            }
            catch
            {
                _fontCache = new List<string>();
            }
            return _fontCache;
        }
    }

    // 주목할 만한 폰트 그룹 키워드
    private static readonly (string Label, string Keyword)[] FontGroups =
    [
        ("한글 폰트",   "malgun"),
        ("나눔 폰트",   "nanum"),
        ("코딩용 폰트", "mono"),
        ("Arial 계열", "arial"),
        ("Times 계열", "times"),
        ("Consolas",   "consolas"),
    ];

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

        if (string.IsNullOrWhiteSpace(q))
        {
            items.Add(new LauncherItem(
                $"설치된 폰트  {fonts.Count}개",
                "font <검색어> 로 필터링",
                null, null, Symbol: "\uE8D2"));

            // 그룹 힌트
            foreach (var (label, kw) in FontGroups)
            {
                var cnt = fonts.Count(f => f.Contains(kw, StringComparison.OrdinalIgnoreCase));
                if (cnt > 0)
                    items.Add(new LauncherItem(label, $"{cnt}개  · font {kw}", null, null, Symbol: "\uE8D2"));
            }

            // 첫 15개 표시
            foreach (var f in fonts.Take(15))
                items.Add(MakeFontItem(f));

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

        // 검색
        var filtered = fonts
            .Where(f => f.Contains(q, StringComparison.OrdinalIgnoreCase))
            .ToList();

        if (filtered.Count == 0)
        {
            items.Add(new LauncherItem("결과 없음",
                $"'{q}' 포함 폰트가 없습니다", null, null, Symbol: "\uE946"));
        }
        else
        {
            items.Add(new LauncherItem(
                $"'{q}' 검색 결과  {filtered.Count}개",
                "전체 복사: 첫 항목 Enter",
                null,
                ("copy", string.Join("\n", filtered)),
                Symbol: "\uE8D2"));

            foreach (var f in filtered.Take(30))
                items.Add(MakeFontItem(f));
        }

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

    private static LauncherItem MakeFontItem(string fontName) =>
        new(fontName, "폰트 이름  · Enter 복사", null, ("copy", fontName), Symbol: "\uE8D2");
}
