"""Market endpoints — ``/market/*``."""

from __future__ import annotations

from typing import Any, Dict, List, Optional, Union

from fireplace_gg._transport import Transport


class Markets:
    """Access market data: metadata, candles, trades, orderbook, positions."""

    def __init__(self, transport: Transport) -> None:
        self._t = transport

    # -- Metadata / discovery --

    def get_by_id(self, id: str) -> Dict[str, Any]:
        """Get market metadata by ID.

        Args:
            id: Market ID. **Required.**
        """
        return self._t.get("/market/get-market-by-id", params={"id": id})

    def get_event_by_id(self, id: str, *, show_active: Optional[bool] = None) -> Dict[str, Any]:
        """Get event metadata and its markets.

        Args:
            id: Event ID. **Required.**
            show_active: Filter to active markets only.
        """
        return self._t.get("/market/get-event-by-id", params={"id": id, "showActive": show_active})

    def get_by_asset_id(self, asset_ids: Union[str, List[str]]) -> Any:
        """Get markets by CLOB token asset IDs.

        Retrieve markets matching the provided CLOB token asset IDs.

        Args:
            asset_ids: Single asset ID or list of CLOB token asset IDs. **Required.**
        """
        return self._t.get("/market/get-market-by-asset-id", params={
            "assetIds": _join(asset_ids),
        })

    def overview(self, market_id: str) -> Any:
        """Get comprehensive market overview.

        Returns current prices, volume, holder counts, and metadata for a market.

        Args:
            market_id: Market ID. **Required.**
        """
        return self._t.get("/market/overview", params={"marketId": market_id})

    # -- Candles --

    def latest_candles(self, market_ids: Union[str, List[str]]) -> Any:
        """Latest OHLCV candles for one or more markets.

        Args:
            market_ids: Single market ID or list (max 100). **Required.**
        """
        return self._t.get("/market/latest-candles", params={"market_ids": _join(market_ids)})

    def historical_candles(
        self,
        market_ids: Union[str, List[str]],
        *,
        outcome: Optional[str] = None,
        start_time: Optional[int] = None,
        end_time: Optional[int] = None,
        interval: Optional[str] = None,
        include_orderbook: Optional[bool] = None,
        limit: Optional[int] = None,
        all: Optional[bool] = None,
    ) -> Any:
        """Historical candles with configurable interval.

        Set ``include_orderbook=True`` to also get bid/offer liquidity depth.

        Args:
            market_ids: Comma-separated market IDs. **Required.**
            outcome: ``"OUT1"`` or ``"OUT2"``.
            start_time: Unix timestamp (seconds).
            end_time: Unix timestamp (seconds).
            interval: ``"1m"``, ``"5m"``, ``"15m"``, ``"1h"``, ``"4h"``, ``"1d"``.
            include_orderbook: ``True`` to include orderbook depth stats.
            limit: Max candles to return.
            all: ``True`` to return all candles in range.
        """
        return self._t.get("/market/historical-candles", params={
            "market_ids": _join(market_ids), "outcome": outcome,
            "start_time": start_time, "end_time": end_time,
            "interval": interval, "include_orderbook": _bool_str(include_orderbook),
            "limit": limit, "all": _bool_str(all),
        })

    # -- Trades & volume --

    def recent_trades(
        self, market_ids: Union[str, List[str]], *,
        limit: Optional[int] = None, cursor: Optional[str] = None,
        outcome: Optional[str] = None, side: Optional[str] = None,
        min_amount: Optional[float] = None,
    ) -> Any:
        """Recent trades for given markets.

        Args:
            market_ids: Comma-separated market IDs. **Required.**
            limit: Max results.
            cursor: Pagination cursor (``blockNumber:txIndex:logIndex``).
            outcome: Filter by outcome.
            side: ``"BUY"`` or ``"SELL"``.
            min_amount: Minimum trade amount.
        """
        return self._t.get("/market/recent-trades", params={
            "market_ids": _join(market_ids), "limit": limit, "cursor": cursor,
            "outcome": outcome, "side": side, "minAmount": min_amount,
        })

    def trades_summary(
        self, market_ids: Union[str, List[str]], *,
        outcome: Optional[str] = None, side: Optional[str] = None,
        min_amount: Optional[float] = None,
    ) -> Any:
        """Aggregated volume summary for given markets.

        Returns aggregated trade statistics (count, volume, avg price).

        Args:
            market_ids: Comma-separated market IDs. **Required.**
            outcome: Filter by outcome.
            side: ``"BUY"`` or ``"SELL"``.
            min_amount: Minimum trade amount.
        """
        return self._t.get("/market/trades-summary", params={
            "market_ids": _join(market_ids), "outcome": outcome,
            "side": side, "minAmount": min_amount,
        })

    def get_volume(self, market_id: str, *, timescale: str = "ALL") -> Any:
        """Trading volume for a market.

        Args:
            market_id: Market ID. **Required.**
            timescale: ``"1H"``, ``"1D"``, ``"1W"``, ``"1M"``, ``"1Y"``, or ``"ALL"``.
                **Required** (defaults to ``"ALL"``).
        """
        return self._t.get("/market/get-volume", params={"marketId": market_id, "timescale": timescale})

    def open_interest(self, market_id: str) -> Any:
        """Open interest for a market.

        Args:
            market_id: Market ID. **Required.**
        """
        return self._t.get("/market/open-interest", params={"marketId": market_id})

    def group_open_interest(self, event_id: str) -> Any:
        """Combined open interest across all markets in an event.

        Args:
            event_id: Event ID. **Required.**
        """
        return self._t.get("/market/group-open-interest", params={"eventId": event_id})

    # -- Orderbook --

    def orderbook(self, market_id: str) -> Any:
        """Live orderbook (bids/asks) for all outcomes of a market.

        Note: This endpoint may not appear in the public Swagger docs but
        is functional via the API.

        Args:
            market_id: Market ID. **Required.**
        """
        return self._t.get("/market/orderbook", params={"marketId": market_id})

    # -- Positions & holders --

    def top_positions(
        self, market_id: str, *, limit: Optional[int] = None,
        offset: Optional[int] = None, outcome: Optional[str] = None,
        amount: Optional[str] = None,
    ) -> Any:
        """Top traders in a market by position size.

        Returns the largest positions, enriched with trader usernames and
        profile images.

        Args:
            market_id: Market ID. **Required.**
            limit: 1-1000 (default 50).
            offset: Default 0.
            outcome: Filter by outcome.
            amount: Min position: ``"100"``, ``"1k"``, ``"10k"``.
        """
        return self._t.get("/market/top-positions", params={
            "market_id": market_id, "limit": limit, "offset": offset,
            "outcome": outcome, "amount": amount,
        })

    def top_positions_stats(self, market_ids: Union[str, List[str]]) -> Any:
        """Aggregated trader statistics for given markets.

        Returns aggregate stats (total holders, total value, etc.) for
        positions across markets.

        Args:
            market_ids: Comma-separated market IDs. **Required.**
        """
        return self._t.get("/market/top-positions-stats", params={"market_ids": _join(market_ids)})

    def top_positions_by_event(
        self, event_id: str, *, limit: Optional[int] = None,
        offset: Optional[int] = None, outcome: Optional[str] = None,
        amount: Optional[str] = None,
    ) -> Any:
        """Top traders across all markets in an event.

        Args:
            event_id: Event ID. **Required.**
            limit: Max results.
            offset: Default 0.
            outcome: Filter by outcome.
            amount: Min position: ``"100"``, ``"1k"``, ``"10k"``.
        """
        return self._t.get("/market/top-positions-by-event", params={
            "event_id": event_id, "limit": limit, "offset": offset,
            "outcome": outcome, "amount": amount,
        })

    def top_holders_stats(
        self, market_id: str, *, limit: Optional[int] = None,
        all_holders_summary: Optional[bool] = None,
    ) -> Any:
        """Holder statistics and summary per outcome.

        Returns detailed holder statistics including holder breakdown by
        outcome and position size distribution.

        Args:
            market_id: Market ID. **Required.**
            limit: Max results.
            all_holders_summary: Include full summary stats for all holders.
        """
        return self._t.get("/market/top-holders-stats", params={
            "market_id": market_id, "limit": limit,
            "all_holders_summary": _bool_str(all_holders_summary),
        })

    def unique_holders(
        self, market_ids: Union[str, List[str]], *,
        outcome: Optional[str] = None, limit: Optional[int] = None,
        offset: Optional[int] = None, stats: Optional[bool] = None,
    ) -> Any:
        """Unique holder counts for given markets.

        Returns list of unique holders with optional outcome filtering,
        pagination, and per-holder stats.

        Args:
            market_ids: Comma-separated market IDs. **Required.**
            outcome: Filter by outcome.
            limit: Number of holders.
            offset: Pagination offset.
            stats: Include detailed stats per holder.
        """
        return self._t.get("/market/unique-holders", params={
            "market_ids": _join(market_ids), "outcome": outcome,
            "limit": limit, "offset": offset,
            "stats": _bool_str(stats),
        })

    def holders_summary(self, market_ids: Union[str, List[str]]) -> Any:
        """Holder counts by market and outcome.

        Args:
            market_ids: Comma-separated market IDs. **Required.**
        """
        return self._t.get("/market/holders-summary", params={"market_ids": _join(market_ids)})


def _join(value: Union[str, List[str]]) -> str:
    if isinstance(value, list):
        return ",".join(value)
    return value


def _bool_str(value: Optional[bool]) -> Optional[str]:
    if value is None:
        return None
    return "true" if value else "false"
