"""Main BotIndex client."""

import os
from typing import Optional, Dict, Any
import httpx
from botindex.models import (
    WhaleAlertResponse,
    SignalResponse,
    ApiError,
)


DEFAULT_BASE_URL = "https://king-backend.fly.dev"


class BotIndex:
    """
    Official BotIndex Python SDK.
    
    Example:
        >>> from botindex import BotIndex
        >>> bot = BotIndex(api_key="botindex_sk_...")
        >>> whales = bot.hyperliquid.whale_alerts()
    """
    
    def __init__(self, api_key: Optional[str] = None, base_url: Optional[str] = None):
        """
        Initialize BotIndex client.
        
        Args:
            api_key: Your BotIndex API key. Get free at https://api.botindex.dev/api/botindex/keys/register?plan=free
            base_url: Optional custom API base URL
        """
        self.api_key = api_key or os.environ.get("BOTINDEX_API_KEY")
        if not self.api_key:
            raise ApiError(
                "API key required. Get free at: "
                "https://api.botindex.dev/api/botindex/keys/register?plan=free "
                "or set BOTINDEX_API_KEY environment variable"
            )
        
        self.base_url = (base_url or os.environ.get("BOTINDEX_URL", DEFAULT_BASE_URL)).rstrip("/")
        self._client = httpx.Client(
            base_url=self.base_url,
            headers={"X-API-Key": self.api_key, "Accept": "application/json"},
            timeout=30.0,
        )
        
        # Sub-clients
        self.hyperliquid = HyperliquidClient(self)
        self.v1 = V1Client(self)
        self.zora = ZoraClient(self)
        self.doppler = DopplerClient(self)
        self.compliance = ComplianceClient(self)
        self.alpha = AlphaClient(self)
        self.discovery = DiscoveryClient(self)
    
    def _request(self, method: str, path: str, params: Optional[Dict] = None) -> Dict[str, Any]:
        """Make authenticated request to BotIndex API."""
        response = self._client.request(method, path, params=params)
        
        if response.status_code == 401:
            raise ApiError("Invalid API key. Check your BOTINDEX_API_KEY.")
        if response.status_code == 429:
            raise ApiError("Rate limit exceeded. Upgrade at https://botindex.dev")
        if response.status_code == 402:
            data = response.json()
            raise ApiError(
                f"Payment required: {data.get('message', 'This endpoint requires x402 payment')}"
            )
        
        response.raise_for_status()
        return response.json()
    
    def __enter__(self):
        return self
    
    def __exit__(self, *args):
        self._client.close()
    
    def close(self):
        """Close HTTP client."""
        self._client.close()


class HyperliquidClient:
    """Hyperliquid exchange data."""
    
    def __init__(self, client: BotIndex):
        self._client = client
    
    def whale_alerts(self) -> WhaleAlertResponse:
        """
        Get whale alert summary — top positions and recent trade count. FREE.
        
        Tracks $187M+ in whale positions across top Hyperliquid traders.
        """
        data = self._client._request("GET", "/api/botindex/hyperliquid/whale-alerts")
        return WhaleAlertResponse(**data)
    
    def whale_alerts_full(self) -> WhaleAlertResponse:
        """
        Get full whale positions + recent large trades. $0.05 per call.
        
        Includes entry prices, leverage, unrealized PnL, liquidation levels,
        and 24h trade history for all tracked whales.
        """
        data = self._client._request("GET", "/api/botindex/hyperliquid/whale-alerts/full")
        return WhaleAlertResponse(**data)
    
    def funding_arb(self) -> Dict[str, Any]:
        """
        Funding rate arbitrage opportunities. $0.05 per call.
        
        Cross-exchange funding rate discrepancies for delta-neutral yield.
        """
        return self._client._request("GET", "/api/botindex/hyperliquid/funding-arb")
    
    def correlation_matrix(self) -> Dict[str, Any]:
        """
        Perpetual correlation matrix. $0.05 per call.
        
        Price correlation between perp pairs for portfolio construction.
        """
        return self._client._request("GET", "/api/botindex/hyperliquid/correlation-matrix")
    
    def liquidation_heatmap(self) -> Dict[str, Any]:
        """
        Liquidation cluster heatmap by price level. $0.05 per call."""
        return self._client._request("GET", "/api/botindex/hyperliquid/liquidation-heatmap")


class V1Client:
    """Core v1 API endpoints."""
    
    def __init__(self, client: BotIndex):
        self._client = client
    
    def signals(self) -> Dict[str, Any]:
        """
        Aggregated premium signals. $0.10 per call.
        
        Correlation leaders + prediction arbitrage + market heatmap.
        """
        return self._client._request("GET", "/api/botindex/v1/signals")
    
    def discover(self) -> Dict[str, Any]:
        """Get full API catalog — all endpoints, pricing. FREE."""
        return self._client._request("GET", "/api/botindex/v1/")


