using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AxCopilot.SDK;
using AxCopilot.Services;

namespace AxCopilot.Handlers;

public class RecentFilesHandler : IActionHandler
{
	private static readonly string RecentFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Microsoft\\Windows\\Recent");

	private static (DateTime At, List<(string Name, string LinkPath, DateTime Modified)> Files)? _cache;

	private static readonly TimeSpan CacheTtl = TimeSpan.FromSeconds(10.0);

	public string? Prefix => "recent";

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

	public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
	{
		string q = query.Trim();
		if (string.IsNullOrWhiteSpace(q))
		{
		}
		List<(string, string, DateTime)> recentFiles = GetRecentFiles();
		IEnumerable<(string, string, DateTime)> source = recentFiles;
		if (!string.IsNullOrWhiteSpace(q))
		{
			source = recentFiles.Where<(string, string, DateTime)>(((string Name, string LinkPath, DateTime Modified) f) => f.Name.Contains(q, StringComparison.OrdinalIgnoreCase));
		}
		List<LauncherItem> list = (from f in source.Take(20)
			select new LauncherItem(f.Name, $"{f.Modified:yyyy-MM-dd HH:mm}  ·  Enter로 열기", null, f.LinkPath, null, GetSymbol(f.Name))).ToList();
		if (!list.Any())
		{
			list.Add(new LauncherItem(string.IsNullOrWhiteSpace(q) ? "최근 파일 없음" : "검색 결과 없음", string.IsNullOrWhiteSpace(q) ? "Windows Recent 폴더가 비어 있습니다" : ("'" + q + "' 파일을 최근 목록에서 찾을 수 없습니다"), null, null, null, "\ue946"));
		}
		return Task.FromResult((IEnumerable<LauncherItem>)list);
	}

	public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
	{
		if (item.Data is string text && File.Exists(text))
		{
			try
			{
				Process.Start(new ProcessStartInfo(text)
				{
					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;
		}
		List<(string, string, DateTime)> list = new List<(string, string, DateTime)>();
		try
		{
			if (!Directory.Exists(RecentFolder))
			{
				return list;
			}
			List<(string, FileInfo)> list2 = (from p in Directory.GetFiles(RecentFolder, "*.lnk")
				select (Path: p, Info: new FileInfo(p)) into f
				orderby f.Info.LastWriteTime descending
				select f).Take(100).ToList();
			foreach (var item3 in list2)
			{
				string item = item3.Item1;
				FileInfo item2 = item3.Item2;
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item2.Name);
				list.Add((fileNameWithoutExtension, item, item2.LastWriteTime));
			}
		}
		catch (Exception ex)
		{
			LogService.Warn("최근 파일 목록 읽기 실패: " + ex.Message);
		}
		_cache = (DateTime.Now, list);
		return list;
	}

	private static string GetSymbol(string name)
	{
		string text = Path.GetExtension(name).ToLowerInvariant();
		if (1 == 0)
		{
		}
		string result;
		switch (text)
		{
		case ".exe":
		case ".msi":
			result = "\uecaa";
			break;
		case ".xlsx":
		case ".xls":
		case ".csv":
			result = "\ue8a5";
			break;
		case ".docx":
		case ".doc":
			result = "\ue8a5";
			break;
		case ".pptx":
		case ".ppt":
			result = "\ue8a5";
			break;
		case ".pdf":
			result = "\ue8a5";
			break;
		case ".txt":
		case ".md":
		case ".log":
			result = "\ue8d2";
			break;
		case ".jpg":
		case ".jpeg":
		case ".png":
		case ".gif":
		case ".webp":
		case ".bmp":
			result = "\ueb9f";
			break;
		default:
			result = "\ue8a5";
			break;
		}
		if (1 == 0)
		{
		}
		return result;
	}
}
