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

namespace AxCopilot.Handlers;

public class ClipboardPipeHandler : IActionHandler
{
	private static readonly Dictionary<string, (string Desc, Func<string, string> Fn)> Filters = new Dictionary<string, (string, Func<string, string>)>(StringComparer.OrdinalIgnoreCase)
	{
		["upper"] = ("대문자 변환", (string s) => s.ToUpperInvariant()),
		["lower"] = ("소문자 변환", (string s) => s.ToLowerInvariant()),
		["trim"] = ("앞뒤 공백 제거", (string s) => s.Trim()),
		["trimall"] = ("모든 공백 제거", (string s) => Regex.Replace(s, "\\s+", "", RegexOptions.None, TimeSpan.FromSeconds(1.0))),
		["sort"] = ("줄 정렬 (오름차순)", (string s) => string.Join("\n", s.Split('\n').Order())),
		["sortd"] = ("줄 정렬 (내림차순)", (string s) => string.Join("\n", s.Split('\n').OrderDescending())),
		["unique"] = ("중복 줄 제거", (string s) => string.Join("\n", s.Split('\n').Distinct())),
		["reverse"] = ("줄 순서 뒤집기", (string s) => string.Join("\n", s.Split('\n').Reverse())),
		["number"] = ("줄번호 추가", (string s) => string.Join("\n", s.Split('\n').Select((string l, int i) => $"{i + 1}. {l}"))),
		["quote"] = ("각 줄 따옴표 감싸기", (string s) => string.Join("\n", from l in s.Split('\n')
			select "\"" + l + "\"")),
		["b64e"] = ("Base64 인코딩", (string s) => Convert.ToBase64String(Encoding.UTF8.GetBytes(s))),
		["b64d"] = ("Base64 디코딩", (string s) => Encoding.UTF8.GetString(Convert.FromBase64String(s.Trim()))),
		["urle"] = ("URL 인코딩", (string s) => Uri.EscapeDataString(s)),
		["urld"] = ("URL 디코딩", (string s) => Uri.UnescapeDataString(s)),
		["md"] = ("마크다운 제거", (string s) => Regex.Replace(s, "[#*_`~\\[\\]()]", "", RegexOptions.None, TimeSpan.FromSeconds(1.0))),
		["lines"] = ("빈 줄 제거", (string s) => string.Join("\n", from l in s.Split('\n')
			where !string.IsNullOrWhiteSpace(l)
			select l)),
		["count"] = ("글자/단어/줄 수", (string s) => $"글자: {s.Length}  단어: {s.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries).Length}  줄: {s.Split('\n').Length}"),
		["csv"] = ("CSV → 탭 변환", (string s) => s.Replace(',', '\t')),
		["tab"] = ("탭 → CSV 변환", (string s) => s.Replace('\t', ','))
	};

	public string? Prefix => "pipe";

	public PluginMetadata Metadata => new PluginMetadata("ClipboardPipe", "클립보드 파이프라인 — pipe", "1.0", "AX");

	public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
	{
		string text = query.Trim();
		if (string.IsNullOrWhiteSpace(text))
		{
			List<LauncherItem> list = Filters.Select<KeyValuePair<string, (string, Func<string, string>)>, LauncherItem>((KeyValuePair<string, (string Desc, Func<string, string> Fn)> kv) => new LauncherItem(kv.Key, kv.Value.Desc, null, null, null, "\ue77f")).ToList();
			list.Insert(0, new LauncherItem("클립보드 파이프라인", "필터를 > 로 연결: pipe upper > trim > b64e", null, null, null, "\ue946"));
			return Task.FromResult((IEnumerable<LauncherItem>)list);
		}
		string[] array = (from s in text.Split('>')
			select s.Trim() into s
			where !string.IsNullOrEmpty(s)
			select s).ToArray();
		string[] array2 = array.Where((string s) => !Filters.ContainsKey(s)).ToArray();
		if (array2.Length != 0)
		{
			return Task.FromResult(new LauncherItem[1]
			{
				new LauncherItem("알 수 없는 필터: " + string.Join(", ", array2), "사용 가능: " + string.Join(", ", Filters.Keys.Take(10)) + " ...", null, null, null, "\ue7ba")
			}.AsEnumerable());
		}
		string text2 = null;
		try
		{
			Application current = Application.Current;
			if (current != null && ((DispatcherObject)current).Dispatcher.Invoke<bool>((Func<bool>)(() => Clipboard.ContainsText())))
			{
				text2 = ((DispatcherObject)Application.Current).Dispatcher.Invoke<string>((Func<string>)(() => Clipboard.GetText()));
			}
		}
		catch
		{
		}
		if (string.IsNullOrEmpty(text2))
		{
			return Task.FromResult(new LauncherItem[1]
			{
				new LauncherItem("클립보드에 텍스트가 없습니다", "텍스트를 복사한 후 시도하세요", null, null, null, "\ue7ba")
			}.AsEnumerable());
		}
		string text3 = text2;
		List<string> list2 = new List<string>();
		try
		{
			string[] array3 = array;
			foreach (string key in array3)
			{
				text3 = Filters[key].Fn(text3);
				list2.Add(Filters[key].Desc);
			}
		}
		catch (Exception ex)
		{
			return Task.FromResult(new LauncherItem[1]
			{
				new LauncherItem("파이프라인 실행 오류: " + ex.Message, "입력 데이터를 확인하세요", null, null, null, "\uea39")
			}.AsEnumerable());
		}
		string text4 = ((text3.Length > 100) ? (text3.Substring(0, 97) + "…") : text3);
		text4 = text4.Replace("\r\n", "↵ ").Replace("\n", "↵ ");
		return Task.FromResult(new LauncherItem[1]
		{
			new LauncherItem("[" + string.Join(" → ", array) + "] 결과 적용", text4 + "  ·  Enter로 클립보드 복사", null, text3, null, "\ue77f")
		}.AsEnumerable());
	}

	public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
	{
		object data = item.Data;
		string text = data as string;
		if (text != null)
		{
			try
			{
				Application current = Application.Current;
				if (current != null)
				{
					((DispatcherObject)current).Dispatcher.Invoke((Action)delegate
					{
						Clipboard.SetText(text);
					});
				}
			}
			catch
			{
			}
			NotificationService.Notify("파이프라인 완료", "변환 결과가 클립보드에 복사되었습니다");
		}
		return Task.CompletedTask;
	}
}
