"""
Binance Convert REST API

OpenAPI Specification for the Binance Convert REST API
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)

Do not edit the class manually.
"""

from typing import Optional, Union
from requests import Session
from binance_common.configuration import ConfigurationRestAPI
from binance_common.errors import RequiredError
from binance_common.models import ApiResponse
from binance_common.signature import Signers
from binance_common.utils import send_request

from ..models import AcceptQuoteResponse
from ..models import CancelLimitOrderResponse
from ..models import GetConvertTradeHistoryResponse
from ..models import OrderStatusResponse
from ..models import PlaceLimitOrderResponse
from ..models import QueryLimitOpenOrdersResponse
from ..models import SendQuoteRequestResponse


class TradeApi:
    """API Client for TradeApi endpoints."""

    def __init__(
        self,
        configuration: ConfigurationRestAPI = None,
        session: Session = None,
        signer: Signers = None,
    ) -> None:
        self._configuration = configuration
        self._session = session
        self._signer = signer

    def accept_quote(
        self,
        quote_id: Union[str, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[AcceptQuoteResponse]:
        """
                Accept Quote (TRADE)
                POST /sapi/v1/convert/acceptQuote
                https://developers.binance.com/docs/convert/trade/Accept-Quote

                Accept the offered quote by quote ID.

        Weight: 500(UID)

                Args:
                    quote_id (Union[str, None]):
                    recv_window (Optional[int] = None): The value cannot be greater than 60000

                Returns:
                    ApiResponse[AcceptQuoteResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        if quote_id is None:
            raise RequiredError(
                field="quote_id", error_message="Missing required parameter 'quote_id'"
            )

        body = {}
        payload = {"quote_id": quote_id, "recv_window": recv_window}

        return send_request(
            self._session,
            self._configuration,
            method="POST",
            path="/sapi/v1/convert/acceptQuote",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=AcceptQuoteResponse,
            is_signed=True,
            signer=self._signer,
        )

    def cancel_limit_order(
        self,
        order_id: Union[int, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[CancelLimitOrderResponse]:
        """
                Cancel limit order (USER_DATA)
                POST /sapi/v1/convert/limit/cancelOrder
                https://developers.binance.com/docs/convert/trade/Cancel-Order

                Enable users to cancel a limit order

        Weight: 200(UID)

                Args:
                    order_id (Union[int, None]): The orderId from `placeOrder` api
                    recv_window (Optional[int] = None): The value cannot be greater than 60000

                Returns:
                    ApiResponse[CancelLimitOrderResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        if order_id is None:
            raise RequiredError(
                field="order_id", error_message="Missing required parameter 'order_id'"
            )

        body = {}
        payload = {"order_id": order_id, "recv_window": recv_window}

        return send_request(
            self._session,
            self._configuration,
            method="POST",
            path="/sapi/v1/convert/limit/cancelOrder",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=CancelLimitOrderResponse,
            is_signed=True,
            signer=self._signer,
        )

    def get_convert_trade_history(
        self,
        start_time: Union[int, None],
        end_time: Union[int, None],
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetConvertTradeHistoryResponse]:
        """
                Get Convert Trade History(USER_DATA)
                GET /sapi/v1/convert/tradeFlow
                https://developers.binance.com/docs/convert/trade/Get-Convert-Trade-History

                Get Convert Trade History

        * The max interval between startTime and endTime is 30 days.

        Weight: 3000

                Args:
                    start_time (Union[int, None]):
                    end_time (Union[int, None]):
                    limit (Optional[int] = None): Default 100, Max 1000
                    recv_window (Optional[int] = None): The value cannot be greater than 60000

                Returns:
                    ApiResponse[GetConvertTradeHistoryResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        if start_time is None:
            raise RequiredError(
                field="start_time",
                error_message="Missing required parameter 'start_time'",
            )
        if end_time is None:
            raise RequiredError(
                field="end_time", error_message="Missing required parameter 'end_time'"
            )

        body = {}
        payload = {
            "start_time": start_time,
            "end_time": end_time,
            "limit": limit,
            "recv_window": recv_window,
        }

        return send_request(
            self._session,
            self._configuration,
            method="GET",
            path="/sapi/v1/convert/tradeFlow",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=GetConvertTradeHistoryResponse,
            is_signed=True,
            signer=self._signer,
        )

    def order_status(
        self,
        order_id: Optional[str] = None,
        quote_id: Optional[str] = None,
    ) -> ApiResponse[OrderStatusResponse]:
        """
                Order status(USER_DATA)
                GET /sapi/v1/convert/orderStatus
                https://developers.binance.com/docs/convert/trade/Order-Status

                Query order status by order ID.

        Weight: 100(UID)

                Args:
                    order_id (Optional[str] = None): Either orderId or quoteId is required
                    quote_id (Optional[str] = None): Either orderId or quoteId is required

                Returns:
                    ApiResponse[OrderStatusResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        body = {}
        payload = {"order_id": order_id, "quote_id": quote_id}

        return send_request(
            self._session,
            self._configuration,
            method="GET",
            path="/sapi/v1/convert/orderStatus",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=OrderStatusResponse,
            is_signed=True,
            signer=self._signer,
        )

    def place_limit_order(
        self,
        base_asset: Union[str, None],
        quote_asset: Union[str, None],
        limit_price: Union[float, None],
        side: Union[str, None],
        expired_type: Union[str, None],
        base_amount: Optional[float] = None,
        quote_amount: Optional[float] = None,
        wallet_type: Optional[str] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[PlaceLimitOrderResponse]:
        """
                Place limit order (USER_DATA)
                POST /sapi/v1/convert/limit/placeOrder
                https://developers.binance.com/docs/convert/trade/Place-Order

                Enable users to place a limit order

        * `baseAsset` or `quoteAsset` can be determined via `exchangeInfo` endpoint.
        * Limit price is defined from `baseAsset` to `quoteAsset`.
        * Either `baseAmount` or `quoteAmount` is used.

        Weight: 500(UID)

                Args:
                    base_asset (Union[str, None]): base asset (use the response `fromIsBase` from `GET /sapi/v1/convert/exchangeInfo` api to check which one is baseAsset )
                    quote_asset (Union[str, None]): quote asset
                    limit_price (Union[float, None]): Symbol limit price (from baseAsset to quoteAsset)
                    side (Union[str, None]): `BUY` or `SELL`
                    expired_type (Union[str, None]): 1_D, 3_D, 7_D, 30_D  (D means day)
                    base_amount (Optional[float] = None): Base asset amount.  (One of `baseAmount` or `quoteAmount` is required)
                    quote_amount (Optional[float] = None): Quote asset amount.  (One of `baseAmount` or `quoteAmount` is required)
                    wallet_type (Optional[str] = None): It is to choose which wallet of assets. The wallet selection is `SPOT`, `FUNDING` and `EARN`. Combination of wallet is supported i.e. `SPOT_FUNDING`, `FUNDING_EARN`, `SPOT_FUNDING_EARN` or `SPOT_EARN`  Default is `SPOT`.
                    recv_window (Optional[int] = None): The value cannot be greater than 60000

                Returns:
                    ApiResponse[PlaceLimitOrderResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        if base_asset is None:
            raise RequiredError(
                field="base_asset",
                error_message="Missing required parameter 'base_asset'",
            )
        if quote_asset is None:
            raise RequiredError(
                field="quote_asset",
                error_message="Missing required parameter 'quote_asset'",
            )
        if limit_price is None:
            raise RequiredError(
                field="limit_price",
                error_message="Missing required parameter 'limit_price'",
            )
        if side is None:
            raise RequiredError(
                field="side", error_message="Missing required parameter 'side'"
            )
        if expired_type is None:
            raise RequiredError(
                field="expired_type",
                error_message="Missing required parameter 'expired_type'",
            )

        body = {}
        payload = {
            "base_asset": base_asset,
            "quote_asset": quote_asset,
            "limit_price": limit_price,
            "side": side,
            "expired_type": expired_type,
            "base_amount": base_amount,
            "quote_amount": quote_amount,
            "wallet_type": wallet_type,
            "recv_window": recv_window,
        }

        return send_request(
            self._session,
            self._configuration,
            method="POST",
            path="/sapi/v1/convert/limit/placeOrder",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=PlaceLimitOrderResponse,
            is_signed=True,
            signer=self._signer,
        )

    def query_limit_open_orders(
        self,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[QueryLimitOpenOrdersResponse]:
        """
                Query limit open orders (USER_DATA)
                GET /sapi/v1/convert/limit/queryOpenOrders
                https://developers.binance.com/docs/convert/trade/Query-Order

                Request a quote for the requested token pairs

        Weight: 3000(UID)

                Args:
                    recv_window (Optional[int] = None): The value cannot be greater than 60000

                Returns:
                    ApiResponse[QueryLimitOpenOrdersResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        body = {}
        payload = {"recv_window": recv_window}

        return send_request(
            self._session,
            self._configuration,
            method="GET",
            path="/sapi/v1/convert/limit/queryOpenOrders",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=QueryLimitOpenOrdersResponse,
            is_signed=True,
            signer=self._signer,
        )

    def send_quote_request(
        self,
        from_asset: Union[str, None],
        to_asset: Union[str, None],
        from_amount: Optional[float] = None,
        to_amount: Optional[float] = None,
        wallet_type: Optional[str] = None,
        valid_time: Optional[str] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[SendQuoteRequestResponse]:
        """
                Send Quote Request(USER_DATA)
                POST /sapi/v1/convert/getQuote
                https://developers.binance.com/docs/convert/trade/Send-quote-request

                Request a quote for the requested token pairs

        * Either fromAmount or toAmount should be sent
        * `quoteId` will be returned only if you have enough funds to convert

        Weight: 200(UID)

                Args:
                    from_asset (Union[str, None]):
                    to_asset (Union[str, None]):
                    from_amount (Optional[float] = None): When specified, it is the amount you will be debited after the conversion
                    to_amount (Optional[float] = None): When specified, it is the amount you will be credited after the conversion
                    wallet_type (Optional[str] = None): It is to choose which wallet of assets. The wallet selection is `SPOT`, `FUNDING` and `EARN`. Combination of wallet is supported i.e. `SPOT_FUNDING`, `FUNDING_EARN`, `SPOT_FUNDING_EARN` or `SPOT_EARN`  Default is `SPOT`.
                    valid_time (Optional[str] = None): 10s, 30s, 1m, default 10s
                    recv_window (Optional[int] = None): The value cannot be greater than 60000

                Returns:
                    ApiResponse[SendQuoteRequestResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        if from_asset is None:
            raise RequiredError(
                field="from_asset",
                error_message="Missing required parameter 'from_asset'",
            )
        if to_asset is None:
            raise RequiredError(
                field="to_asset", error_message="Missing required parameter 'to_asset'"
            )

        body = {}
        payload = {
            "from_asset": from_asset,
            "to_asset": to_asset,
            "from_amount": from_amount,
            "to_amount": to_amount,
            "wallet_type": wallet_type,
            "valid_time": valid_time,
            "recv_window": recv_window,
        }

        return send_request(
            self._session,
            self._configuration,
            method="POST",
            path="/sapi/v1/convert/getQuote",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=SendQuoteRequestResponse,
            is_signed=True,
            signer=self._signer,
        )
