using System.Text.Json;

namespace ClaudeDo.Worker.Runner;

public sealed record ClaudeRunConfig(
    string? Model,
    string? SystemPrompt,
    string? AgentPath,
    string? ResumeSessionId,
    int? MaxTurns = null,
    string? PermissionMode = null,
    string? McpConfigPath = null,
    string? AllowedTools = null,
    IReadOnlyList<string>? SkillNames = null,
    string? Effort = null
)
{
    public IReadOnlyList<string> SkillNames { get; init; } = SkillNames ?? Array.Empty<string>();
}

public sealed class ClaudeArgsBuilder
{
    private static readonly string ResultSchema = JsonSerializer.Serialize(new
    {
        type = "object",
        properties = new
        {
            summary = new { type = "string" },
            files_changed = new { type = "array", items = new { type = "string" } },
            commit_type = new { type = "string" },
        },
        required = new[] { "summary" },
    });

    public IReadOnlyList<string> Build(ClaudeRunConfig config)
    {
        var args = new List<string>
        {
            "-p",
            "--output-format", "stream-json",
            "--verbose",
        };

        args.Add("--permission-mode");
        args.Add(PermissionModeResolver.Resolve(config.Model, config.PermissionMode));

        if (config.Model is not null)
        {
            args.Add("--model");
            args.Add(config.Model);
        }

        if (!string.IsNullOrWhiteSpace(config.Effort))
        {
            args.Add("--effort");
            args.Add(config.Effort);
        }

        if (config.MaxTurns is int turns && turns > 0)
        {
            args.Add("--max-turns");
            args.Add(turns.ToString());
        }

        if (config.SystemPrompt is not null)
        {
            args.Add("--append-system-prompt");
            args.Add(config.SystemPrompt);
        }

        if (config.AgentPath is not null)
        {
            var agentJson = JsonSerializer.Serialize(new[] { new { file = config.AgentPath } });
            args.Add("--agents");
            args.Add(agentJson);
        }

        args.Add("--json-schema");
        args.Add(ResultSchema);

        if (config.McpConfigPath is not null)
        {
            args.Add("--mcp-config");
            args.Add(config.McpConfigPath);
        }

        if (config.AllowedTools is not null)
        {
            args.Add("--allowedTools");
            args.Add(config.AllowedTools);
        }

        if (config.ResumeSessionId is not null)
        {
            args.Add("--resume");
            args.Add(config.ResumeSessionId);
        }

        return args;
    }
}
