namespace KArtSell.Modules.SignalEngine.Domain.Policies;

public sealed class ConcentrationLiquidityPolicy : ISellPolicy
{
    public int Priority => SellPolicyContract.ConcentrationLiquidityPriority;
    public string PolicyId => SellPolicyContract.ConcentrationLiquidityPolicyId;

    public SellPolicyResult Evaluate(SellDecisionInput input)
    {
        var requested = Math.Clamp(input.ConcentrationSellRatioOfLot, 0m, 1m);
        if (requested <= 0m)
        {
            return SellPolicyResult.NotApplicable(PolicyId, Priority, "NO_CONCENTRATION_EXCESS");
        }

        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,
            "CONCENTRATION_OR_LIQUIDITY",
            input.EvidenceId,
            input.DatasetId,
            input.ModelVersion,
            input.ConfigVersion,
            input.CodeSha,
            true,
            Array.Empty<PolicyTraceEntry>());
        return SellPolicyResult.Applied(decision, requested, applied < requested);
    }
}
