"""CoinMarketCap data provider."""

from typing import Any

from pydantic import BaseModel

from .base import Provider, ProviderData


class CoinMarketCapData(ProviderData):
    """CoinMarketCap specific data."""

    provider: str = "coinmarketcap"
    current_price: float | None = None
    market_cap: float | None = None
    total_volume: float | None = None
    price_change_24h: float | None = None
    price_change_7d: float | None = None
    price_change_30d: float | None = None
    market_cap_dominance: float | None = None
    circulating_supply: float | None = None
    total_supply: float | None = None
    cmc_rank: int | None = None


class CoinMarketCapProvider(Provider):
    """CoinMarketCap API provider for price and market data."""

    name = "coinmarketcap"
    base_url = "https://pro-api.coinmarketcap.com/v1"
    requires_auth = True

    def _get_auth_headers(self) -> dict[str, str]:
        """Get authentication headers."""
        if self.api_key:
            return {"X-CMC_PRO_API_KEY": self.api_key}
        return {}

    async def fetch_data(self, symbol: str) -> CoinMarketCapData:
        """Fetch market data for a coin."""
        data = await self.get(
            "/cryptocurrency/quotes/latest",
            params={"symbol": symbol.upper(), "convert": "USD"},
        )

        coins = data.get("data", {})
        if not coins:
            return CoinMarketCapData(symbol=symbol.upper(), raw_data={})

        # Get first match for symbol
        coin_data = list(coins.values())[0] if coins else {}
        quote = coin_data.get("quote", {}).get("USD", {})

        return CoinMarketCapData(
            symbol=symbol.upper(),
            current_price=quote.get("price"),
            market_cap=quote.get("market_cap"),
            total_volume=quote.get("volume_24h"),
            price_change_24h=quote.get("percent_change_24h"),
            price_change_7d=quote.get("percent_change_7d"),
            price_change_30d=quote.get("percent_change_30d"),
            market_cap_dominance=quote.get("market_cap_dominance"),
            circulating_supply=coin_data.get("circulating_supply"),
            total_supply=coin_data.get("total_supply"),
            cmc_rank=coin_data.get("cmc_rank"),
            raw_data=coin_data,
        )

    async def fetch_global_metrics(self) -> dict[str, Any]:
        """Fetch global market metrics."""
        data = await self.get("/global-metrics/quotes/latest")
        return data.get("data", {})