class ZoraClient:
    """Zora attention market data."""
    
    def __init__(self, client: BotIndex):
        self._client = client
    
    def trending_coins(self, limit: Optional[int] = None) -> Dict[str, Any]:
        """Trending Zora attention market coins. $0.03 per call."""
        params = {"limit": limit} if limit else None
        return self._client._request("GET", "/api/botindex/zora/trending-coins", params)
    
    def creator_scores(self, limit: Optional[int] = None) -> Dict[str, Any]:
        """Creator performance scores. $0.03 per call."""
        params = {"limit": limit} if limit else None
        return self._client._request("GET", "/api/botindex/zora/creator-scores", params)
    
    def attention_momentum(self, limit: Optional[int] = None) -> Dict[str, Any]:
        """Attention momentum — accelerating trends. $0.03 per call."""
        params = {"limit": limit} if limit else None
        return self._client._request("GET", "/api/botindex/zora/attention-momentum", params)


class DopplerClient:
    """Doppler token launch data."""
    
    def __init__(self, client: BotIndex):
        self._client = client
    
    def launches(self, limit: Optional[int] = None) -> Dict[str, Any]:
        """Recent Doppler token launches on Base. $0.01 per call."""
        params = {"limit": limit} if limit else None
        return self._client._request("GET", "/api/botindex/doppler/launches", params)


class ComplianceClient:
    """Regulatory compliance & OSINT intelligence."""
    
    def __init__(self, client: BotIndex):
        self._client = client
    
    def headlines(self) -> Dict[str, Any]:
        """
        Latest crypto regulatory headlines from 24+ sources. FREE.
        
        SEC filings, CFTC actions, global regulatory news.
        """
        return self._client._request("GET", "/api/botindex/compliance/headlines")
    
    def signal_desk(self) -> Dict[str, Any]:
        """
        DeepSeek-powered compliance verdicts: COPY / IGNORE / COUNTER.
        
        Free: teaser with top verdict. Paid: full analysis with reasoning.
        """
        return self._client._request("GET", "/api/botindex/compliance/signal-desk")
    
    def threat_radar(self) -> Dict[str, Any]:
        """
        Overall regulatory threat score with enforcement tracker.
        
        Jurisdiction risk map (US/EU/APAC/LATAM), active enforcements,
        safe harbors, builder advice.
        
        Free: threat level + trend only. Paid: full report.
        """
        return self._client._request("GET", "/api/botindex/compliance/threat-radar")
    
    def exposure(self, project: str) -> Dict[str, Any]:
        """
        Per-project regulatory exposure scan.
        
        Args:
            project: Protocol/project name (e.g., "uniswap", "polymarket")
        
        Returns exposure level, score, active actions, risk factors.
        Free: score + level only. Paid: full details.
        """
        return self._client._request("GET", "/api/botindex/compliance/exposure", {"project": project})
    
    def overview(self) -> Dict[str, Any]:
        """
        Lightweight compliance snapshot. FREE. No DeepSeek call.
        
        Headline count + signal desk summary + threat level + top jurisdictions.
        """
        return self._client._request("GET", "/api/botindex/compliance/overview")


class AlphaClient:
    """Cross-signal intelligence."""
    
    def __init__(self, client: BotIndex):
        self._client = client
    
    def scan(self, q: str) -> Dict[str, Any]:
        """
        Alpha Scan — cross-signal convergence analysis. $0.10 per call.
        
        Args:
            q: Search query (e.g., "polymarket election", "eth funding rate")
        
        DeepSeek-powered multi-source intelligence synthesis.
        """
        return self._client._request("GET", "/api/botindex/alpha-scan", {"q": q})


class DiscoveryClient:
    """Agorion agent service discovery."""
    
    def __init__(self, client: BotIndex):
        self._client = client
    
    def discover(self, q: Optional[str] = None) -> Dict[str, Any]:
        """
        Find healthy agent service providers. FREE.
        
        Args:
            q: Optional capability search (e.g., "crypto", "compliance")
        """
        params = {"q": q} if q else None
        return self._client._request("GET", "/api/agorion/discover", params)
    
    def providers(self, q: Optional[str] = None) -> Dict[str, Any]:
        """List all indexed providers. FREE."""
        params = {"q": q} if q else None
        return self._client._request("GET", "/api/agorion/providers", params)
    
    def stats(self) -> Dict[str, Any]:
        """Registry statistics and health summary. FREE."""
        return self._client._request("GET", "/api/agorion/stats")
