using System.Text;
using Markdig;
using Model;

var repoRoot = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", ".."));

var docsDir = Path.GetFullPath(args.Length > 0 ? args[0] : Path.Combine(repoRoot, "gsr.docs"));
var outputDir = Path.GetFullPath(args.Length > 1 ? args[1] : Path.Combine(repoRoot, "GSR", "Model"));

var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();

var games = new List<GameDoc>();
string? overviewHtml = null;

foreach (var file in Directory.EnumerateFiles(docsDir, "*.md"))
{
    var text = File.ReadAllText(file);
    var title = Path.GetFileNameWithoutExtension(file);

    string body;
    var category = string.Empty;
    bool? isVisible = true;
    string? link = null;
    string? git = null;

    if (text.StartsWith("---"))
    {
        var endIdx = text.IndexOf("---", 3, StringComparison.Ordinal);
        if (endIdx > 0)
        {
            var yaml = text[3..endIdx].Trim();
            body = text[(endIdx + 3)..].Trim();

            foreach (var line in yaml.Split('\n', StringSplitOptions.RemoveEmptyEntries))
            {
                var colonIdx = line.IndexOf(':');
                if (colonIdx < 0) continue;

                var key = line[..colonIdx].Trim();
                var val = line[(colonIdx + 1)..].Trim();

                if (val.Length == 0) continue;

                switch (key)
                {
                    case "category": category = val; break;
                    case "link": link = val; break;
                    case "isVisible": isVisible = bool.Parse(val); break;
                    case "git": git = val; break;
                }
            }
        }
        else
        {
            body = text;
        }
    }
    else
    {
        body = text;
    }

    var html = Markdown.ToHtml(body, pipeline);

    if (title == "Overview")
    {
        overviewHtml = html;
    }
    else
    {
        games.Add(new GameDoc
        {
            Title = title,
            Category = category,
            Link = link,
            Git = git,
            ContentHtml = html,
            IsVisible = isVisible,
        });
    }
}

static string VStr(string? s) =>
    s is null ? "null" : "@\"" + s.Replace("\"", "\"\"") + "\"";

var sb = new StringBuilder();
sb.AppendLine("// <auto-generated/>");
sb.AppendLine("#nullable enable");
sb.AppendLine("namespace Model;");
sb.AppendLine();
sb.AppendLine("public static class GeneratedData");
sb.AppendLine("{");
sb.AppendLine($"    public static string? OverviewHtml => {VStr(overviewHtml)};");
sb.AppendLine();
sb.AppendLine("    public static List<GameDoc> Games => new()");
sb.AppendLine("    {");

foreach (var g in games)
{
    sb.AppendLine("        new GameDoc");
    sb.AppendLine("        {");
    sb.AppendLine($"            Title = {VStr(g.Title)},");
    sb.AppendLine($"            Category = {VStr(g.Category)},");
    sb.AppendLine($"            Link = {VStr(g.Link)},");
    sb.AppendLine($"            Git = {VStr(g.Git)},");
    sb.AppendLine($"            ContentHtml = {VStr(g.ContentHtml)},");
    sb.AppendLine($"            IsVisible = {(g.IsVisible != null && g.IsVisible.Value ? "true" : "false")},");
    sb.AppendLine("        },");
}

sb.AppendLine("    };");
sb.AppendLine("}");

File.WriteAllText(Path.Combine(outputDir, "GeneratedData.cs"), sb.ToString());

Console.WriteLine($"Generated GeneratedData.cs: {games.Count} games, overview: {overviewHtml != null}");