using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Tornado3_2026Election.Domain;

internal readonly record struct CutDebugRecommendation(string Key, CutDebugItemKind Kind);

internal static class CutDebugRecommendationCatalog
{
    private static readonly Lazy<IReadOnlyDictionary<string, CutDebugRecommendation>> Recommendations =
        new(LoadRecommendations);

    public static bool TryGetRecommendation(string templateId, out CutDebugRecommendation recommendation)
    {
        return Recommendations.Value.TryGetValue(templateId, out recommendation);
    }

    public static int Count => Recommendations.Value.Count;

    private static IReadOnlyDictionary<string, CutDebugRecommendation> LoadRecommendations()
    {
        var path = FindRecommendationPath();
        if (path is null || !File.Exists(path))
        {
            return new Dictionary<string, CutDebugRecommendation>(StringComparer.OrdinalIgnoreCase);
        }

        var recommendations = new Dictionary<string, CutDebugRecommendation>(StringComparer.OrdinalIgnoreCase);
        foreach (var rawLine in File.ReadLines(path, Encoding.UTF8).Skip(1))
        {
            if (string.IsNullOrWhiteSpace(rawLine))
            {
                continue;
            }

            var columns = rawLine.Split('\t');
            if (columns.Length < 3)
            {
                continue;
            }

            var templateId = columns[0].Trim();
            var key = columns[1].Trim();
            if (!Enum.TryParse<CutDebugItemKind>(columns[2].Trim(), ignoreCase: true, out var kind) ||
                string.IsNullOrWhiteSpace(templateId) ||
                string.IsNullOrWhiteSpace(key))
            {
                continue;
            }

            recommendations[templateId] = new CutDebugRecommendation(key, kind);
        }

        return recommendations;
    }

    private static string? FindRecommendationPath()
    {
        foreach (var root in EnumerateSearchRoots())
        {
            var candidate = Path.Combine(root, "tools", "KarismaTcpProbe", "cut-debug-recommendations.tsv");
            if (File.Exists(candidate))
            {
                return candidate;
            }
        }

        return null;
    }

    private static IEnumerable<string> EnumerateSearchRoots()
    {
        var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

        foreach (var start in new[] { AppContext.BaseDirectory, Environment.CurrentDirectory })
        {
            if (string.IsNullOrWhiteSpace(start))
            {
                continue;
            }

            var directory = new DirectoryInfo(Path.GetFullPath(start));
            while (directory is not null)
            {
                if (seen.Add(directory.FullName))
                {
                    yield return directory.FullName;
                }

                directory = directory.Parent;
            }
        }
    }
}
