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

namespace AxCopilot.Handlers;

/// <summary>
/// 최근 파일 핸들러. "recent" 프리픽스로 사용합니다.
/// Windows Recent 폴더(%APPDATA%\Microsoft\Windows\Recent)의 .lnk 파일을
/// 최근 수정 순으로 나열합니다.
/// 예: recent          → 최근 20개 파일 목록
///     recent 보고서   → 이름에 "보고서" 포함 파일 필터
/// </summary>
public class RecentFilesHandler : IActionHandler
{
    public string? Prefix => "recent";

    public PluginMetadata Metadata => new(
        "RecentFiles",
        "최근 파일 — recent 뒤에 검색어 입력",
        "1.0",
        "AX");

    private static readonly string RecentFolder = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
        @"Microsoft\Windows\Recent");

    // 간단한 캐시: 10초간 유효
    private static (DateTime At, List<(string Name, string LinkPath, DateTime Modified)> Files)? _cache;
    private static readonly TimeSpan CacheTtl = TimeSpan.FromSeconds(10);

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

        if (string.IsNullOrWhiteSpace(q))
        {
            // 힌트만 표시
        }

        var files = GetRecentFiles();
        IEnumerable<(string Name, string LinkPath, DateTime Modified)> filtered = files;

        if (!string.IsNullOrWhiteSpace(q))
        {
            filtered = files.Where(f =>
                f.Name.Contains(q, StringComparison.OrdinalIgnoreCase));
        }

        var items = filtered.Take(20).Select(f => new LauncherItem(
            f.Name,
            $"{f.Modified:yyyy-MM-dd HH:mm}  ·  Enter로 열기",
            null,
            f.LinkPath,
            Symbol: GetSymbol(f.Name))).ToList();

        if (!items.Any())
        {
            items.Add(new LauncherItem(
                string.IsNullOrWhiteSpace(q) ? "최근 파일 없음" : "검색 결과 없음",
                string.IsNullOrWhiteSpace(q)
                    ? "Windows Recent 폴더가 비어 있습니다"
                    : $"'{q}' 파일을 최근 목록에서 찾을 수 없습니다",
                null, null, Symbol: Symbols.Info));
        }

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

    public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
    {
        if (item.Data is string linkPath && File.Exists(linkPath))
        {
            try
            {
                System.Diagnostics.Process.Start(
                    new System.Diagnostics.ProcessStartInfo(linkPath)
                    { UseShellExecute = true });
            }
            catch (Exception ex)
            {
                LogService.Warn($"최근 파일 열기 실패: {ex.Message}");
            }
        }
        return Task.CompletedTask;
    }

    // ─── 내부 ─────────────────────────────────────────────────────────────────

    private static List<(string Name, string LinkPath, DateTime Modified)> GetRecentFiles()
    {
        // 캐시 유효 확인
        if (_cache.HasValue && (DateTime.Now - _cache.Value.At) < CacheTtl)
            return _cache.Value.Files;

        var result = new List<(string, string, DateTime)>();

        try
        {
            if (!Directory.Exists(RecentFolder))
                return result;

            var lnkFiles = Directory
                .GetFiles(RecentFolder, "*.lnk")
                .Select(p => (Path: p, Info: new FileInfo(p)))
                .OrderByDescending(f => f.Info.LastWriteTime)
                .Take(100)
                .ToList();

            foreach (var (path, info) in lnkFiles)
            {
                var name = Path.GetFileNameWithoutExtension(info.Name);
                result.Add((name, path, info.LastWriteTime));
            }
        }
        catch (Exception ex)
        {
            LogService.Warn($"최근 파일 목록 읽기 실패: {ex.Message}");
        }

        _cache = (DateTime.Now, result);
        return result;
    }

    private static string GetSymbol(string name)
    {
        var ext = Path.GetExtension(name).ToLowerInvariant();
        return ext switch
        {
            ".exe" or ".msi" => Symbols.App,
            ".xlsx" or ".xls" or ".csv" => Symbols.File,
            ".docx" or ".doc" => Symbols.File,
            ".pptx" or ".ppt" => Symbols.File,
            ".pdf" => Symbols.File,
            ".txt" or ".md" or ".log" => Symbols.Text,
            ".jpg" or ".jpeg" or ".png" or ".gif" or ".webp" or ".bmp" => Symbols.Picture,
            _ => Symbols.File
        };
    }
}
