"""Top-level Fireplace client."""

from __future__ import annotations

import os
from typing import Optional

from fireplace_gg._transport import Transport
from fireplace_gg.leaderboard import Leaderboard
from fireplace_gg.markets import Markets
from fireplace_gg.news import News
from fireplace_gg.profiles import Profiles
from fireplace_gg.search import Search
from fireplace_gg.stream import Stream
from fireplace_gg.trading import Trading
from fireplace_gg.wallets import Wallets


class Fireplace:
    """Fireplace External API client.

    Usage::

        from fireplace_gg import Fireplace

        fp = Fireplace(api_key="fp_pk_...", api_secret="fp_sk_...")
        events = fp.search.events(q="Bitcoin", limit=5)

        # With trading support:
        fp = Fireplace(api_key=..., api_secret=..., trading_token=...)
        fp.trading.limit_order("12345", "Yes", "BUY", 0.45, 100, 0.01)

    Parameters:
        api_key: Public API key (``fp_pk_...``). Falls back to ``FIREPLACE_API_KEY`` env var.
        api_secret: Secret API key (``fp_sk_...``). Falls back to ``FIREPLACE_API_SECRET`` env var.
        trading_token: Agent Mode bearer token. Falls back to ``FIREPLACE_TRADING_TOKEN`` env var.
            Only required for Trading API endpoints.
        base_url: Override the REST base URL.
        ws_url: Override the WebSocket URL.
        timeout: HTTP request timeout in seconds (default 30).
    """

    def __init__(
        self, api_key: Optional[str] = None, api_secret: Optional[str] = None, *,
        trading_token: Optional[str] = None,
        base_url: str = "https://data.fireplace.gg/api/v1/external",
        ws_url: str = "wss://stream.fireplace.gg",
        timeout: float = 30.0,
    ) -> None:
        resolved_key = api_key or os.environ.get("FIREPLACE_API_KEY", "")
        resolved_secret = api_secret or os.environ.get("FIREPLACE_API_SECRET", "")
        if not resolved_key or not resolved_secret:
            raise ValueError(
                "Both api_key and api_secret are required. "
                "Pass them directly or set FIREPLACE_API_KEY and FIREPLACE_API_SECRET environment variables."
            )

        resolved_trading = trading_token or os.environ.get("FIREPLACE_TRADING_TOKEN") or None

        self._transport = Transport(
            resolved_key, resolved_secret,
            base_url=base_url, timeout=timeout,
            trading_token=resolved_trading,
        )

        self.markets: Markets = Markets(self._transport)
        """Market data: metadata, candles, trades, orderbook, positions."""

        self.profiles: Profiles = Profiles(self._transport)
        """Trader profiles: portfolio overview, positions, PnL, activity."""

        self.wallets: Wallets = Wallets(self._transport)
        """Wallet-centric data: trades and net flows."""

        self.leaderboard: Leaderboard = Leaderboard(self._transport)
        """Trader leaderboard with rich filtering."""

        self.search: Search = Search(self._transport)
        """Full-text market and event search with rich filtering."""

        self.news: News = News(self._transport)
        """Market-matched news tweets with significance scoring."""

        self.trading: Trading = Trading(self._transport)
        """Programmatic trading: orders, stops, redemptions, splits, merges."""

        self.stream: Stream = Stream(resolved_key, resolved_secret, ws_url=ws_url)
        """Real-time WebSocket streams (trades, candles, market headers, news)."""

    @property
    def rate_limit(self) -> Optional[int]:
        """Max requests per second from the last response."""
        return self._transport.rate_limit

    @property
    def rate_remaining(self) -> Optional[int]:
        """Requests remaining in the current window."""
        return self._transport.rate_remaining

    @property
    def rate_reset(self) -> Optional[float]:
        """Unix timestamp when the rate-limit window resets."""
        return self._transport.rate_reset

    def close(self) -> None:
        """Close the underlying HTTP connection pool."""
        self._transport.close()

    def __enter__(self) -> "Fireplace":
        return self

    def __exit__(self, *exc: object) -> None:
        self.close()

    def __repr__(self) -> str:
        return "Fireplace(connected)"
