"""Portfolio client for balance and position management."""

from __future__ import annotations

from typing import Any, Dict, List, Optional

from zenotc.clients.base import BaseClient
from zenotc.models.portfolio import (
    Balance,
    Exposure,
    ExposureSummary,
    PortfolioSummary,
    Position,
)


class PortfolioClient(BaseClient):
    """Client for portfolio management."""

    async def get_balances(self) -> List[Balance]:
        """Get all asset balances."""
        await self._rate_limiter.acquire()
        response = await self._http.get("/api/v1/portfolio/balances")
        return [Balance.model_validate(b) for b in response.get("balances", [])]

    async def get_balance(self, asset: str) -> Balance:
        """Get balance for a specific asset."""
        await self._rate_limiter.acquire()
        response = await self._http.get(f"/api/v1/portfolio/balances/{asset.upper()}")
        return Balance.model_validate(response)

    async def get_positions(self) -> List[Position]:
        """Get all trading positions."""
        await self._rate_limiter.acquire()
        response = await self._http.get("/api/v1/portfolio/positions")
        return [Position.model_validate(p) for p in response.get("positions", [])]

    async def get_position(self, asset: str) -> Optional[Position]:
        """Get position for a specific asset."""
        await self._rate_limiter.acquire()
        try:
            response = await self._http.get(f"/api/v1/portfolio/positions/{asset.upper()}")
            return Position.model_validate(response)
        except Exception as e:
            if hasattr(e, "status_code") and e.status_code == 404:
                return None
            raise

    async def get_exposure(self) -> ExposureSummary:
        """Get portfolio exposure summary."""
        await self._rate_limiter.acquire()
        response = await self._http.get("/api/v1/portfolio/exposure")
        return ExposureSummary.model_validate(response)

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

    async def get_summary(self) -> PortfolioSummary:
        """Get complete portfolio summary."""
        await self._rate_limiter.acquire()
        response = await self._http.get("/api/v1/portfolio/summary")
        return PortfolioSummary.model_validate(response)

    async def get_pnl(self, period: str = "24h") -> Dict[str, Any]:
        """Get P&L breakdown."""
        await self._rate_limiter.acquire()
        response = await self._http.get(
            "/api/v1/portfolio/pnl",
            params={"period": period},
        )
        return response

    async def get_transaction_history(
        self,
        asset: Optional[str] = None,
        transaction_type: Optional[str] = None,
        page: int = 1,
        limit: int = 50,
    ) -> Dict[str, Any]:
        """Get transaction history."""
        params: Dict[str, Any] = {"page": page, "limit": limit}
        if asset:
            params["asset"] = asset.upper()
        if transaction_type:
            params["type"] = transaction_type

        await self._rate_limiter.acquire()
        response = await self._http.get("/api/v1/portfolio/transactions", params=params)
        return response

    async def get_trade_history(
        self,
        asset: Optional[str] = None,
        side: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        page: int = 1,
        limit: int = 50,
    ) -> Dict[str, Any]:
        """Get trade history."""
        params: Dict[str, Any] = {"page": page, "limit": limit}
        if asset:
            params["asset"] = asset.upper()
        if side:
            params["side"] = side
        if start_date:
            params["startDate"] = start_date
        if end_date:
            params["endDate"] = end_date

        await self._rate_limiter.acquire()
        response = await self._http.get("/api/v1/portfolio/trades", params=params)
        return response

    async def get_available_for_trading(self, asset: str) -> Dict[str, Any]:
        """Get available balance for trading."""
        await self._rate_limiter.acquire()
        response = await self._http.get(f"/api/v1/portfolio/available/{asset.upper()}")
        return response
