"""
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.
"""

import requests
from typing import Optional, TypeVar, Union
from binance_common.configuration import ConfigurationRestAPI
from binance_common.models import ApiResponse
from binance_common.signature import Signers
from binance_common.utils import send_request
from .api.market_data_api import MarketDataApi
from .api.trade_api import TradeApi

from .models import ListAllConvertPairsResponse
from .models import QueryOrderQuantityPrecisionPerAssetResponse
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


T = TypeVar("T")


class ConvertRestAPI:
    def __init__(
        self,
        configuration: ConfigurationRestAPI,
    ) -> None:
        self.configuration = configuration
        self._session = requests.Session()
        self._signer = (
            Signers.get_signer(
                configuration.private_key, configuration.private_key_passphrase
            )
            if configuration.private_key is not None
            else None
        )

        self._marketDataApi = MarketDataApi(
            self.configuration, self._session, self._signer
        )
        self._tradeApi = TradeApi(self.configuration, self._session, self._signer)

    def send_request(
        self,
        endpoint: str,
        method: str,
        query_params: Optional[dict] = None,
        body_params: Optional[dict] = None,
    ) -> ApiResponse[T]:
        """
        Sends an request to the Binance REST API.

        Args:
            endpoint (str): The API endpoint path to send the request to.
            method (str): The HTTP method to use for the request (e.g. "GET", "POST", "PUT", "DELETE").
            query_params (Optional[dict]): The request payload as a dictionary, or None if no payload is required.
            body_params (Optional[dict]): The request body as a dictionary, or None if no body is required.

        Returns:
            ApiResponse[T]: The API response, where T is the expected response type.
        """
        return send_request[T](
            self._session,
            self.configuration,
            method,
            endpoint,
            query_params,
            body_params,
        )

    def send_signed_request(
        self,
        endpoint: str,
        method: str,
        query_params: Optional[dict] = None,
        body_params: Optional[dict] = None,
    ) -> ApiResponse[T]:
        """
        Sends a signed request to the Binance REST API.

        Args:
            endpoint (str): The API endpoint path to send the request to.
            method (str): The HTTP method to use for the request (e.g. "GET", "POST", "PUT", "DELETE").
            query_params (Optional[dict]): The request payload as a dictionary, or None if no payload is required.
            body_params (Optional[dict]): The request body as a dictionary, or None if no body is required.

        Returns:
            ApiResponse[T]: The API response, where T is the expected response type.
        """
        return send_request[T](
            self._session,
            self.configuration,
            method,
            endpoint,
            query_params,
            body_params,
            is_signed=True,
            signer=self._signer,
        )

    def list_all_convert_pairs(
        self,
        from_asset: Optional[str] = None,
        to_asset: Optional[str] = None,
    ) -> ApiResponse[ListAllConvertPairsResponse]:
        """
                List All Convert Pairs

                Query for all convertible token pairs and the tokens’ respective upper/lower limits

        * User needs to supply either or both of the input parameter
        * If not defined for both fromAsset and toAsset, only partial token pairs will be returned

        Weight: 3000(IP)

                Args:
                    from_asset (Optional[str] = None): User spends coin
                    to_asset (Optional[str] = None): User receives coin

                Returns:
                    ApiResponse[ListAllConvertPairsResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._marketDataApi.list_all_convert_pairs(from_asset, to_asset)

    def query_order_quantity_precision_per_asset(
        self,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[QueryOrderQuantityPrecisionPerAssetResponse]:
        """
                Query order quantity precision per asset(USER_DATA)

                Query for supported asset’s precision information

        Weight: 100(IP)

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

                Returns:
                    ApiResponse[QueryOrderQuantityPrecisionPerAssetResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._marketDataApi.query_order_quantity_precision_per_asset(recv_window)

    def accept_quote(
        self,
        quote_id: Union[str, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[AcceptQuoteResponse]:
        """
                Accept Quote (TRADE)

                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.

        """

        return self._tradeApi.accept_quote(quote_id, recv_window)

    def cancel_limit_order(
        self,
        order_id: Union[int, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[CancelLimitOrderResponse]:
        """
                Cancel limit order (USER_DATA)

                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.

        """

        return self._tradeApi.cancel_limit_order(order_id, recv_window)

    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 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.

        """

        return self._tradeApi.get_convert_trade_history(
            start_time, end_time, limit, recv_window
        )

    def order_status(
        self,
        order_id: Optional[str] = None,
        quote_id: Optional[str] = None,
    ) -> ApiResponse[OrderStatusResponse]:
        """
                Order status(USER_DATA)

                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.

        """

        return self._tradeApi.order_status(order_id, quote_id)

    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)

                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.

        """

        return self._tradeApi.place_limit_order(
            base_asset,
            quote_asset,
            limit_price,
            side,
            expired_type,
            base_amount,
            quote_amount,
            wallet_type,
            recv_window,
        )

    def query_limit_open_orders(
        self,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[QueryLimitOpenOrdersResponse]:
        """
                Query limit open orders (USER_DATA)

                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.

        """

        return self._tradeApi.query_limit_open_orders(recv_window)

    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)

                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.

        """

        return self._tradeApi.send_quote_request(
            from_asset,
            to_asset,
            from_amount,
            to_amount,
            wallet_type,
            valid_time,
            recv_window,
        )
