"""Futures (期货) contract and market data API module.

All K-line responses use TianQin (天勤/TqSdk) compatible field format:
    - Daily/weekly/monthly: datetime, open, high, low, close, volume, open_oi, close_oi, amount, settle
    - 5min/15min: datetime, open, high, low, close, volume, open_oi, close_oi
    - Tick: datetime, last_price, highest, lowest, volume, amount, open_interest, bid_price1, bid_volume1, ...
"""


class FuturesAPI:
    """Access futures market data (port 5001).

    All K-line data uses TianQin-compatible field names:
    ``datetime, open, high, low, close, volume, open_oi, close_oi``.

    Available via ``client.futures``.
    """

    def __init__(self, client):
        self._client = client

    def _request(self, method, path, **kwargs):
        """Route to futures backend URL if configured."""
        return self._client._request(
            method, path, _base_url=self._client.futures_url, **kwargs
        )

    # ------------------------------------------------------------------
    # Market-level endpoints
    # ------------------------------------------------------------------

    def overview(self) -> dict:
        """Get futures market overview with top contracts and summary stats."""
        return self._request("GET", "/api/market/overview")

    def indices(self) -> dict:
        """Get main contract quotes for all products."""
        return self._request("GET", "/api/market/indices")

    def sectors(self) -> dict:
        """Get market data aggregated by exchange (SHFE, DCE, CZCE, etc.)."""
        return self._request("GET", "/api/market/sectors")

    def gainers(self) -> dict:
        """Get futures gainers. Returns all results."""
        return self._request("GET", "/api/market/gainers")

    def losers(self) -> dict:
        """Get futures losers. Returns all results."""
        return self._request("GET", "/api/market/losers")

    def market_scan(self) -> dict:
        """Market scanner showing volume surges and open interest changes."""
        return self._request("GET", "/api/market/market-scan")

    # ------------------------------------------------------------------
    # Contract-level endpoints
    # ------------------------------------------------------------------

    def contracts(
        self,
        page: int = None,
        per_page: int = None,
        exchange: str = None,
        product: str = None,
        main_only: bool = None,
    ) -> dict:
        """Get contract list with pagination and filtering.

        Args:
            page: Page number (default 1).
            per_page: Results per page (default 50, max 200).
            exchange: Filter by exchange (SHFE, DCE, CZCE, CFFEX, INE, GFEX).
            product: Filter by product code (rb, ic, i, etc.).
            main_only: Show only continuous main contracts.
        """
        params = {
            "page": page,
            "per_page": per_page,
            "exchange": exchange,
            "product": product,
        }
        if main_only is not None:
            params["main_only"] = 1 if main_only else 0
        return self._request("GET", "/api/stock/list", params=params)

    def search(self, q: str) -> dict:
        """Search contracts by symbol or name (supports Chinese).

        Args:
            q: Search keyword.
        """
        return self._request("GET", "/api/stock/search", params={"q": q})

    def basic(self, symbol: str) -> dict:
        """Get contract basic information (multiplier, price tick, exchange).

        Args:
            symbol: Contract symbol (e.g. ``rb2510``, ``IF2504``).
        """
        return self._request("GET", f"/api/stock/{symbol}/basic")

    def price(self, symbol: str) -> dict:
        """Get latest quote for a contract.

        Args:
            symbol: Contract symbol.
        """
        return self._request("GET", f"/api/stock/{symbol}/price")

    def daily(
        self,
        symbol: str,
        start_date: str = None,
        end_date: str = None,
    ) -> dict:
        """Get daily K-line history (TianQin format).

        Response fields per bar:
            datetime, open, high, low, close, volume, open_oi, close_oi,
            amount, settle, pre_settle, pre_close

        Args:
            symbol: Contract symbol, e.g. ``rb2510``, ``IF2504``.
            start_date: Start date (YYYYMMDD). Defaults to 120 days ago.
            end_date: End date (YYYYMMDD). Defaults to today.
        """
        return self._request("GET", f"/api/stock/{symbol}/daily", params={
            "start_date": start_date, "end_date": end_date,
        })

    def indicators(self, symbol: str) -> dict:
        """Get technical indicators (MA5, MA10, MA20, MA60).

        Args:
            symbol: Contract symbol.
        """
        return self._request("GET", f"/api/stock/{symbol}/indicators")

    def indicators_latest(self, symbol: str) -> dict:
        """Get latest single technical indicator bar.

        Args:
            symbol: Contract symbol.
        """
        return self._request("GET", f"/api/stock/{symbol}/indicators/latest")

    def kline(
        self,
        symbol: str,
        period: str = None,
        start_date: str = None,
        end_date: str = None,
    ) -> dict:
        """Get minute-level K-line data (TianQin format).

        Response fields per bar:
            datetime, open, high, low, close, volume, open_oi, close_oi

        Args:
            symbol: Contract symbol, e.g. ``rb2510``, ``IF2504``.
            period: Bar period (``5min`` or ``15min``). Default ``5min``.
            start_date: Start datetime (YYYY-MM-DD HH:MM:SS). Defaults to server default.
            end_date: End datetime (YYYY-MM-DD HH:MM:SS). Defaults to today.
        """
        return self._request("GET", f"/api/contract/{symbol}/kline", params={
            "period": period, "start_date": start_date, "end_date": end_date,
        })

    def kline_unified(
        self,
        symbol: str,
        freq: str = "daily",
        start_date: str = None,
        end_date: str = None,
    ) -> dict:
        """Get K-line data at any frequency via unified endpoint (TianQin format).

        Supports all granularities: tick, 5min, 15min, daily, weekly, monthly.
        Weekly and monthly bars are aggregated from daily data on-the-fly.

        Response fields:
            - daily/weekly/monthly: datetime, open, high, low, close, volume,
              open_oi, close_oi, amount, settle
            - 5min/15min: datetime, open, high, low, close, volume, open_oi, close_oi
            - tick: datetime, last_price, highest, lowest, volume, amount,
              open_interest, bid_price1, bid_volume1, ask_price1, ask_volume1

        Args:
            symbol: Contract symbol, e.g. ``rb2510``, ``IF2504``.
            freq: Frequency — ``tick``, ``5min``, ``15min``, ``daily``,
                  ``weekly``, or ``monthly``. Default ``daily``.
            start_date: Start date/datetime. Defaults to server default.
            end_date: End date/datetime. Defaults to today.
        """
        return self._request("GET", f"/api/contract/{symbol}/kline-unified", params={
            "freq": freq, "start_date": start_date, "end_date": end_date,
        })
