"""Bybit Live Execution Adapter with Hard Locks & Multi-Stage Safeguards."""
from __future__ import annotations

from datetime import datetime, timezone
from decimal import Decimal
from typing import Any, Optional

from backend.app.audit.logger import audit_logger
from backend.app.config.settings import TradingMode, settings
from backend.app.market_data.bybit_client import BybitV5Client
from backend.app.risk.kill_switch import kill_switch
from backend.app.schemas.order import OrderIntent, OrderResult, OrderStatus


class BybitLiveExecutionAdapter:
    """Executes trades against Bybit Mainnet only after verified authorization."""

    def __init__(self) -> None:
        self._check_safety_locks()
        self.client = BybitV5Client(mode=TradingMode.LIVE)

    def _check_safety_locks(self) -> None:
        if not settings.ENABLE_LIVE_TRADING:
            raise PermissionError(
                "CRITICAL SECURITY LOCK: Live trading is disabled by default via ENABLE_LIVE_TRADING=False."
            )
        if settings.TRADING_MODE != TradingMode.LIVE:
            raise PermissionError(
                f"MODE MISMATCH: Live adapter invoked while TRADING_MODE is {settings.TRADING_MODE.value}."
            )
        if not settings.BYBIT_LIVE_API_KEY or not settings.BYBIT_LIVE_API_SECRET:
            raise ValueError("Live Bybit API keys are missing.")

    def execute_order(self, intent: OrderIntent) -> OrderResult:
        self._check_safety_locks()

        if kill_switch.is_active():
            return OrderResult(
                client_order_id=intent.client_order_id,
                exchange_order_id=None,
                status=OrderStatus.REJECTED,
                message="Live order blocked: Emergency Kill Switch is engaged.",
            )

        try:
            res = self.client.place_order(
                symbol=intent.symbol,
                side=intent.side.value,
                order_type=intent.order_type.value,
                qty=str(intent.quantity),
                price=str(intent.price) if intent.price else None,
                stop_loss=str(intent.stop_loss) if intent.stop_loss else None,
                take_profit=str(intent.take_profit) if intent.take_profit else None,
                client_order_id=intent.client_order_id,
                reduce_only=intent.reduce_only,
            )

            if res.get("retCode") == 0:
                order_id = res.get("result", {}).get("orderId")
                audit_logger.critical("LIVE ORDER EXECUTED ON BYBIT MAINNET: %s (Exchange ID: %s)", intent.client_order_id, order_id)
                return OrderResult(
                    client_order_id=intent.client_order_id,
                    exchange_order_id=order_id,
                    status=OrderStatus.ACCEPTED,
                    filled_qty=intent.quantity,
                    avg_price=intent.price or Decimal("0"),
                    message="Live order accepted on Bybit Mainnet.",
                )
            else:
                err_msg = res.get("retMsg", "Unknown error")
                audit_logger.error("Live order rejected by Bybit: %s", err_msg)
                return OrderResult(
                    client_order_id=intent.client_order_id,
                    exchange_order_id=None,
                    status=OrderStatus.REJECTED,
                    message=f"Live order rejected: {err_msg}",
                )

        except Exception as e:
            audit_logger.critical("Live order execution network exception: %s", str(e))
            return OrderResult(
                client_order_id=intent.client_order_id,
                exchange_order_id=None,
                status=OrderStatus.UNKNOWN,
                message=f"Ambiguous live order state: {str(e)}. Manual reconciliation required.",
            )


bybit_live_adapter: Optional[BybitLiveExecutionAdapter] = None
if settings.ENABLE_LIVE_TRADING and settings.TRADING_MODE == TradingMode.LIVE:
    try:
        bybit_live_adapter = BybitLiveExecutionAdapter()
    except Exception as e:
        audit_logger.error("Could not initialize live adapter: %s", str(e))
