using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using AxCopilot.SDK;

namespace AxCopilot.Handlers;

public class DateCalcHandler : IActionHandler
{
	private static readonly string[] DateFormats = new string[5] { "yyyy-MM-dd", "yyyy/MM/dd", "yyyyMMdd", "MM/dd/yyyy", "dd-MM-yyyy" };

	public string? Prefix => "date";

	public PluginMetadata Metadata => new PluginMetadata("DateCalc", "날짜 계산 · D-day · 타임스탬프 변환", "1.0", "AX");

	public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
	{
		string text = query.Trim();
		DateTime now = DateTime.Now;
		List<LauncherItem> list = new List<LauncherItem>();
		if (string.IsNullOrWhiteSpace(text))
		{
			string value = now.ToString("dddd", new CultureInfo("ko-KR"));
			list.Add(Item($"{now:yyyy-MM-dd} ({value})", $"{now:HH:mm:ss}  ·  {now:yyyy-MM-dd}"));
			list.Add(Item($"유닉스 타임스탬프: {new DateTimeOffset(now).ToUnixTimeSeconds()}", "현재 시각의 Unix epoch"));
			list.Add(Item($"올해 {now.DayOfYear}일째 / 남은 일: {(new DateTime(now.Year, 12, 31) - now).Days}일", $"ISO 주차: {ISOWeek.GetWeekOfYear(now)}주"));
			return Task.FromResult((IEnumerable<LauncherItem>)list);
		}
		Match match = Regex.Match(text, "^([+-])(\\d+)([dDwWmMyY])$");
		if (match.Success)
		{
			int num = ((match.Groups[1].Value == "+") ? 1 : (-1));
			int num2 = int.Parse(match.Groups[2].Value) * num;
			string text2 = match.Groups[3].Value.ToLowerInvariant();
			if (1 == 0)
			{
			}
			DateTime dateTime = text2 switch
			{
				"d" => now.AddDays(num2), 
				"w" => now.AddDays(num2 * 7), 
				"m" => now.AddMonths(num2), 
				"y" => now.AddYears(num2), 
				_ => now, 
			};
			if (1 == 0)
			{
			}
			DateTime value2 = dateTime;
			string value3 = value2.ToString("dddd", new CultureInfo("ko-KR"));
			int days = (value2.Date - now.Date).Days;
			string subtitle = ((days >= 0) ? $"오늘로부터 {days}일 후" : $"오늘로부터 {Math.Abs(days)}일 전");
			list.Add(Item($"{value2:yyyy-MM-dd} ({value3})", subtitle));
			return Task.FromResult((IEnumerable<LauncherItem>)list);
		}
		if (Regex.IsMatch(text, "^\\d{10,13}$") && long.TryParse(text, out var result))
		{
			long seconds = ((result > 9999999999L) ? (result / 1000) : result);
			DateTime localDateTime = DateTimeOffset.FromUnixTimeSeconds(seconds).LocalDateTime;
			string value4 = localDateTime.ToString("dddd", new CultureInfo("ko-KR"));
			list.Add(Item($"{localDateTime:yyyy-MM-dd HH:mm:ss} ({value4})", $"Unix {result} → 로컬 시간"));
			return Task.FromResult((IEnumerable<LauncherItem>)list);
		}
		if (text.Equals("unix", StringComparison.OrdinalIgnoreCase) || text.Equals("to unix", StringComparison.OrdinalIgnoreCase))
		{
			long value5 = new DateTimeOffset(now).ToUnixTimeSeconds();
			list.Add(Item($"{value5}", $"현재 시각 ({now:yyyy-MM-dd HH:mm:ss}) → Unix 타임스탬프"));
			return Task.FromResult((IEnumerable<LauncherItem>)list);
		}
		if (DateTime.TryParseExact(text, DateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out var result2))
		{
			string value6 = result2.ToString("dddd", new CultureInfo("ko-KR"));
			int days2 = (result2.Date - now.Date).Days;
			if (1 == 0)
			{
			}
			string text3 = ((days2 > 0) ? $"D-{days2} (앞으로 {days2}일)" : ((days2 != 0) ? $"D+{Math.Abs(days2)} ({Math.Abs(days2)}일 지남)" : "오늘"));
			if (1 == 0)
			{
			}
			string subtitle2 = text3;
			list.Add(Item($"{result2:yyyy-MM-dd} ({value6})", subtitle2));
			return Task.FromResult((IEnumerable<LauncherItem>)list);
		}
		list.Add(new LauncherItem("날짜 형식을 인식할 수 없습니다", "예: +30d, -100d, 2026-12-25, 1711584000, unix", null, null, null, "\ue7ba"));
		return Task.FromResult((IEnumerable<LauncherItem>)list);
	}

	private static LauncherItem Item(string title, string subtitle)
	{
		return new LauncherItem(title, subtitle + "  ·  Enter로 복사", null, title, null, "\ue823");
	}

	public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
	{
		object data = item.Data;
		string text = data as string;
		if (text != null && !string.IsNullOrWhiteSpace(text))
		{
			try
			{
				Application current = Application.Current;
				if (current != null)
				{
					((DispatcherObject)current).Dispatcher.Invoke((Action)delegate
					{
						Clipboard.SetText(text);
					});
				}
			}
			catch
			{
			}
		}
		return Task.CompletedTask;
	}
}
