using System;
using System.Collections.Generic;
using System.Linq;
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 BatchTextHandler : IActionHandler
{
	private static readonly (string Cmd, string Desc)[] Commands = new(string, string)[14]
	{
		("prefix [텍스트]", "각 줄 앞에 텍스트 추가"),
		("suffix [텍스트]", "각 줄 뒤에 텍스트 추가"),
		("wrap [문자]", "각 줄을 지정 문자로 감싸기 (예: wrap \")"),
		("number", "줄번호 추가 (1. 2. 3. ...)"),
		("sort", "줄 오름차순 정렬"),
		("sortd", "줄 내림차순 정렬"),
		("reverse", "줄 순서 뒤집기"),
		("unique", "중복 줄 제거"),
		("trim", "각 줄 앞뒤 공백 제거"),
		("replace [A] [B]", "A를 B로 전체 치환"),
		("csv", "줄들을 쉼표로 합쳐 한 줄로"),
		("split [구분자]", "한 줄을 구분자로 분리하여 여러 줄로"),
		("indent [N]", "각 줄 앞에 공백 N개 추가"),
		("unindent", "각 줄의 선행 공백/탭 제거")
	};

	public string? Prefix => "batch";

	public PluginMetadata Metadata => new PluginMetadata("BatchText", "텍스트 일괄 처리 — batch", "1.0", "AX");

	public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
	{
		string text = query.Trim();
		if (string.IsNullOrWhiteSpace(text))
		{
			List<LauncherItem> list = Commands.Select(((string Cmd, string Desc) c) => new LauncherItem("batch " + c.Cmd, c.Desc, null, null, null, "\ue8d2")).ToList();
			list.Insert(0, new LauncherItem("텍스트 일괄 처리", "클립보드 텍스트의 각 줄에 변환 적용  ·  명령 입력", null, null, null, "\ue946"));
			return Task.FromResult((IEnumerable<LauncherItem>)list);
		}
		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((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("클립보드에 텍스트가 없습니다", "텍스트를 복사한 후 시도하세요", null, null, null, "\ue7ba")));
		}
		string[] array = (from l in text2.Split('\n')
			select l.TrimEnd('\r')).ToArray();
		string[] array2 = text.Split(' ', 2, StringSplitOptions.TrimEntries);
		string text3 = array2[0].ToLowerInvariant();
		string arg = ((array2.Length > 1) ? array2[1] : "");
		string text4 = null;
		string text5 = null;
		try
		{
			switch (text3)
			{
			case "prefix":
				text4 = string.Join("\n", array.Select((string l) => arg + l));
				text5 = "각 줄 앞에 '" + arg + "' 추가";
				break;
			case "suffix":
				text4 = string.Join("\n", array.Select((string l) => l + arg));
				text5 = "각 줄 뒤에 '" + arg + "' 추가";
				break;
			case "wrap":
			{
				string w = (string.IsNullOrEmpty(arg) ? "\"" : arg);
				text4 = string.Join("\n", array.Select((string l) => w + l + w));
				text5 = "각 줄을 '" + w + "'로 감싸기";
				break;
			}
			case "number":
				text4 = string.Join("\n", array.Select((string l, int i) => $"{i + 1}. {l}"));
				text5 = "줄번호 추가";
				break;
			case "sort":
				text4 = string.Join("\n", array.Order());
				text5 = "오름차순 정렬";
				break;
			case "sortd":
				text4 = string.Join("\n", array.OrderDescending());
				text5 = "내림차순 정렬";
				break;
			case "reverse":
				text4 = string.Join("\n", array.Reverse());
				text5 = "줄 순서 뒤집기";
				break;
			case "unique":
			{
				string[] array4 = array.Distinct().ToArray();
				text4 = string.Join("\n", array4);
				text5 = $"중복 제거: {array.Length}줄 → {array4.Length}줄";
				break;
			}
			case "trim":
				text4 = string.Join("\n", array.Select((string l) => l.Trim()));
				text5 = "각 줄 공백 제거";
				break;
			case "replace":
			{
				string[] array3 = arg.Split(' ', 2, StringSplitOptions.TrimEntries);
				if (array3.Length == 2)
				{
					text4 = text2.Replace(array3[0], array3[1]);
					text5 = $"'{array3[0]}' → '{array3[1]}' 치환";
				}
				break;
			}
			case "csv":
				text4 = string.Join(",", array.Select((string l) => l.Trim()));
				text5 = $"{array.Length}줄 → CSV 한 줄";
				break;
			case "split":
			{
				string text6 = (string.IsNullOrEmpty(arg) ? "," : arg);
				text4 = string.Join("\n", text2.Split(text6));
				text5 = "'" + text6 + "' 기준 분리";
				break;
			}
			case "indent":
			{
				int result;
				int num = (int.TryParse(arg, out result) ? result : 4);
				string pad = new string(' ', num);
				text4 = string.Join("\n", array.Select((string l) => pad + l));
				text5 = $"{num}칸 들여쓰기";
				break;
			}
			case "unindent":
				text4 = string.Join("\n", array.Select((string l) => l.TrimStart(' ', '\t')));
				text5 = "선행 공백 제거";
				break;
			}
		}
		catch (Exception ex)
		{
			return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("처리 오류: " + ex.Message, "입력 데이터를 확인하세요", null, null, null, "\uea39")));
		}
		if (text4 == null)
		{
			return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("알 수 없는 명령: " + text3, "batch 만 입력하면 전체 명령 목록", null, null, null, "\ue7ba")));
		}
		string text7 = ((text4.Length > 120) ? (text4.Substring(0, 117) + "…") : text4);
		text7 = text7.Replace("\n", "↵ ");
		return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("[" + text5 + "] → Enter로 클립보드 복사", text7, null, text4, null, "\ue8d2")));
	}

	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;
	}
}
