using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
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 FavoriteHandler : IActionHandler
{
	private class FavEntry
	{
		[JsonPropertyName("name")]
		public string Name { get; set; } = "";

		[JsonPropertyName("path")]
		public string Path { get; set; } = "";
	}

	private static readonly string FavFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "favorites.json");

	private static readonly JsonSerializerOptions JsonOpts = new JsonSerializerOptions
	{
		WriteIndented = true,
		PropertyNameCaseInsensitive = true
	};

	private List<FavEntry> _cache = new List<FavEntry>();

	private bool _loaded;

	public string? Prefix => "fav";

	public PluginMetadata Metadata => new PluginMetadata("Favorite", "즐겨찾기 관리 — fav", "1.0", "AX");

	public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
	{
		EnsureLoaded();
		string q = query.Trim();
		if (q.StartsWith("add ", StringComparison.OrdinalIgnoreCase))
		{
			string text = q;
			string text2 = text.Substring(4, text.Length - 4).Trim();
			int num = text2.IndexOf(' ');
			if (num > 0)
			{
				string text3 = text2.Substring(0, num).Trim();
				text = text2;
				int num2 = num + 1;
				string text4 = text.Substring(num2, text.Length - num2).Trim();
				return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("즐겨찾기 추가: " + text3, "경로: " + text4 + "  ·  Enter로 추가", null, ValueTuple.Create("__ADD__", text3, text4), null, "\ue74e")));
			}
			return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("사용법: fav add [이름] [경로]", "예: fav add 보고서 C:\\work\\report.xlsx", null, null, null, "\ue946")));
		}
		if (q.StartsWith("del ", StringComparison.OrdinalIgnoreCase))
		{
			string text = q;
			string name = text.Substring(4, text.Length - 4).Trim();
			FavEntry favEntry = _cache.FirstOrDefault((FavEntry b) => b.Name.Contains(name, StringComparison.OrdinalIgnoreCase));
			if (favEntry != null)
			{
				return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("즐겨찾기 삭제: " + favEntry.Name, "경로: " + favEntry.Path + "  ·  Enter로 삭제", null, ValueTuple.Create("__DEL__", favEntry.Name), null, "\ue74d")));
			}
			return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("'" + name + "'에 해당하는 즐겨찾기 없음", "fav으로 전체 목록 확인", null, null, null, "\ue7ba")));
		}
		List<FavEntry> source = (string.IsNullOrWhiteSpace(q) ? _cache : _cache.Where((FavEntry b) => b.Name.Contains(q, StringComparison.OrdinalIgnoreCase) || b.Path.Contains(q, StringComparison.OrdinalIgnoreCase)).ToList());
		if (!source.Any())
		{
			return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem((_cache.Count == 0) ? "즐겨찾기가 없습니다" : ("'" + q + "'에 해당하는 즐겨찾기 없음"), "fav add [이름] [경로]로 추가하세요", null, null, null, "\ue946")));
		}
		List<LauncherItem> result = source.Select(delegate(FavEntry b)
		{
			bool flag = Directory.Exists(b.Path);
			bool flag2 = File.Exists(b.Path);
			string symbol = (flag ? "\ue8b7" : (flag2 ? "\ue8a5" : "\ue7ba"));
			string text5 = (flag ? "폴더 열기" : (flag2 ? "파일 열기" : "경로를 찾을 수 없음"));
			return new LauncherItem(b.Name, b.Path + "  ·  " + text5, null, b.Path, null, symbol);
		}).ToList();
		return Task.FromResult((IEnumerable<LauncherItem>)result);
	}

	public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
	{
		if (item.Data is (string, string, string) { Item1: "__ADD__" } tuple)
		{
			AddFav(tuple.Item2, tuple.Item3);
			NotificationService.Notify("AX Copilot", "즐겨찾기 추가: " + tuple.Item2);
			return Task.CompletedTask;
		}
		if (item.Data is (string, string) { Item1: "__DEL__" } tuple2)
		{
			RemoveFav(tuple2.Item2);
			NotificationService.Notify("AX Copilot", "즐겨찾기 삭제: " + tuple2.Item2);
			return Task.CompletedTask;
		}
		object data = item.Data;
		string path = data as string;
		if (path != null)
		{
			if (Directory.Exists(path) || File.Exists(path))
			{
				try
				{
					Process.Start(new ProcessStartInfo(path)
					{
						UseShellExecute = true
					});
				}
				catch (Exception ex)
				{
					LogService.Warn("즐겨찾기 열기 실패: " + ex.Message);
				}
			}
			else
			{
				try
				{
					Application current = Application.Current;
					if (current != null)
					{
						((DispatcherObject)current).Dispatcher.Invoke((Action)delegate
						{
							Clipboard.SetText(path);
						});
					}
				}
				catch
				{
				}
			}
		}
		return Task.CompletedTask;
	}

	private void EnsureLoaded()
	{
		if (_loaded)
		{
			return;
		}
		_loaded = true;
		try
		{
			if (File.Exists(FavFile))
			{
				_cache = JsonSerializer.Deserialize<List<FavEntry>>(File.ReadAllText(FavFile), JsonOpts) ?? new List<FavEntry>();
			}
		}
		catch (Exception ex)
		{
			LogService.Warn("즐겨찾기 로드 실패: " + ex.Message);
		}
	}

	private void AddFav(string name, string path)
	{
		EnsureLoaded();
		_cache.RemoveAll((FavEntry b) => b.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
		_cache.Insert(0, new FavEntry
		{
			Name = name,
			Path = path
		});
		Save();
	}

	private void RemoveFav(string name)
	{
		EnsureLoaded();
		_cache.RemoveAll((FavEntry b) => b.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
		Save();
	}

	private void Save()
	{
		try
		{
			Directory.CreateDirectory(Path.GetDirectoryName(FavFile));
			File.WriteAllText(FavFile, JsonSerializer.Serialize(_cache, JsonOpts));
		}
		catch (Exception ex)
		{
			LogService.Warn("즐겨찾기 저장 실패: " + ex.Message);
		}
	}
}
