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

namespace AxCopilot.Handlers;

/// <summary>
/// 텍스트 통계 분석 핸들러. "stats" 프리픽스로 사용합니다.
/// 클립보드 텍스트의 글자 수, 단어 수, 줄 수, 키워드 빈도 등을 분석합니다.
/// 예: stats         → 현재 클립보드 텍스트 분석
///     stats 키워드   → 클립보드에서 해당 키워드 빈도 검색
/// Enter 시 분석 결과를 클립보드에 복사합니다.
/// </summary>
public class TextStatsHandler : IActionHandler
{
    public string? Prefix => "stats";

    public PluginMetadata Metadata => new(
        "TextStats",
        "텍스트 통계 분석",
        "1.0",
        "AX");

    public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
    {
        string? text = null;
        try
        {
            if (Application.Current?.Dispatcher.Invoke(() => Clipboard.ContainsText()) == true)
                text = Application.Current.Dispatcher.Invoke(() => Clipboard.GetText());
        }
        catch (Exception) { }

        if (string.IsNullOrEmpty(text))
        {
            return Task.FromResult<IEnumerable<LauncherItem>>(
            [
                new LauncherItem(
                    "클립보드에 텍스트가 없습니다",
                    "텍스트를 복사한 후 다시 시도하세요",
                    null, null, Symbol: Symbols.Info)
            ]);
        }

        var q = query.Trim();
        var items = new List<LauncherItem>();

        // 기본 통계
        var charCount = text.Length;
        var charNoSpace = text.Replace(" ", "").Replace("\t", "").Replace("\r", "").Replace("\n", "").Length;
        var words = Regex.Split(text, @"\s+", RegexOptions.None, TimeSpan.FromSeconds(1))
            .Where(w => !string.IsNullOrWhiteSpace(w)).ToArray();
        var wordCount = words.Length;
        var lines = text.Split('\n');
        var lineCount = lines.Length;
        var nonEmptyLines = lines.Count(l => !string.IsNullOrWhiteSpace(l));
        var byteCount = System.Text.Encoding.UTF8.GetByteCount(text);

        // 요약
        var summary = $"글자 {charCount:N0}  ·  공백 제외 {charNoSpace:N0}  ·  단어 {wordCount:N0}  ·  줄 {lineCount:N0}";

        items.Add(new LauncherItem(
            $"글자 수: {charCount:N0} ({charNoSpace:N0} 공백 제외)",
            $"UTF-8: {byteCount:N0} bytes  ·  Enter로 결과 복사",
            null, $"글자 수: {charCount:N0} (공백 제외: {charNoSpace:N0})",
            Symbol: "\uE8D2"));

        items.Add(new LauncherItem(
            $"단어 수: {wordCount:N0}",
            $"공백·줄바꿈 기준 분리  ·  Enter로 결과 복사",
            null, $"단어 수: {wordCount:N0}",
            Symbol: "\uE8D2"));

        items.Add(new LauncherItem(
            $"줄 수: {lineCount:N0} (비어있지 않은 줄: {nonEmptyLines:N0})",
            "Enter로 결과 복사",
            null, $"줄 수: {lineCount:N0} (비어있지 않은 줄: {nonEmptyLines:N0})",
            Symbol: "\uE8D2"));

        // 읽기 시간 추정 (한국어 500자/분, 영어 200단어/분)
        var koreanChars = text.Count(c => c >= '\uAC00' && c <= '\uD7AF');
        var readMinutes = koreanChars > charCount / 2
            ? (double)charNoSpace / 500
            : (double)wordCount / 200;
        var readTime = readMinutes < 1 ? "1분 미만" : $"약 {Math.Ceiling(readMinutes)}분";

        items.Add(new LauncherItem(
            $"예상 읽기 시간: {readTime}",
            koreanChars > charCount / 2 ? "한국어 기준 (500자/분)" : "영어 기준 (200단어/분)",
            null, $"예상 읽기 시간: {readTime}",
            Symbol: Symbols.Clock));

        // 키워드 빈도 (상위 5개)
        if (string.IsNullOrWhiteSpace(q))
        {
            var freq = words
                .Where(w => w.Length >= 2)
                .GroupBy(w => w.ToLowerInvariant())
                .OrderByDescending(g => g.Count())
                .Take(5)
                .Select(g => $"{g.Key}({g.Count()})");

            var freqStr = string.Join(", ", freq);
            if (!string.IsNullOrEmpty(freqStr))
            {
                items.Add(new LauncherItem(
                    "상위 키워드",
                    freqStr,
                    null, $"상위 키워드: {freqStr}",
                    Symbol: Symbols.Search));
            }
        }
        else
        {
            // 특정 키워드 빈도 검색
            try
            {
                var count = Regex.Matches(text, Regex.Escape(q), RegexOptions.IgnoreCase,
                    TimeSpan.FromSeconds(1)).Count;
                items.Insert(0, new LauncherItem(
                    $"'{q}' 출현 횟수: {count}회",
                    $"대소문자 무시 검색  ·  Enter로 결과 복사",
                    null, $"'{q}' 출현 횟수: {count}회",
                    Symbol: Symbols.Search));
            }
            catch (Exception) { }
        }

        // 전체 요약 항목
        items.Add(new LauncherItem(
            "전체 요약 복사",
            summary,
            null, $"[텍스트 통계]\n{summary}\nUTF-8: {byteCount:N0} bytes\n읽기 시간: {readTime}",
            Symbol: Symbols.Clipboard));

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

    public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
    {
        if (item.Data is string text && !string.IsNullOrWhiteSpace(text))
        {
            try { Application.Current?.Dispatcher.Invoke(() => Clipboard.SetText(text)); }
            catch (Exception) { }
        }
        return Task.CompletedTask;
    }
}
