using ClaudeDo.Data.Models;

namespace ClaudeDo.Worker.Agents;

public sealed class AgentFileService
{
    private readonly string _agentsDir;

    public AgentFileService(string agentsDir)
    {
        _agentsDir = agentsDir;
    }

    public Task<List<AgentInfo>> ScanAsync(CancellationToken ct = default)
    {
        var agents = new List<AgentInfo>();
        if (!Directory.Exists(_agentsDir))
            return Task.FromResult(agents);

        foreach (var file in Directory.EnumerateFiles(_agentsDir, "*.md"))
        {
            ct.ThrowIfCancellationRequested();
            var (name, description) = ParseFrontmatter(file);
            agents.Add(new AgentInfo(name, description, file));
        }

        agents.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
        return Task.FromResult(agents);
    }

    public async Task<string> ReadAsync(string path, CancellationToken ct = default)
    {
        return await File.ReadAllTextAsync(path, ct);
    }

    public async Task WriteAsync(string path, string content, CancellationToken ct = default)
    {
        var dir = Path.GetDirectoryName(path);
        if (dir is not null) Directory.CreateDirectory(dir);
        await File.WriteAllTextAsync(path, content, ct);
    }

    public Task DeleteAsync(string path, CancellationToken ct = default)
    {
        ct.ThrowIfCancellationRequested();
        if (File.Exists(path)) File.Delete(path);
        return Task.CompletedTask;
    }

    private static (string name, string description) ParseFrontmatter(string filePath)
    {
        var fileName = Path.GetFileNameWithoutExtension(filePath);
        string name = fileName;
        string description = "";

        try
        {
            using var reader = new StreamReader(filePath);
            var firstLine = reader.ReadLine();
            if (firstLine?.Trim() != "---")
                return (name, description);

            while (reader.ReadLine() is { } line)
            {
                if (line.Trim() == "---") break;
                if (line.StartsWith("name:"))
                    name = line["name:".Length..].Trim();
                else if (line.StartsWith("description:"))
                    description = line["description:".Length..].Trim();
            }
        }
        catch { /* Can't read file -- use filename fallback */ }

        return (name, description);
    }
}
