"""Risk client for limits and pre-trade checks."""

from __future__ import annotations

from decimal import Decimal
from typing import Any, Dict, List, Optional

from zenotc.clients.base import BaseClient
from zenotc.models.risk import (
    LimitType,
    PreTradeCheckRequest,
    PreTradeCheckResult,
    RiskLimit,
    RiskLimits,
)


class RiskClient(BaseClient):
    """Client for risk management."""

    async def get_limits(self) -> RiskLimits:
        """Get all risk limits."""
        await self._rate_limiter.acquire()
        response = await self._http.get("/api/v1/risk/limits")
        return RiskLimits.model_validate(response)

    async def get_limit(
        self, limit_type: str | LimitType, asset: Optional[str] = None
    ) -> Optional[RiskLimit]:
        """Get a specific risk limit."""
        limits = await self.get_limits()

        if isinstance(limit_type, str):
            limit_type = LimitType(limit_type)

        return limits.get_limit(limit_type, asset.upper() if asset else None)

    async def pre_trade_check(
        self,
        side: str,
        asset: str,
        quantity: float | Decimal,
        price: float | Decimal,
    ) -> PreTradeCheckResult:
        """Perform pre-trade risk check."""
        request = PreTradeCheckRequest(
            side=side.lower(),
            asset=asset.upper(),
            quantity=Decimal(str(quantity)),
            price=Decimal(str(price)),
        )

        await self._rate_limiter.acquire()
        response = await self._http.post("/api/v1/risk/pre-trade-check", json_data=request)
        return PreTradeCheckResult.model_validate(response)

    async def get_exposure(self) -> Dict[str, Any]:
        """Get current risk exposure."""
        await self._rate_limiter.acquire()
        response = await self._http.get("/api/v1/risk/exposure")
        return response

    async def get_exposure_by_asset(self, asset: str) -> Dict[str, Any]:
        """Get exposure for a specific asset."""
        await self._rate_limiter.acquire()
        response = await self._http.get(f"/api/v1/risk/exposure/{asset.upper()}")
        return response

    async def get_utilization(self) -> Dict[str, Any]:
        """Get limit utilization summary."""
        await self._rate_limiter.acquire()
        response = await self._http.get("/api/v1/risk/utilization")
        return response

    async def get_breached_limits(self) -> List[RiskLimit]:
        """Get currently breached limits."""
        limits = await self.get_limits()
        return limits.get_breached_limits()

    async def check_order_quantity(
        self, side: str, asset: str, price: float | Decimal
    ) -> Dict[str, Any]:
        """Get maximum allowed order quantity."""
        params = {
            "side": side.lower(),
            "asset": asset.upper(),
            "price": str(Decimal(str(price))),
        }

        await self._rate_limiter.acquire()
        response = await self._http.get("/api/v1/risk/max-quantity", params=params)
        return response

    async def get_risk_metrics(self) -> Dict[str, Any]:
        """Get comprehensive risk metrics."""
        await self._rate_limiter.acquire()
        response = await self._http.get("/api/v1/risk/metrics")
        return response

    async def simulate_order(
        self,
        side: str,
        asset: str,
        quantity: float | Decimal,
        price: float | Decimal,
    ) -> Dict[str, Any]:
        """Simulate order impact on risk limits."""
        request = {
            "side": side.lower(),
            "asset": asset.upper(),
            "quantity": str(Decimal(str(quantity))),
            "price": str(Decimal(str(price))),
        }

        await self._rate_limiter.acquire()
        response = await self._http.post("/api/v1/risk/simulate", json_data=request)
        return response
