from typing import Any



from models.discipline import TradeCheckRequest

from models.platform import PlatformId, TradeIntent

from services.config_sync import apply_pine_config

from services.risk_manager import RiskDecision, check_trade_request, evaluate_trade_intent

from services.trading_stats import rules_snapshot





def _to_float(value) -> float | None:

    if value is None or value == "":

        return None

    try:

        return float(value)

    except (TypeError, ValueError):

        return None





class DisciplineEngine:

    """

    Coeur du compagnon — agnostique plateforme.



    Connecteurs NinjaTrader et manuel passent par ici

    pour regles, verification et journal discipline.

    """



    def apply_config(self, payload: dict[str, Any], source: PlatformId) -> dict[str, Any]:

        applied = apply_pine_config(payload)

        return {"source": source.value, **applied}



    def check_intent(self, intent: TradeIntent, *, log: bool = True) -> RiskDecision:

        raw = intent.raw or {}

        return evaluate_trade_intent(

            action=intent.action,

            source=f"{intent.platform.value}:{intent.source}",

            ticker=intent.ticker,

            strategy=intent.strategy,

            quantity=intent.quantity,

            price=intent.price,

            stop_loss=intent.stop_loss,

            risk_usd=_to_float(raw.get("risk_usd") or raw.get("risk")),
            point_value=_to_float(raw.get("point_value") or raw.get("pointValue")),
            log=log,

        )



    def check_manual(self, body: TradeCheckRequest) -> RiskDecision:

        return check_trade_request(body)



    def snapshot(self) -> dict[str, Any]:

        return rules_snapshot()





discipline_engine = DisciplineEngine()

