using ClaudeDo.Data;
using ClaudeDo.Worker.Hub;

namespace ClaudeDo.Worker.Lifecycle;

/// <summary>
/// Startup-only sweep: drops any prompt override file that only matched a now-superseded
/// bundled default and was never actually edited (see <see cref="PromptFiles.ReconcileStaleDefaults"/>),
/// and quarantines any *.md file under the prompts root that no longer maps to a known
/// <see cref="PromptKind"/> (leftovers from a retired naming scheme).
/// </summary>
public sealed class PromptFileRecovery : IHostedService
{
    public const string Phase = "prompt-files";

    private readonly ILogger<PromptFileRecovery> _logger;
    private readonly HubBroadcaster _broadcaster;
    private readonly string? _root;

    public PromptFileRecovery(ILogger<PromptFileRecovery> logger, HubBroadcaster broadcaster, string? root = null)
    {
        _logger = logger;
        _broadcaster = broadcaster;
        _root = root;
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        PromptFiles.ReconcileStaleDefaults(_root);

        var orphans = PromptFiles.QuarantineOrphans(_root);
        if (orphans.Count == 0)
        {
            _logger.LogInformation("Prompt file recovery: no orphaned prompt files found");
            await _broadcaster.OperationProgress(OperationProgressOpKeys.StartupRecovery, Phase, 0, 0);
            return;
        }

        foreach (var orphan_path in orphans)
        {
            _logger.LogWarning("Prompt file recovery: quarantined orphaned prompt file {orphan_path}", orphan_path);
            if (Path.GetFileNameWithoutExtension(orphan_path)
                    .StartsWith("merge-helper-execute", StringComparison.OrdinalIgnoreCase))
                _logger.LogWarning(
                    "Prompt file recovery: {orphan_path} was a customization of the retired merge-helper-execute.md prompt, which was split into merge-helper-wait.md and merge-helper-merge.md; its content was not migrated to either",
                    orphan_path);
        }

        await _broadcaster.OperationProgress(OperationProgressOpKeys.StartupRecovery, Phase, orphans.Count, orphans.Count);
    }

    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
