"""
Binance Crypto Loan REST API

OpenAPI Specification for the Binance Crypto 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.flexible_rate_api import FlexibleRateApi
from .api.stable_rate_api import StableRateApi

from .models import CheckCollateralRepayRateResponse
from .models import FlexibleLoanAdjustLtvResponse
from .models import FlexibleLoanBorrowResponse
from .models import FlexibleLoanRepayResponse
from .models import GetFlexibleLoanAssetsDataResponse
from .models import GetFlexibleLoanBorrowHistoryResponse
from .models import GetFlexibleLoanCollateralAssetsDataResponse
from .models import GetFlexibleLoanLiquidationHistoryResponse
from .models import GetFlexibleLoanLtvAdjustmentHistoryResponse
from .models import GetFlexibleLoanOngoingOrdersResponse
from .models import GetFlexibleLoanRepaymentHistoryResponse
from .models import CheckCollateralRepayRateStableRateResponse
from .models import GetCryptoLoansIncomeHistoryResponse
from .models import GetLoanBorrowHistoryResponse
from .models import GetLoanLtvAdjustmentHistoryResponse
from .models import GetLoanRepaymentHistoryResponse


T = TypeVar("T")


class CryptoLoanRestAPI:
    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._flexibleRateApi = FlexibleRateApi(
            self.configuration, self._session, self._signer
        )
        self._stableRateApi = StableRateApi(
            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 check_collateral_repay_rate(
        self,
        loan_coin: Union[str, None],
        collateral_coin: Union[str, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[CheckCollateralRepayRateResponse]:
        """
                Check Collateral Repay Rate (USER_DATA)


        Weight: 6000

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

                Returns:
                    ApiResponse[CheckCollateralRepayRateResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._flexibleRateApi.check_collateral_repay_rate(
            loan_coin, collateral_coin, recv_window
        )

    def flexible_loan_adjust_ltv(
        self,
        loan_coin: Union[str, None],
        collateral_coin: Union[str, None],
        adjustment_amount: Union[float, None],
        direction: Union[str, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[FlexibleLoanAdjustLtvResponse]:
        """
                Flexible Loan Adjust LTV(TRADE)

                Flexible Loan Adjust LTV

        * API Key needs Spot & Margin Trading permission for this endpoint

        Weight: 6000

                Args:
                    loan_coin (Union[str, None]):
                    collateral_coin (Union[str, None]):
                    adjustment_amount (Union[float, None]):
                    direction (Union[str, None]): "ADDITIONAL", "REDUCED"
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[FlexibleLoanAdjustLtvResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._flexibleRateApi.flexible_loan_adjust_ltv(
            loan_coin, collateral_coin, adjustment_amount, direction, recv_window
        )

    def flexible_loan_borrow(
        self,
        loan_coin: Union[str, None],
        collateral_coin: Union[str, None],
        loan_amount: Optional[float] = None,
        collateral_amount: Optional[float] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[FlexibleLoanBorrowResponse]:
        """
                Flexible Loan Borrow(TRADE)

                Borrow Flexible Loan


        * Only available for master account
        * You can customize LTV by entering loanAmount and collateralAmount.

        Weight: 6000

                Args:
                    loan_coin (Union[str, None]):
                    collateral_coin (Union[str, None]):
                    loan_amount (Optional[float] = None): Mandatory when collateralAmount is empty
                    collateral_amount (Optional[float] = None): Mandatory when loanAmount is empty
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[FlexibleLoanBorrowResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._flexibleRateApi.flexible_loan_borrow(
            loan_coin, collateral_coin, loan_amount, collateral_amount, recv_window
        )

    def flexible_loan_repay(
        self,
        loan_coin: Union[str, None],
        collateral_coin: Union[str, None],
        repay_amount: Union[float, None],
        collateral_return: Optional[bool] = None,
        full_repayment: Optional[bool] = None,
        repayment_type: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[FlexibleLoanRepayResponse]:
        """
                Flexible Loan Repay(TRADE)

                Flexible Loan Repay


        * repayAmount is mandatory even fullRepayment = FALSE

        Weight: 6000

                Args:
                    loan_coin (Union[str, None]):
                    collateral_coin (Union[str, None]):
                    repay_amount (Union[float, None]): repay amount of loanCoin
                    collateral_return (Optional[bool] = None): Default: TRUE. TRUE: Return extra collateral to spot account; FALSE: Keep extra collateral in the order, and lower LTV.
                    full_repayment (Optional[bool] = None): Default: FALSE. TRUE: Full repayment; FALSE: Partial repayment, based on loanAmount
                    repayment_type (Optional[int] = None): Default: 1. 1: Repayment with loan asset; 2: Repayment with collateral
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[FlexibleLoanRepayResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._flexibleRateApi.flexible_loan_repay(
            loan_coin,
            collateral_coin,
            repay_amount,
            collateral_return,
            full_repayment,
            repayment_type,
            recv_window,
        )

    def get_flexible_loan_assets_data(
        self,
        loan_coin: Optional[str] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetFlexibleLoanAssetsDataResponse]:
        """
                Get Flexible Loan Assets Data(USER_DATA)

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

        Weight: 400

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

                Returns:
                    ApiResponse[GetFlexibleLoanAssetsDataResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._flexibleRateApi.get_flexible_loan_assets_data(
            loan_coin, recv_window
        )

    def get_flexible_loan_borrow_history(
        self,
        loan_coin: Optional[str] = None,
        collateral_coin: Optional[str] = None,
        start_time: Optional[int] = None,
        end_time: Optional[int] = None,
        current: Optional[int] = None,
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetFlexibleLoanBorrowHistoryResponse]:
        """
                Get Flexible Loan Borrow History(USER_DATA)

                Get Flexible Loan Borrow History

        * If startTime and endTime are not sent, the recent 90-day data will be returned.
        * The max interval between startTime and endTime is 180 days.

        Weight: 400

                Args:
                    loan_coin (Optional[str] = None):
                    collateral_coin (Optional[str] = None):
                    start_time (Optional[int] = None):
                    end_time (Optional[int] = None):
                    current (Optional[int] = None): Current querying page. Start from 1; default: 1; max: 1000
                    limit (Optional[int] = None): Default: 10; max: 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetFlexibleLoanBorrowHistoryResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._flexibleRateApi.get_flexible_loan_borrow_history(
            loan_coin,
            collateral_coin,
            start_time,
            end_time,
            current,
            limit,
            recv_window,
        )

    def get_flexible_loan_collateral_assets_data(
        self,
        collateral_coin: Optional[str] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetFlexibleLoanCollateralAssetsDataResponse]:
        """
                Get Flexible Loan Collateral Assets Data(USER_DATA)

                Get LTV information and collateral limit of flexible loan's collateral assets. The collateral limit is shown in USD value.

        Weight: 400

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

                Returns:
                    ApiResponse[GetFlexibleLoanCollateralAssetsDataResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._flexibleRateApi.get_flexible_loan_collateral_assets_data(
            collateral_coin, recv_window
        )

    def get_flexible_loan_liquidation_history(
        self,
        loan_coin: Optional[str] = None,
        collateral_coin: Optional[str] = None,
        start_time: Optional[int] = None,
        end_time: Optional[int] = None,
        current: Optional[int] = None,
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetFlexibleLoanLiquidationHistoryResponse]:
        """
                Get Flexible Loan Liquidation History (USER_DATA)


        Weight: 400

                Args:
                    loan_coin (Optional[str] = None):
                    collateral_coin (Optional[str] = None):
                    start_time (Optional[int] = None):
                    end_time (Optional[int] = None):
                    current (Optional[int] = None): Current querying page. Start from 1; default: 1; max: 1000
                    limit (Optional[int] = None): Default: 10; max: 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetFlexibleLoanLiquidationHistoryResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._flexibleRateApi.get_flexible_loan_liquidation_history(
            loan_coin,
            collateral_coin,
            start_time,
            end_time,
            current,
            limit,
            recv_window,
        )

    def get_flexible_loan_ltv_adjustment_history(
        self,
        loan_coin: Optional[str] = None,
        collateral_coin: Optional[str] = None,
        start_time: Optional[int] = None,
        end_time: Optional[int] = None,
        current: Optional[int] = None,
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetFlexibleLoanLtvAdjustmentHistoryResponse]:
        """
                Get Flexible Loan LTV Adjustment History(USER_DATA)

                Get Flexible Loan LTV Adjustment History

        * If startTime and endTime are not sent, the recent 90-day data will be returned.
        * The max interval between startTime and endTime is 180 days.

        Weight: 400

                Args:
                    loan_coin (Optional[str] = None):
                    collateral_coin (Optional[str] = None):
                    start_time (Optional[int] = None):
                    end_time (Optional[int] = None):
                    current (Optional[int] = None): Current querying page. Start from 1; default: 1; max: 1000
                    limit (Optional[int] = None): Default: 10; max: 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetFlexibleLoanLtvAdjustmentHistoryResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._flexibleRateApi.get_flexible_loan_ltv_adjustment_history(
            loan_coin,
            collateral_coin,
            start_time,
            end_time,
            current,
            limit,
            recv_window,
        )

    def get_flexible_loan_ongoing_orders(
        self,
        loan_coin: Optional[str] = None,
        collateral_coin: Optional[str] = None,
        current: Optional[int] = None,
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetFlexibleLoanOngoingOrdersResponse]:
        """
                Get Flexible Loan Ongoing Orders(USER_DATA)

                Get Flexible Loan Ongoing Orders

        Weight: 300

                Args:
                    loan_coin (Optional[str] = None):
                    collateral_coin (Optional[str] = None):
                    current (Optional[int] = None): Current querying page. Start from 1; default: 1; max: 1000
                    limit (Optional[int] = None): Default: 10; max: 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetFlexibleLoanOngoingOrdersResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._flexibleRateApi.get_flexible_loan_ongoing_orders(
            loan_coin, collateral_coin, current, limit, recv_window
        )

    def get_flexible_loan_repayment_history(
        self,
        loan_coin: Optional[str] = None,
        collateral_coin: Optional[str] = None,
        start_time: Optional[int] = None,
        end_time: Optional[int] = None,
        current: Optional[int] = None,
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetFlexibleLoanRepaymentHistoryResponse]:
        """
                Get Flexible Loan Repayment History(USER_DATA)

                Get Flexible Loan Repayment History

        * If startTime and endTime are not sent, the recent 90-day data will be returned.
        * The max interval between startTime and endTime is 180 days.

        Weight: 400

                Args:
                    loan_coin (Optional[str] = None):
                    collateral_coin (Optional[str] = None):
                    start_time (Optional[int] = None):
                    end_time (Optional[int] = None):
                    current (Optional[int] = None): Current querying page. Start from 1; default: 1; max: 1000
                    limit (Optional[int] = None): Default: 10; max: 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetFlexibleLoanRepaymentHistoryResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._flexibleRateApi.get_flexible_loan_repayment_history(
            loan_coin,
            collateral_coin,
            start_time,
            end_time,
            current,
            limit,
            recv_window,
        )

    def check_collateral_repay_rate_stable_rate(
        self,
        loan_coin: Union[str, None],
        collateral_coin: Union[str, None],
        repay_amount: Union[float, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[CheckCollateralRepayRateStableRateResponse]:
        """
                Check Collateral Repay Rate(USER_DATA)

                Get the the rate of collateral coin / loan coin when using collateral repay, the rate will be valid within 8 second.

        Weight: 6000

                Args:
                    loan_coin (Union[str, None]):
                    collateral_coin (Union[str, None]):
                    repay_amount (Union[float, None]): repay amount of loanCoin
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[CheckCollateralRepayRateStableRateResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._stableRateApi.check_collateral_repay_rate_stable_rate(
            loan_coin, collateral_coin, repay_amount, recv_window
        )

    def get_crypto_loans_income_history(
        self,
        asset: Optional[str] = None,
        type: Optional[str] = None,
        start_time: Optional[int] = None,
        end_time: Optional[int] = None,
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetCryptoLoansIncomeHistoryResponse]:
        """
                Get Crypto Loans Income History(USER_DATA)

                Get Crypto Loans Income History

        * If startTime and endTime are not sent, the recent 7-day data will be returned.
        * The max interval between startTime and endTime is 30 days.

        Weight: 6000

                Args:
                    asset (Optional[str] = None):
                    type (Optional[str] = None): All types will be returned by default. Enum：`borrowIn` ,`collateralSpent`, `repayAmount`, `collateralReturn`(Collateral return after repayment), `addCollateral`, `removeCollateral`, `collateralReturnAfterLiquidation`
                    start_time (Optional[int] = None):
                    end_time (Optional[int] = None):
                    limit (Optional[int] = None): Default: 10; max: 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetCryptoLoansIncomeHistoryResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._stableRateApi.get_crypto_loans_income_history(
            asset, type, start_time, end_time, limit, recv_window
        )

    def get_loan_borrow_history(
        self,
        order_id: Optional[int] = None,
        loan_coin: Optional[str] = None,
        collateral_coin: Optional[str] = None,
        start_time: Optional[int] = None,
        end_time: Optional[int] = None,
        current: Optional[int] = None,
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetLoanBorrowHistoryResponse]:
        """
                Get Loan Borrow History(USER_DATA)

                Get Loan Borrow History

        * If startTime and endTime are not sent, the recent 90-day data will be returned.
        * The max interval between startTime and endTime is 180 days.

        Weight: 400

                Args:
                    order_id (Optional[int] = None): orderId in `POST /sapi/v1/loan/borrow`
                    loan_coin (Optional[str] = None):
                    collateral_coin (Optional[str] = None):
                    start_time (Optional[int] = None):
                    end_time (Optional[int] = None):
                    current (Optional[int] = None): Current querying page. Start from 1; default: 1; max: 1000
                    limit (Optional[int] = None): Default: 10; max: 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetLoanBorrowHistoryResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._stableRateApi.get_loan_borrow_history(
            order_id,
            loan_coin,
            collateral_coin,
            start_time,
            end_time,
            current,
            limit,
            recv_window,
        )

    def get_loan_ltv_adjustment_history(
        self,
        order_id: Optional[int] = None,
        loan_coin: Optional[str] = None,
        collateral_coin: Optional[str] = None,
        start_time: Optional[int] = None,
        end_time: Optional[int] = None,
        current: Optional[int] = None,
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetLoanLtvAdjustmentHistoryResponse]:
        """
                Get Loan LTV Adjustment History(USER_DATA)

                Get Loan LTV Adjustment History

        * If startTime and endTime are not sent, the recent 90-day data will be returned.
        * The max interval between startTime and endTime is 180 days.

        Weight: 400

                Args:
                    order_id (Optional[int] = None): orderId in `POST /sapi/v1/loan/borrow`
                    loan_coin (Optional[str] = None):
                    collateral_coin (Optional[str] = None):
                    start_time (Optional[int] = None):
                    end_time (Optional[int] = None):
                    current (Optional[int] = None): Current querying page. Start from 1; default: 1; max: 1000
                    limit (Optional[int] = None): Default: 10; max: 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetLoanLtvAdjustmentHistoryResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._stableRateApi.get_loan_ltv_adjustment_history(
            order_id,
            loan_coin,
            collateral_coin,
            start_time,
            end_time,
            current,
            limit,
            recv_window,
        )

    def get_loan_repayment_history(
        self,
        order_id: Optional[int] = None,
        loan_coin: Optional[str] = None,
        collateral_coin: Optional[str] = None,
        start_time: Optional[int] = None,
        end_time: Optional[int] = None,
        current: Optional[int] = None,
        limit: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[GetLoanRepaymentHistoryResponse]:
        """
                Get Loan Repayment History(USER_DATA)

                Get Loan Repayment History

        * If startTime and endTime are not sent, the recent 90-day data will be returned.
        * The max interval between startTime and endTime is 180 days.

        Weight: 400

                Args:
                    order_id (Optional[int] = None): orderId in `POST /sapi/v1/loan/borrow`
                    loan_coin (Optional[str] = None):
                    collateral_coin (Optional[str] = None):
                    start_time (Optional[int] = None):
                    end_time (Optional[int] = None):
                    current (Optional[int] = None): Current querying page. Start from 1; default: 1; max: 1000
                    limit (Optional[int] = None): Default: 10; max: 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[GetLoanRepaymentHistoryResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return self._stableRateApi.get_loan_repayment_history(
            order_id,
            loan_coin,
            collateral_coin,
            start_time,
            end_time,
            current,
            limit,
            recv_window,
        )
