"""Trading API — programmatic orders, stops, redemptions, splits, merges.

Requires an Agent Mode bearer token (separate from data API keys).
"""

from __future__ import annotations

from typing import Any, Dict, List, Optional

from fireplace_gg._transport import Transport


class Trading:
    """Programmatic trading on Fireplace / Polymarket.

    All mutating methods use POST with Bearer-token auth.
    Query methods (open_orders, order_status) use GET.

    Usage::

        fp = Fireplace(api_key=..., api_secret=..., trading_token=...)
        fp.trading.limit_order("12345", "Yes", "BUY", price=0.45, size=100, tick_size=0.01)
    """

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

    def _post(self, path: str, payload: Dict[str, Any]) -> Any:
        return self._t.post(path, payload, headers=self._t._trading_headers())

    def _get(self, path: str, params: Optional[Dict[str, Any]] = None) -> Any:
        return self._t.get(path, params, headers=self._t._trading_headers())

    # ── Order placement ──────────────────────────────────────────────

    def market_order(
        self,
        market_id: str,
        outcome: str,
        side: str,
        amount: float,
        *,
        order_type: str = "FOK",
        exit_orders: Optional[List[Dict[str, Any]]] = None,
    ) -> Any:
        """Place a market order (Fill-or-Kill or Fill-and-Kill).

        Args:
            market_id: Market ID. **Required.**
            outcome: Outcome label (e.g. ``"Yes"``, ``"Blackhawks"``). **Required.**
            side: ``"BUY"`` or ``"SELL"``. **Required.**
            amount: USDC amount. **Required.**
            order_type: ``"FOK"`` (default) or ``"FAK"``.
            exit_orders: Optional TP/SL exit orders attached to BUY orders.
        """
        payload: Dict[str, Any] = {
            "order": {
                "marketId": market_id,
                "outcome": outcome,
                "side": side,
                "amount": amount,
            },
            "orderType": order_type,
        }
        if exit_orders:
            payload["exitOrders"] = exit_orders
        return self._post("/trading/market-order", payload)

    def limit_order(
        self,
        market_id: str,
        outcome: str,
        side: str,
        price: float,
        size: float,
        tick_size: float,
        *,
        expiration: Optional[int] = None,
        exit_orders: Optional[List[Dict[str, Any]]] = None,
    ) -> Any:
        """Place a GTC or GTD limit order.

        Args:
            market_id: Market ID. **Required.**
            outcome: Outcome label. **Required.**
            side: ``"BUY"`` or ``"SELL"``. **Required.**
            price: Limit price (0-1). **Required.**
            size: Number of shares (min 5). **Required.**
            tick_size: Price tick size (e.g. ``0.01``). **Required.**
            expiration: Unix timestamp for GTD orders (must be >=90s in the future).
            exit_orders: Optional TP/SL exit orders attached to BUY orders.
        """
        payload: Dict[str, Any] = {
            "order": {
                "marketId": market_id,
                "outcome": outcome,
                "side": side,
                "price": price,
                "size": size,
                "tickSize": tick_size,
            },
        }
        if expiration is not None:
            payload["expiration"] = expiration
        if exit_orders:
            payload["exitOrders"] = exit_orders
        return self._post("/trading/limit-order", payload)

    def stop_market(
        self,
        market_id: str,
        outcome: str,
        side: str,
        amount: float,
        trigger_price: float,
    ) -> Any:
        """Create a stop market order.

        Args:
            market_id: Market ID. **Required.**
            outcome: Outcome label. **Required.**
            side: ``"BUY"`` or ``"SELL"``. **Required.**
            amount: USDC amount. **Required.**
            trigger_price: Price that triggers execution. **Required.**
        """
        return self._post("/trading/stop-market", {
            "marketId": market_id,
            "outcome": outcome,
            "side": side,
            "amount": amount,
            "triggerPrice": trigger_price,
        })

    def stop_limit(
        self,
        market_id: str,
        outcome: str,
        side: str,
        size: float,
        trigger_price: float,
        limit_price: float,
        tick_size: float,
    ) -> Any:
        """Create a stop limit order.

        Args:
            market_id: Market ID. **Required.**
            outcome: Outcome label. **Required.**
            side: ``"BUY"`` or ``"SELL"``. **Required.**
            size: Number of shares. **Required.**
            trigger_price: Price that triggers the limit order. **Required.**
            limit_price: Limit price once triggered. **Required.**
            tick_size: Price tick size. **Required.**
        """
        return self._post("/trading/stop-limit", {
            "marketId": market_id,
            "outcome": outcome,
            "side": side,
            "size": size,
            "triggerPrice": trigger_price,
            "limitPrice": limit_price,
            "tickSize": tick_size,
        })

    # ── Order management ─────────────────────────────────────────────

    def cancel_order(self, order_id: str) -> Any:
        """Cancel a single order.

        Args:
            order_id: The order ID to cancel. **Required.**
        """
        return self._post("/trading/cancel-order", {"orderId": order_id})

    def cancel_all(self, *, market_id: Optional[str] = None) -> Any:
        """Cancel all open orders, optionally filtered to a market.

        Args:
            market_id: If provided, only cancel orders for this market.
        """
        payload: Dict[str, Any] = {}
        if market_id is not None:
            payload["marketId"] = market_id
        return self._post("/trading/cancel-all", payload)

    def edit_order(
        self,
        order_id: str,
        *,
        price: Optional[float] = None,
        size: Optional[float] = None,
    ) -> Any:
        """Edit an existing open order.

        Args:
            order_id: The order to edit. **Required.**
            price: New price.
            size: New size.
        """
        payload: Dict[str, Any] = {"orderId": order_id}
        if price is not None:
            payload["price"] = price
        if size is not None:
            payload["size"] = size
        return self._post("/trading/edit-order", payload)

    # ── Order queries ────────────────────────────────────────────────

    def open_orders(self, *, market_id: Optional[str] = None) -> Any:
        """List all open orders.

        Args:
            market_id: Filter to a specific market.
        """
        return self._get("/trading/open-orders", {"marketId": market_id})

    def order_status(self, order_id: str) -> Any:
        """Get status of a specific order.

        Args:
            order_id: The order ID. **Required.**
        """
        return self._get("/trading/order-status", {"orderId": order_id})

    # ── Token operations ─────────────────────────────────────────────

    def redeem(self, *, market_id: Optional[str] = None) -> Any:
        """Redeem resolved positions.

        Args:
            market_id: If provided, only redeem for this market.
        """
        payload: Dict[str, Any] = {}
        if market_id is not None:
            payload["marketId"] = market_id
        return self._post("/trading/redeem", payload)

    def split(self, market_id: str, amount: float) -> Any:
        """Split USDC into outcome tokens.

        Args:
            market_id: Market ID. **Required.**
            amount: USDC amount to split. **Required.**
        """
        return self._post("/trading/split", {
            "marketId": market_id,
            "amount": amount,
        })

    def merge(self, market_id: str, amount: float) -> Any:
        """Merge outcome tokens back into USDC.

        Args:
            market_id: Market ID. **Required.**
            amount: Token amount to merge. **Required.**
        """
        return self._post("/trading/merge", {
            "marketId": market_id,
            "amount": amount,
        })
