using AxCopilot.SDK;
using AxCopilot.Themes;

namespace AxCopilot.Handlers;

/// <summary>
/// 환경변수 조회 핸들러. "env" 프리픽스로 사용합니다.
/// 예: env           → 자주 쓰는 환경변수 목록
///     env PATH      → PATH 값 표시 (Enter로 복사)
///     env java      → 이름에 "java" 포함된 환경변수 검색
/// </summary>
public class EnvHandler : IActionHandler
{
    public string? Prefix => "env";

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

    // 자주 쓰는 환경변수 우선 표시 순서
    private static readonly string[] _priorityKeys =
    [
        "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 Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
    {
        var q = query.Trim();

        var allVars = Environment.GetEnvironmentVariables()
            .Cast<System.Collections.DictionaryEntry>()
            .Select(e => (Key: e.Key?.ToString() ?? "", Value: e.Value?.ToString() ?? ""))
            .Where(x => !string.IsNullOrEmpty(x.Key))
            .ToList();

        IEnumerable<(string Key, string Value)> filtered;

        if (string.IsNullOrWhiteSpace(q))
        {
            // 우선순위 키를 앞에, 나머지 알파벳 순
            var prioritySet = new HashSet<string>(_priorityKeys, StringComparer.OrdinalIgnoreCase);
            var prioritized = _priorityKeys
                .Where(k => allVars.Any(v => string.Equals(v.Key, k, StringComparison.OrdinalIgnoreCase)))
                .Select(k => allVars.First(v => string.Equals(v.Key, k, StringComparison.OrdinalIgnoreCase)));
            var rest = allVars
                .Where(v => !prioritySet.Contains(v.Key))
                .OrderBy(v => v.Key);
            filtered = prioritized.Concat(rest).Take(20);
        }
        else
        {
            // 키 또는 값에 쿼리 포함 검색
            filtered = allVars
                .Where(v => v.Key.Contains(q, StringComparison.OrdinalIgnoreCase)
                         || v.Value.Contains(q, StringComparison.OrdinalIgnoreCase))
                .OrderBy(v => v.Key.StartsWith(q, StringComparison.OrdinalIgnoreCase) ? 0 : 1)
                .ThenBy(v => v.Key)
                .Take(20);
        }

        var items = filtered.Select(v =>
        {
            // PATH처럼 긴 값은 첫 경로만 미리보기
            var preview = v.Value.Length > 80 ? v.Value[..77] + "…" : v.Value;
            // PATH 변수는 세미콜론으로 분할하여 첫 항목만 표시
            if (v.Key.Equals("PATH", StringComparison.OrdinalIgnoreCase) && v.Value.Contains(';'))
                preview = v.Value.Split(';')[0] + $"  (외 {v.Value.Split(';').Length - 1}개)";

            return new LauncherItem(
                v.Key,
                $"{preview}  ·  Enter로 값 복사",
                null,
                v.Value,
                Symbol: Symbols.EnvVar);
        }).ToList<LauncherItem>();

        if (!items.Any())
            items.Add(new LauncherItem(
                $"'{q}' — 환경변수 없음",
                "해당 이름의 환경변수를 찾을 수 없습니다",
                null, null, Symbol: Symbols.Warning));

        return Task.FromResult<IEnumerable<LauncherItem>>(items);
    }

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