namespace KArtSell.Modules.SignalEngine.Domain.Policies;

/// <summary>Capital-floor protection may cross the strategic core because survival outranks profit protection.</summary>
public sealed class PortfolioSurvivalPolicy : ISellPolicy
{
    public int Priority => SellPolicyContract.PortfolioSurvivalPriority;
    public string PolicyId => SellPolicyContract.PortfolioSurvivalPolicyId;

    public SellPolicyResult Evaluate(SellDecisionInput input)
    {
        if (!input.CapitalFloorBreached)
        {
            return SellPolicyResult.NotApplicable(PolicyId, Priority, "CAPITAL_FLOOR_NOT_BREACHED");
        }

        var requested = Math.Clamp(input.SurvivalSellRatioOfLot, 0m, 1m);
        if (!input.CooldownSatisfied)
        {
            return SellPolicyResult.Blocked(PolicyId, Priority, "COOLDOWN_NOT_SATISFIED", requested);
        }

        if (requested <= 0m)
        {
            return SellPolicyResult.Blocked(PolicyId, Priority, "SURVIVAL_RATIO_NOT_POSITIVE", requested);
        }

        var action = requested >= 1m ? SellAction.FullSell : SellAction.PartialSell;
        var decision = new SellDecision(
            action,
            requested,
            input.TargetSecurityPortfolioWeightAfter(requested),
            PolicyId,
            Priority,
            "PORTFOLIO_SURVIVAL",
            input.EvidenceId,
            input.DatasetId,
            input.ModelVersion,
            input.ConfigVersion,
            input.CodeSha,
            true,
            Array.Empty<PolicyTraceEntry>());
        return SellPolicyResult.Applied(decision, requested, false);
    }
}
