namespace KArtSell.Modules.ModelOperations.Domain;

/// <summary>
/// Evidence gate only. It never activates, promotes, rolls back or mutates a model.
/// </summary>
public sealed class PromotionGateEvaluator
{
    public static PromotionGateResult Evaluate(ModelEvaluationSnapshot snapshot, PromotionGateThresholds thresholds)
    {
        var blockers = new List<string>();
        var warnings = new List<string>();

        if (snapshot.OperationalIntegrityErrors != 0)
            blockers.Add("Operational integrity errors must be zero.");
        if (snapshot.ShadowTradingDays < thresholds.MinimumShadowTradingDays)
            blockers.Add($"Shadow evidence requires at least {thresholds.MinimumShadowTradingDays} trading days.");
        if (snapshot.DistinctRegimes < thresholds.MinimumDistinctRegimes)
            blockers.Add($"At least {thresholds.MinimumDistinctRegimes} distinct market regimes are required.");
        if (snapshot.NetExpectedUtility <= 0)
            blockers.Add("Net expected utility after costs must be positive.");
        if (!snapshot.CalibrationStable)
            blockers.Add("Calibration is not stable against the approved baseline.");
        if (snapshot.FalseExitAnnualRate > thresholds.MaximumFalseExitAnnualRate)
            blockers.Add("False-exit annual rate exceeds the approved threshold.");
        if (snapshot.ReentryCaptureRate < thresholds.MinimumReentryCaptureRate)
            blockers.Add("Reentry capture rate is below the approved threshold.");
        if (snapshot.Pbo > thresholds.MaximumPbo)
            blockers.Add("Probability of backtest overfitting exceeds the approved threshold.");
        if (snapshot.Dsr < thresholds.MinimumDsr)
            blockers.Add("Deflated Sharpe Ratio is below the approved threshold.");
        if (!snapshot.PositiveUnderDoubleCost)
            blockers.Add("Expected utility is not positive under the 2x cost stress.");

        if (snapshot.ShadowTradingDays < 504)
            warnings.Add("Evidence is below the preferred 24-month horizon.");

        return new PromotionGateResult(
            blockers.Count == 0 ? GateDecision.Pass : GateDecision.Hold,
            blockers,
            warnings,
            RequiresIndependentValidation: true,
            RequiresHumanApproval: true,
            Boundary: "EVIDENCE_ONLY_NO_AUTO_PROMOTION");
    }
}
