using System;
using System.Collections.Immutable;
using System.Linq;

namespace StellaOps.Vexer.Policy;

public interface IVexPolicyDiagnostics
{
    VexPolicyDiagnosticsReport GetDiagnostics();
}

public sealed record VexPolicyDiagnosticsReport(
    string Version,
    string RevisionId,
    string Digest,
    int ErrorCount,
    int WarningCount,
    DateTimeOffset GeneratedAt,
    ImmutableArray<VexPolicyIssue> Issues,
    ImmutableArray<string> Recommendations,
    ImmutableDictionary<string, double> ActiveOverrides);

public sealed class VexPolicyDiagnostics : IVexPolicyDiagnostics
{
    private readonly IVexPolicyProvider _policyProvider;
    private readonly TimeProvider _timeProvider;

    public VexPolicyDiagnostics(
        IVexPolicyProvider policyProvider,
        TimeProvider? timeProvider = null)
    {
        _policyProvider = policyProvider ?? throw new ArgumentNullException(nameof(policyProvider));
        _timeProvider = timeProvider ?? TimeProvider.System;
    }

    public VexPolicyDiagnosticsReport GetDiagnostics()
    {
        var snapshot = _policyProvider.GetSnapshot();
        var issues = snapshot.Issues;

        var errorCount = issues.Count(static issue => issue.Severity == VexPolicyIssueSeverity.Error);
        var warningCount = issues.Count(static issue => issue.Severity == VexPolicyIssueSeverity.Warning);
        var overrides = snapshot.ConsensusOptions.ProviderOverrides
            .OrderBy(static pair => pair.Key, StringComparer.Ordinal)
            .ToImmutableDictionary();

        var recommendations = BuildRecommendations(errorCount, warningCount, overrides);

        return new VexPolicyDiagnosticsReport(
            snapshot.Version,
            snapshot.RevisionId,
            snapshot.Digest,
            errorCount,
            warningCount,
            _timeProvider.GetUtcNow(),
            issues,
            recommendations,
            overrides);
    }

    private static ImmutableArray<string> BuildRecommendations(
        int errorCount,
        int warningCount,
        ImmutableDictionary<string, double> overrides)
    {
        var messages = ImmutableArray.CreateBuilder<string>();

        if (errorCount > 0)
        {
            messages.Add("Resolve policy errors before running consensus; defaults are used while errors persist.");
        }

        if (warningCount > 0)
        {
            messages.Add("Review policy warnings via CLI/Web diagnostics and adjust configuration as needed.");
        }

        if (overrides.Count > 0)
        {
            messages.Add($"Provider overrides active for: {string.Join(", ", overrides.Keys)}.");
        }

        messages.Add("Refer to docs/ARCHITECTURE_VEXER.md for policy upgrade and diagnostics guidance.");

        return messages.ToImmutable();
    }
}
