# AUTO-GENERATED from pykalshi/_async/communications.py — do not edit manually.
# Re-run: python scripts/generate_sync.py
from __future__ import annotations

from typing import TYPE_CHECKING
from urllib.parse import urlencode

from ..models import RfqModel, QuoteModel
from ..dataframe import DataFrameList

if TYPE_CHECKING:
    from .client import KalshiClient


class Communications:
    """RFQ (Request for Quote) and quote operations for combo trading.

    Multivariate event combos trade via the RFQ system rather than
    standard limit orders. The flow is:

    1. Create an RFQ broadcasting your intent to trade a combo.
    2. Market makers respond with two-sided quotes.
    3. Accept a quote to execute the trade.

    Usage:
        # Create an RFQ for a combo market
        rfq = client.communications.create_rfq(
            market_ticker="KXMVE-...",
            contracts_fp="10.00",
        )

        # List active RFQs
        rfqs = client.communications.get_rfqs(status="active")

        # Respond to an RFQ as a market maker
        quote = client.communications.create_quote(
            rfq_id=rfq.rfq_id,
            yes_bid="0.45",
            no_bid="0.55",
        )
    """

    def __init__(self, client: KalshiClient) -> None:
        self._client = client

    def create_rfq(
        self,
        market_ticker: str,
        *,
        contracts_fp: str | None = None,
        target_cost_dollars: str | None = None,
        rest_remainder: bool = False,
    ) -> RfqModel:
        """Create a Request for Quote.

        Args:
            market_ticker: The combo market ticker to request quotes for.
            contracts_fp: Number of contracts to trade (fixed-point string, e.g. "10.00").
            target_cost_dollars: Target cost in dollars (e.g. "10.00").
                                 Use this OR contracts_fp, not both.
            rest_remainder: If True, rest any unfilled portion on the orderbook.
        """

        body: dict = {
            "market_ticker": market_ticker.upper(),
            "rest_remainder": rest_remainder,
        }
        if contracts_fp is not None:
            body["contracts_fp"] = contracts_fp
        if target_cost_dollars is not None:
            body["target_cost_dollars"] = target_cost_dollars

        response = self._client.post("/communications/rfqs", body)
        return RfqModel.model_validate(response.get("rfq", response))

    def get_rfqs(
        self,
        *,
        market_ticker: str | None = None,
        status: str | None = None,
        mve_collection_ticker: str | None = None,
        limit: int = 100,
        cursor: str | None = None,
        fetch_all: bool = False,
    ) -> DataFrameList[RfqModel]:
        """List RFQs.

        Args:
            market_ticker: Filter by combo market ticker.
            status: Filter by RFQ status (e.g., "active", "expired").
            mve_collection_ticker: Filter by collection ticker.
            limit: Maximum results per page (default 100).
            cursor: Pagination cursor.
            fetch_all: If True, automatically fetch all pages.
        """
        params: dict = {"limit": limit}
        if market_ticker:
            params["market_ticker"] = market_ticker.upper()
        if status:
            params["status"] = status
        if mve_collection_ticker:
            params["mve_collection_ticker"] = mve_collection_ticker
        if cursor:
            params["cursor"] = cursor

        data = self._client.paginated_get("/communications/rfqs", "rfqs", params, fetch_all)
        return DataFrameList(RfqModel.model_validate(r) for r in data)

    def get_rfq(self, rfq_id: str) -> RfqModel:
        """Get a single RFQ by ID."""
        response = self._client.get(f"/communications/rfqs/{rfq_id}")
        return RfqModel.model_validate(response.get("rfq", response))

    def create_quote(
        self,
        rfq_id: str,
        *,
        yes_bid: str,
        no_bid: str,
        rest_remainder: bool = False,
    ) -> QuoteModel:
        """Create a quote in response to an RFQ.

        Prices are in FixedPointDollars (e.g., "0.45").

        Args:
            rfq_id: ID of the RFQ to respond to.
            yes_bid: Your bid price for the YES side (FixedPointDollars).
            no_bid: Your bid price for the NO side (FixedPointDollars).
            rest_remainder: If True, rest any unfilled portion on the orderbook.
        """
        body: dict = {
            "rfq_id": rfq_id,
            "yes_bid": yes_bid,
            "no_bid": no_bid,
            "rest_remainder": rest_remainder,
        }

        response = self._client.post("/communications/quotes", body)
        return QuoteModel.model_validate(response.get("quote", response))

    def get_quotes(
        self,
        *,
        creator_user_id: str | None = None,
        rfq_creator_user_id: str | None = None,
        rfq_id: str | None = None,
        market_ticker: str | None = None,
        status: str | None = None,
        limit: int = 100,
        cursor: str | None = None,
        fetch_all: bool = False,
    ) -> DataFrameList[QuoteModel]:
        """List quotes.

        The API requires at least one of creator_user_id or rfq_creator_user_id.

        Args:
            creator_user_id: Filter by quote creator. Required if rfq_creator_user_id not set.
            rfq_creator_user_id: Filter by RFQ creator. Required if creator_user_id not set.
            rfq_id: Filter by RFQ ID.
            market_ticker: Filter by combo market ticker.
            status: Filter by quote status.
            limit: Maximum results per page (default 100).
            cursor: Pagination cursor.
            fetch_all: If True, automatically fetch all pages.
        """
        params: dict = {"limit": limit}
        if creator_user_id:
            params["creator_user_id"] = creator_user_id
        if rfq_creator_user_id:
            params["rfq_creator_user_id"] = rfq_creator_user_id
        if rfq_id:
            params["rfq_id"] = rfq_id
        if market_ticker:
            params["market_ticker"] = market_ticker.upper()
        if status:
            params["status"] = status
        if cursor:
            params["cursor"] = cursor

        data = self._client.paginated_get("/communications/quotes", "quotes", params, fetch_all)
        return DataFrameList(QuoteModel.model_validate(q) for q in data)
