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

namespace AxCopilot.Handlers;

public class EnvHandler : IActionHandler
{
	private static readonly string[] _priorityKeys = new string[22]
	{
		"PATH", "JAVA_HOME", "PYTHON_HOME", "NODE_HOME", "GOPATH", "GOROOT", "USERPROFILE", "APPDATA", "LOCALAPPDATA", "TEMP",
		"TMP", "COMPUTERNAME", "USERNAME", "USERDOMAIN", "OS", "PROCESSOR_ARCHITECTURE", "SYSTEMROOT", "WINDIR", "PROGRAMFILES", "PROGRAMFILES(X86)",
		"COMMONPROGRAMFILES", "NUMBER_OF_PROCESSORS"
	};

	public string? Prefix => "env";

	public PluginMetadata Metadata => new PluginMetadata("EnvVars", "환경변수 조회 — env 뒤에 변수명 입력", "1.0", "AX");

	public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
	{
		string q = query.Trim();
		List<(string Key, string Value)> allVars = (from DictionaryEntry e in Environment.GetEnvironmentVariables()
			select (Key: e.Key?.ToString() ?? "", Value: e.Value?.ToString() ?? "") into x
			where !string.IsNullOrEmpty(x.Key)
			select x).ToList();
		IEnumerable<(string, string)> source;
		if (string.IsNullOrWhiteSpace(q))
		{
			HashSet<string> prioritySet = new HashSet<string>(_priorityKeys, StringComparer.OrdinalIgnoreCase);
			IEnumerable<(string, string)> first = from k in _priorityKeys
				where allVars.Any(((string Key, string Value) v) => string.Equals(v.Key, k, StringComparison.OrdinalIgnoreCase))
				select allVars.First(((string Key, string Value) v) => string.Equals(v.Key, k, StringComparison.OrdinalIgnoreCase));
			IOrderedEnumerable<(string, string)> second = from v in allVars
				where !prioritySet.Contains(v.Key)
				orderby v.Key
				select v;
			source = first.Concat(second).Take(20);
		}
		else
		{
			source = (from v in allVars
				where v.Key.Contains(q, StringComparison.OrdinalIgnoreCase) || v.Value.Contains(q, StringComparison.OrdinalIgnoreCase)
				orderby (!v.Key.StartsWith(q, StringComparison.OrdinalIgnoreCase)) ? 1 : 0, v.Key
				select v).Take(20);
		}
		List<LauncherItem> list = source.Select<(string, string), LauncherItem>(delegate((string Key, string Value) v)
		{
			string text = ((v.Value.Length > 80) ? (v.Value.Substring(0, 77) + "…") : v.Value);
			if (v.Key.Equals("PATH", StringComparison.OrdinalIgnoreCase) && v.Value.Contains(';'))
			{
				text = v.Value.Split(';')[0] + $"  (외 {v.Value.Split(';').Length - 1}개)";
			}
			return new LauncherItem(v.Key, text + "  ·  Enter로 값 복사", null, v.Value, null, "\ue8d7");
		}).ToList();
		if (!list.Any())
		{
			list.Add(new LauncherItem("'" + q + "' — 환경변수 없음", "해당 이름의 환경변수를 찾을 수 없습니다", null, null, null, "\ue7ba"));
		}
		return Task.FromResult((IEnumerable<LauncherItem>)list);
	}

	public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
	{
		if (item.Data is string text)
		{
			try
			{
				Clipboard.SetText(text);
			}
			catch
			{
			}
		}
		return Task.CompletedTask;
	}
}
