/*
 * Binance VIP Loan REST API
 *
 * OpenAPI Specification for the Binance VIP Loan REST API
 *
 * The version of the OpenAPI document: 1.0.0
 *
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

#![allow(unused_imports)]
use http::Method;
use serde::de::DeserializeOwned;
use serde_json::Value;
use std::collections::BTreeMap;

use crate::common::{config::ConfigurationRestApi, models::RestApiResponse, utils::send_request};

mod apis;
mod models;

pub use apis::*;
pub use models::*;

#[derive(Debug, Clone)]
pub struct RestApi {
    configuration: ConfigurationRestApi,
    market_data_api_client: MarketDataApiClient,
    trade_api_client: TradeApiClient,
    user_information_api_client: UserInformationApiClient,
}

impl RestApi {
    pub fn new(configuration: ConfigurationRestApi) -> Self {
        let market_data_api_client = MarketDataApiClient::new(configuration.clone());
        let trade_api_client = TradeApiClient::new(configuration.clone());
        let user_information_api_client = UserInformationApiClient::new(configuration.clone());

        Self {
            configuration,
            market_data_api_client,
            trade_api_client,
            user_information_api_client,
        }
    }

    /// Send an unsigned request to the API
    ///
    /// # Arguments
    ///
    /// * `endpoint` - The API endpoint to send the request to
    /// * `method` - The HTTP method to use for the request
    /// * `query_params` - A map of query parameters to send with the request
    /// * `body_params` - A map of body parameters to send with the request
    ///
    /// # Returns
    ///
    /// A `RestApiResponse` containing the deserialized response data on success, or an error if the request fails
    ///
    /// # Errors
    ///
    /// Returns an `anyhow::Error` if the HTTP request fails or if parsing the response fails
    pub async fn send_request<R: DeserializeOwned + Send + 'static>(
        &self,
        endpoint: &str,
        method: Method,
        query_params: BTreeMap<String, Value>,
        body_params: BTreeMap<String, Value>,
    ) -> anyhow::Result<RestApiResponse<R>> {
        send_request::<R>(
            &self.configuration,
            endpoint,
            method,
            query_params,
            body_params,
            None,
            false,
        )
        .await
    }

    /// Send a signed request to the API
    ///
    /// # Arguments
    ///
    /// * `endpoint` - The API endpoint to send the request to
    /// * `method` - The HTTP method to use for the request
    /// * `query_params` - A map of query parameters to send with the request
    /// * `body_params` - A map of body parameters to send with the request
    ///
    /// # Returns
    ///
    /// A `RestApiResponse` containing the deserialized response data on success, or an error if the request fails
    ///
    /// # Errors
    ///
    /// Returns an `anyhow::Error` if the HTTP request fails or if parsing the response fails
    pub async fn send_signed_request<R: DeserializeOwned + Send + 'static>(
        &self,
        endpoint: &str,
        method: Method,
        query_params: BTreeMap<String, Value>,
        body_params: BTreeMap<String, Value>,
    ) -> anyhow::Result<RestApiResponse<R>> {
        send_request::<R>(
            &self.configuration,
            endpoint,
            method,
            query_params,
            body_params,
            None,
            true,
        )
        .await
    }

    /// Get Borrow Interest `Rate(USER_DATA)`
    ///
    /// Get Borrow Interest Rate
    ///
    /// Weight: 400
    ///
    /// # Arguments
    ///
    /// - `params`: [`GetBorrowInterestRateParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<Vec<models::GetBorrowInterestRateResponseInner>>`] on success.
    ///
    /// # Errors
    ///
    /// This function will return an [`anyhow::Error`] if:
    /// - the HTTP request fails
    /// - any parameter is invalid
    /// - the response cannot be parsed
    /// - or one of the following occurs:
    ///   - `RequiredError`
    ///   - `ConnectorClientError`
    ///   - `UnauthorizedError`
    ///   - `ForbiddenError`
    ///   - `TooManyRequestsError`
    ///   - `RateLimitBanError`
    ///   - `ServerError`
    ///   - `NotFoundError`
    ///   - `NetworkError`
    ///   - `BadRequestError`
    ///
    ///
    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/vip_loan/market-data/Get-Borrow-Interest-Rate).
    ///
    pub async fn get_borrow_interest_rate(
        &self,
        params: GetBorrowInterestRateParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::GetBorrowInterestRateResponseInner>>> {
        self.market_data_api_client
            .get_borrow_interest_rate(params)
            .await
    }

    /// Get Collateral Asset `Data(USER_DATA)`
    ///
    /// Get Collateral Asset Data
    ///
    /// Weight: 400
    ///
    /// # Arguments
    ///
    /// - `params`: [`GetCollateralAssetDataParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::GetCollateralAssetDataResponse>`] on success.
    ///
    /// # Errors
    ///
    /// This function will return an [`anyhow::Error`] if:
    /// - the HTTP request fails
    /// - any parameter is invalid
    /// - the response cannot be parsed
    /// - or one of the following occurs:
    ///   - `RequiredError`
    ///   - `ConnectorClientError`
    ///   - `UnauthorizedError`
    ///   - `ForbiddenError`
    ///   - `TooManyRequestsError`
    ///   - `RateLimitBanError`
    ///   - `ServerError`
    ///   - `NotFoundError`
    ///   - `NetworkError`
    ///   - `BadRequestError`
    ///
    ///
    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/vip_loan/market-data/Get-Collateral-Asset-Data).
    ///
    pub async fn get_collateral_asset_data(
        &self,
        params: GetCollateralAssetDataParams,
    ) -> anyhow::Result<RestApiResponse<models::GetCollateralAssetDataResponse>> {
        self.market_data_api_client
            .get_collateral_asset_data(params)
            .await
    }

    /// 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
    ///
    /// # Arguments
    ///
    /// - `params`: [`GetLoanableAssetsDataParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::GetLoanableAssetsDataResponse>`] on success.
    ///
    /// # Errors
    ///
    /// This function will return an [`anyhow::Error`] if:
    /// - the HTTP request fails
    /// - any parameter is invalid
    /// - the response cannot be parsed
    /// - or one of the following occurs:
    ///   - `RequiredError`
    ///   - `ConnectorClientError`
    ///   - `UnauthorizedError`
    ///   - `ForbiddenError`
    ///   - `TooManyRequestsError`
    ///   - `RateLimitBanError`
    ///   - `ServerError`
    ///   - `NotFoundError`
    ///   - `NetworkError`
    ///   - `BadRequestError`
    ///
    ///
    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/vip_loan/market-data/Get-Loanable-Assets-Data).
    ///
    pub async fn get_loanable_assets_data(
        &self,
        params: GetLoanableAssetsDataParams,
    ) -> anyhow::Result<RestApiResponse<models::GetLoanableAssetsDataResponse>> {
        self.market_data_api_client
            .get_loanable_assets_data(params)
            .await
    }

    /// Get VIP Loan Interest Rate History (`USER_DATA`)
    ///
    /// Check VIP Loan flexible interest rate history
    ///
    /// * If startTime and endTime are not sent, the recent 90-day data will be returned
    /// * The max interval between startTime and end Time is 180 days.
    /// * Time based on UTC+0.
    ///
    /// Weight: 400
    ///
    /// # Arguments
    ///
    /// - `params`: [`GetVipLoanInterestRateHistoryParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::GetVipLoanInterestRateHistoryResponse>`] on success.
    ///
    /// # Errors
    ///
    /// This function will return an [`anyhow::Error`] if:
    /// - the HTTP request fails
    /// - any parameter is invalid
    /// - the response cannot be parsed
    /// - or one of the following occurs:
    ///   - `RequiredError`
    ///   - `ConnectorClientError`
    ///   - `UnauthorizedError`
    ///   - `ForbiddenError`
    ///   - `TooManyRequestsError`
    ///   - `RateLimitBanError`
    ///   - `ServerError`
    ///   - `NotFoundError`
    ///   - `NetworkError`
    ///   - `BadRequestError`
    ///
    ///
    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/vip_loan/market-data/Get-VIP-Loan-Interest-Rate-History).
    ///
    pub async fn get_vip_loan_interest_rate_history(
        &self,
        params: GetVipLoanInterestRateHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetVipLoanInterestRateHistoryResponse>> {
        self.market_data_api_client
            .get_vip_loan_interest_rate_history(params)
            .await
    }

    /// 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
    ///
    /// # Arguments
    ///
    /// - `params`: [`VipLoanBorrowParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::VipLoanBorrowResponse>`] on success.
    ///
    /// # Errors
    ///
    /// This function will return an [`anyhow::Error`] if:
    /// - the HTTP request fails
    /// - any parameter is invalid
    /// - the response cannot be parsed
    /// - or one of the following occurs:
    ///   - `RequiredError`
    ///   - `ConnectorClientError`
    ///   - `UnauthorizedError`
    ///   - `ForbiddenError`
    ///   - `TooManyRequestsError`
    ///   - `RateLimitBanError`
    ///   - `ServerError`
    ///   - `NotFoundError`
    ///   - `NetworkError`
    ///   - `BadRequestError`
    ///
    ///
    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/vip_loan/trade/VIP-Loan-Borrow).
    ///
    pub async fn vip_loan_borrow(
        &self,
        params: VipLoanBorrowParams,
    ) -> anyhow::Result<RestApiResponse<models::VipLoanBorrowResponse>> {
        self.trade_api_client.vip_loan_borrow(params).await
    }

    /// VIP Loan Renew(TRADE)
    ///
    /// VIP loan is available for VIP users only.
    ///
    /// Weight: 6000
    ///
    /// # Arguments
    ///
    /// - `params`: [`VipLoanRenewParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::VipLoanRenewResponse>`] on success.
    ///
    /// # Errors
    ///
    /// This function will return an [`anyhow::Error`] if:
    /// - the HTTP request fails
    /// - any parameter is invalid
    /// - the response cannot be parsed
    /// - or one of the following occurs:
    ///   - `RequiredError`
    ///   - `ConnectorClientError`
    ///   - `UnauthorizedError`
    ///   - `ForbiddenError`
    ///   - `TooManyRequestsError`
    ///   - `RateLimitBanError`
    ///   - `ServerError`
    ///   - `NotFoundError`
    ///   - `NetworkError`
    ///   - `BadRequestError`
    ///
    ///
    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/vip_loan/trade/VIP-Loan-Renew).
    ///
    pub async fn vip_loan_renew(
        &self,
        params: VipLoanRenewParams,
    ) -> anyhow::Result<RestApiResponse<models::VipLoanRenewResponse>> {
        self.trade_api_client.vip_loan_renew(params).await
    }

    /// VIP Loan Repay(TRADE)
    ///
    /// VIP loan is available for VIP users only.
    ///
    /// Weight: 6000
    ///
    /// # Arguments
    ///
    /// - `params`: [`VipLoanRepayParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::VipLoanRepayResponse>`] on success.
    ///
    /// # Errors
    ///
    /// This function will return an [`anyhow::Error`] if:
    /// - the HTTP request fails
    /// - any parameter is invalid
    /// - the response cannot be parsed
    /// - or one of the following occurs:
    ///   - `RequiredError`
    ///   - `ConnectorClientError`
    ///   - `UnauthorizedError`
    ///   - `ForbiddenError`
    ///   - `TooManyRequestsError`
    ///   - `RateLimitBanError`
    ///   - `ServerError`
    ///   - `NotFoundError`
    ///   - `NetworkError`
    ///   - `BadRequestError`
    ///
    ///
    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/vip_loan/trade/VIP-Loan-Repay).
    ///
    pub async fn vip_loan_repay(
        &self,
        params: VipLoanRepayParams,
    ) -> anyhow::Result<RestApiResponse<models::VipLoanRepayResponse>> {
        self.trade_api_client.vip_loan_repay(params).await
    }

    /// 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
    ///
    /// # Arguments
    ///
    /// - `params`: [`CheckVipLoanCollateralAccountParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::CheckVipLoanCollateralAccountResponse>`] on success.
    ///
    /// # Errors
    ///
    /// This function will return an [`anyhow::Error`] if:
    /// - the HTTP request fails
    /// - any parameter is invalid
    /// - the response cannot be parsed
    /// - or one of the following occurs:
    ///   - `RequiredError`
    ///   - `ConnectorClientError`
    ///   - `UnauthorizedError`
    ///   - `ForbiddenError`
    ///   - `TooManyRequestsError`
    ///   - `RateLimitBanError`
    ///   - `ServerError`
    ///   - `NotFoundError`
    ///   - `NetworkError`
    ///   - `BadRequestError`
    ///
    ///
    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/vip_loan/user-information/Check-Locked-Value-of-VIP-Collateral-Account).
    ///
    pub async fn check_vip_loan_collateral_account(
        &self,
        params: CheckVipLoanCollateralAccountParams,
    ) -> anyhow::Result<RestApiResponse<models::CheckVipLoanCollateralAccountResponse>> {
        self.user_information_api_client
            .check_vip_loan_collateral_account(params)
            .await
    }

    /// Get VIP Loan Accrued Interest (`USER_DATA`)
    ///
    /// Check VIP Loan interest record
    ///
    /// * If startTime and endTime are not sent, the recent 90-day data will be returned.
    /// * The max interval between startTime and endTime is 90 days.
    ///
    /// Weight: 400
    ///
    /// # Arguments
    ///
    /// - `params`: [`GetVipLoanAccruedInterestParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::GetVipLoanAccruedInterestResponse>`] on success.
    ///
    /// # Errors
    ///
    /// This function will return an [`anyhow::Error`] if:
    /// - the HTTP request fails
    /// - any parameter is invalid
    /// - the response cannot be parsed
    /// - or one of the following occurs:
    ///   - `RequiredError`
    ///   - `ConnectorClientError`
    ///   - `UnauthorizedError`
    ///   - `ForbiddenError`
    ///   - `TooManyRequestsError`
    ///   - `RateLimitBanError`
    ///   - `ServerError`
    ///   - `NotFoundError`
    ///   - `NetworkError`
    ///   - `BadRequestError`
    ///
    ///
    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/vip_loan/user-information/Get-VIP-Loan-Accrued-Interest).
    ///
    pub async fn get_vip_loan_accrued_interest(
        &self,
        params: GetVipLoanAccruedInterestParams,
    ) -> anyhow::Result<RestApiResponse<models::GetVipLoanAccruedInterestResponse>> {
        self.user_information_api_client
            .get_vip_loan_accrued_interest(params)
            .await
    }

    /// Get VIP Loan Ongoing `Orders(USER_DATA)`
    ///
    /// VIP loan is available for VIP users only.
    ///
    /// Weight: 400
    ///
    /// # Arguments
    ///
    /// - `params`: [`GetVipLoanOngoingOrdersParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::GetVipLoanOngoingOrdersResponse>`] on success.
    ///
    /// # Errors
    ///
    /// This function will return an [`anyhow::Error`] if:
    /// - the HTTP request fails
    /// - any parameter is invalid
    /// - the response cannot be parsed
    /// - or one of the following occurs:
    ///   - `RequiredError`
    ///   - `ConnectorClientError`
    ///   - `UnauthorizedError`
    ///   - `ForbiddenError`
    ///   - `TooManyRequestsError`
    ///   - `RateLimitBanError`
    ///   - `ServerError`
    ///   - `NotFoundError`
    ///   - `NetworkError`
    ///   - `BadRequestError`
    ///
    ///
    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/vip_loan/user-information/Get-VIP-Loan-Ongoing-Orders).
    ///
    pub async fn get_vip_loan_ongoing_orders(
        &self,
        params: GetVipLoanOngoingOrdersParams,
    ) -> anyhow::Result<RestApiResponse<models::GetVipLoanOngoingOrdersResponse>> {
        self.user_information_api_client
            .get_vip_loan_ongoing_orders(params)
            .await
    }

    /// Query Application `Status(USER_DATA)`
    ///
    /// Query Application Status
    ///
    /// Weight: 400
    ///
    /// # Arguments
    ///
    /// - `params`: [`QueryApplicationStatusParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::QueryApplicationStatusResponse>`] on success.
    ///
    /// # Errors
    ///
    /// This function will return an [`anyhow::Error`] if:
    /// - the HTTP request fails
    /// - any parameter is invalid
    /// - the response cannot be parsed
    /// - or one of the following occurs:
    ///   - `RequiredError`
    ///   - `ConnectorClientError`
    ///   - `UnauthorizedError`
    ///   - `ForbiddenError`
    ///   - `TooManyRequestsError`
    ///   - `RateLimitBanError`
    ///   - `ServerError`
    ///   - `NotFoundError`
    ///   - `NetworkError`
    ///   - `BadRequestError`
    ///
    ///
    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/vip_loan/user-information/Query-Application-Status).
    ///
    pub async fn query_application_status(
        &self,
        params: QueryApplicationStatusParams,
    ) -> anyhow::Result<RestApiResponse<models::QueryApplicationStatusResponse>> {
        self.user_information_api_client
            .query_application_status(params)
            .await
    }
}
