using ClaudeDo.Data;
using ClaudeDo.Worker.Git;
using Microsoft.Extensions.Logging;

namespace ClaudeDo.Worker.Skills;

public sealed class SessionSkillSeeder : ISessionSkillSeeder
{
    private readonly string _skillsRoot;
    private readonly ILogger<SessionSkillSeeder> _logger;

    public SessionSkillSeeder(ILogger<SessionSkillSeeder> logger, string? skillsRoot = null)
    {
        _logger = logger;
        _skillsRoot = skillsRoot ?? Path.Combine(Paths.AppDataRoot(), "session-skills");
    }

    public async Task SeedAsync(string workingDir, IReadOnlyList<string> skillNames, bool isWorktree, CancellationToken ct)
    {
        if (skillNames.Count == 0) return;

        var skillsDestRoot = Path.Combine(workingDir, ".claude", "skills");

        foreach (var name in skillNames)
        {
            var sourceDir = Path.Combine(_skillsRoot, name);
            if (!Directory.Exists(sourceDir))
            {
                _logger.LogWarning("Session skill '{SkillName}' not found on disk at {SourceDir}; skipping", name, sourceDir);
                continue;
            }

            var destDir = Path.Combine(skillsDestRoot, name);
            CopyDirectory(sourceDir, destDir);

            if (isWorktree)
                await GitExcludeWriter.AppendLineAsync(workingDir, $"/.claude/skills/{name}/", ct);
        }
    }

    private static void CopyDirectory(string sourceDir, string destDir)
    {
        Directory.CreateDirectory(destDir);
        foreach (var file in Directory.EnumerateFiles(sourceDir, "*", SearchOption.AllDirectories))
        {
            var relative = Path.GetRelativePath(sourceDir, file);
            var destPath = Path.Combine(destDir, relative);
            var destParent = Path.GetDirectoryName(destPath);
            if (!string.IsNullOrEmpty(destParent))
                Directory.CreateDirectory(destParent);
            File.Copy(file, destPath, overwrite: true);
        }
    }

}
