"""
Binance VIP Loan REST API

OpenAPI Specification for the Binance VIP Loan 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 .api.user_information_api import UserInformationApi

from .models import GetBorrowInterestRateResponse
from .models import GetCollateralAssetDataResponse
from .models import GetLoanableAssetsDataResponse
from .models import VipLoanBorrowResponse
from .models import VipLoanRenewResponse
from .models import VipLoanRepayResponse
from .models import CheckVIPLoanCollateralAccountResponse
from .models import GetVIPLoanOngoingOrdersResponse
from .models import QueryApplicationStatusResponse


T = TypeVar("T")


class VipLoanRestAPI:
    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)
        self._userInformationApi = UserInformationApi(
            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 get_borrow_interest_rate(
        self,
        loan_coin: Union[str, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetBorrowInterestRateResponse]:
        """
                Get Borrow Interest Rate(USER_DATA)

                Get Borrow Interest Rate

        Weight: 400

                Args:
                    loan_coin (Union[str, None]):
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetBorrowInterestRateResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._marketDataApi.get_borrow_interest_rate(loan_coin, recv_window)

    def get_collateral_asset_data(
        self,
        collateral_coin: Optional[str] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetCollateralAssetDataResponse]:
        """
                Get Collateral Asset Data(USER_DATA)

                Get Collateral Asset Data

        Weight: 400

                Args:
                    collateral_coin (Optional[str] = None):
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetCollateralAssetDataResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._marketDataApi.get_collateral_asset_data(
            collateral_coin, recv_window
        )

    def get_loanable_assets_data(
        self,
        loan_coin: Optional[str] = None,
        vip_level: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetLoanableAssetsDataResponse]:
        """
                Get Loanable Assets Data(USER_DATA)

                Get interest rate and borrow limit of loanable assets. The borrow limit is shown in USD value.

        Weight: 400

                Args:
                    loan_coin (Optional[str] = None):
                    vip_level (Optional[int] = None): default:user's vip level
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetLoanableAssetsDataResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._marketDataApi.get_loanable_assets_data(
            loan_coin, vip_level, recv_window
        )

    def vip_loan_borrow(
        self,
        loan_account_id: Union[int, None],
        loan_coin: Union[str, None],
        loan_amount: Union[float, None],
        collateral_account_id: Union[str, None],
        collateral_coin: Union[str, None],
        is_flexible_rate: Union[bool, None],
        loan_term: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[VipLoanBorrowResponse]:
        """
                VIP Loan Borrow(TRADE)

                VIP loan is available for VIP users only.

        * loanAccountId refer to loan receiving account
        * Only master account applications are supported
        * loanAccountId and collateralAccountId under same master account
        * loanTerm is mandatory if user choose stable rate

        Weight: 0

                Args:
                    loan_account_id (Union[int, None]):
                    loan_coin (Union[str, None]):
                    loan_amount (Union[float, None]):
                    collateral_account_id (Union[str, None]): Multiple split by `,`
                    collateral_coin (Union[str, None]): Multiple split by `,`
                    is_flexible_rate (Union[bool, None]): Default: TRUE. TRUE : flexible rate; FALSE: fixed rate
                    loan_term (Optional[int] = None): Mandatory for fixed rate. Optional for fixed interest rate. Eg: 30/60 days
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[VipLoanBorrowResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._tradeApi.vip_loan_borrow(
            loan_account_id,
            loan_coin,
            loan_amount,
            collateral_account_id,
            collateral_coin,
            is_flexible_rate,
            loan_term,
            recv_window,
        )

    def vip_loan_renew(
        self,
        order_id: Union[int, None],
        loan_term: Union[int, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[VipLoanRenewResponse]:
        """
                VIP Loan Renew(TRADE)

                VIP loan is available for VIP users only.

        Weight: 6000

                Args:
                    order_id (Union[int, None]):
                    loan_term (Union[int, None]): 30/60 days
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[VipLoanRenewResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._tradeApi.vip_loan_renew(order_id, loan_term, recv_window)

    def vip_loan_repay(
        self,
        order_id: Union[int, None],
        amount: Union[float, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[VipLoanRepayResponse]:
        """
                VIP Loan Repay(TRADE)

                VIP loan is available for VIP users only.

        Weight: 6000

                Args:
                    order_id (Union[int, None]):
                    amount (Union[float, None]):
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[VipLoanRepayResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._tradeApi.vip_loan_repay(order_id, amount, recv_window)

    def check_vip_loan_collateral_account(
        self,
        order_id: Optional[int] = None,
        collateral_account_id: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[CheckVIPLoanCollateralAccountResponse]:
        """
                Check VIP Loan Collateral Account (USER_DATA)

                VIP loan is available for VIP users only

        * If the login account is loan account, all collateral accounts under the loan account can be queried.
        * If the login account is collateral account, only the current collateral account can be queried.

        Weight: 6000

                Args:
                    order_id (Optional[int] = None):
                    collateral_account_id (Optional[int] = None):
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[CheckVIPLoanCollateralAccountResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._userInformationApi.check_vip_loan_collateral_account(
            order_id, collateral_account_id, recv_window
        )

    def get_vip_loan_ongoing_orders(
        self,
        order_id: Optional[int] = None,
        collateral_account_id: Optional[int] = None,
        loan_coin: Optional[str] = None,
        collateral_coin: Optional[str] = None,
        current: Optional[int] = None,
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetVIPLoanOngoingOrdersResponse]:
        """
                Get VIP Loan Ongoing Orders(USER_DATA)

                VIP loan is available for VIP users only.

        Weight: 400

                Args:
                    order_id (Optional[int] = None):
                    collateral_account_id (Optional[int] = None):
                    loan_coin (Optional[str] = None):
                    collateral_coin (Optional[str] = None):
                    current (Optional[int] = None): Currently querying page. Start from 1, Default:1, Max: 1000.
                    limit (Optional[int] = None): Default: 10, Max: 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetVIPLoanOngoingOrdersResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._userInformationApi.get_vip_loan_ongoing_orders(
            order_id,
            collateral_account_id,
            loan_coin,
            collateral_coin,
            current,
            limit,
            recv_window,
        )

    def query_application_status(
        self,
        current: Optional[int] = None,
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[QueryApplicationStatusResponse]:
        """
                Query Application Status(USER_DATA)

                Query Application Status

        Weight: 400

                Args:
                    current (Optional[int] = None): Currently querying page. Start from 1, Default:1, Max: 1000.
                    limit (Optional[int] = None): Default: 10, Max: 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[QueryApplicationStatusResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._userInformationApi.query_application_status(
            current, limit, recv_window
        )
