from __future__ import annotations

import uuid

from .models import OrderIntent, OrderResult, RiskDecision, TradingMode


def build_client_order_id(prefix: str = "bq") -> str:
    return f"{prefix}-{uuid.uuid4().hex[:24]}"


def order_intent_from_decision(decision: RiskDecision) -> OrderIntent:
    if not decision.approved or decision.signal.side is None or decision.quote_amount is None:
        raise ValueError("approved risk decision with side and quote_amount is required")
    return OrderIntent(
        symbol=decision.signal.symbol,
        side=decision.signal.side,
        quote_amount=decision.quote_amount,
        client_order_id=build_client_order_id(),
    )


class ExecutionEngine:
    def __init__(self, mode: TradingMode, exchange_client) -> None:
        self.mode = mode
        self.exchange_client = exchange_client

    def execute(self, intent: OrderIntent) -> OrderResult:
        if self.mode is TradingMode.DRY_RUN:
            return OrderResult(
                symbol=intent.symbol,
                side=intent.side,
                client_order_id=intent.client_order_id,
                status="DRY_RUN",
                raw={
                    "symbol": intent.symbol,
                    "side": intent.side.value,
                    "quoteOrderQty": str(intent.quote_amount),
                    "clientOrderId": intent.client_order_id,
                },
                dry_run=True,
            )
        if self.mode in {TradingMode.TESTNET_LIVE, TradingMode.LIVE}:
            payload = self.exchange_client.create_market_order(
                intent.symbol,
                intent.side,
                intent.quote_amount,
                intent.client_order_id,
            )
            return OrderResult(
                symbol=intent.symbol,
                side=intent.side,
                client_order_id=intent.client_order_id,
                status=payload.get("status", "UNKNOWN"),
                raw=payload,
                dry_run=False,
            )
        raise ValueError(f"unsupported trading mode: {self.mode}")
