namespace KArtSell.Modules.SignalEngine.Domain.Policies;

public sealed class TwoCloseFloorBreachPolicy : ISellPolicy
{
    public int Priority => SellPolicyContract.TwoCloseFloorBreachPriority;
    public string PolicyId => SellPolicyContract.TwoCloseFloorBreachPolicyId;

    public SellPolicyResult Evaluate(SellDecisionInput input)
    {
        const decimal requested = SellPolicyContract.TwoCloseSellRatioOfLot;
        if (input.ConsecutiveCloseBreaches < SellPolicyContract.TwoCloseBreachCount)
        {
            return SellPolicyResult.NotApplicable(PolicyId, Priority, "TWO_CLOSE_NOT_CONFIRMED");
        }

        if (!input.CooldownSatisfied)
        {
            return SellPolicyResult.Blocked(PolicyId, Priority, "COOLDOWN_NOT_SATISFIED", requested);
        }

        var max = input.MaxSellRatioPreservingStrategicCore();
        var applied = Math.Min(requested, max);
        if (applied <= 0m)
        {
            return SellPolicyResult.Blocked(PolicyId, Priority, "STRATEGIC_CORE_BLOCKED", requested);
        }

        var decision = new SellDecision(
            SellAction.PartialSell,
            applied,
            input.TargetSecurityPortfolioWeightAfter(applied),
            PolicyId,
            Priority,
            "TWO_CLOSE_FLOOR_BREACH",
            input.EvidenceId,
            input.DatasetId,
            input.ModelVersion,
            input.ConfigVersion,
            input.CodeSha,
            true,
            Array.Empty<PolicyTraceEntry>());
        return SellPolicyResult.Applied(decision, requested, applied < requested);
    }
}
