/*
 * Binance Fiat REST API
 *
 * OpenAPI Specification for the Binance Fiat 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,
    fiat_api_client: FiatApiClient,
}

impl RestApi {
    pub fn new(configuration: ConfigurationRestApi) -> Self {
        let fiat_api_client = FiatApiClient::new(configuration.clone());

        Self {
            configuration,
            fiat_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
    }

    /// Deposit(TRADE)
    ///
    /// Submit deposit request, in this version, we only support BRL deposit via pix.
    ///
    ///
    ///
    /// For BRL deposit via pix, you need to place an order before making a transfer from your bank.
    ///
    /// Before calling this api, please make sure you have already completed your KYC or KYB, and already activated your fiat service on our website.
    ///
    /// Weight: 45000
    ///
    /// # Arguments
    ///
    /// - `params`: [`DepositParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::DepositResponse>`] 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/fiat/rest-api/Fiat-Deposit).
    ///
    pub async fn deposit(
        &self,
        params: DepositParams,
    ) -> anyhow::Result<RestApiResponse<models::DepositResponse>> {
        self.fiat_api_client.deposit(params).await
    }

    /// Fiat Withdraw(WITHDRAW)
    ///
    /// Submit withdraw request, in this version, we support BRL,ARS,MXN withdrawal via `bank_transfer`.
    ///
    /// You need to call this api first, and call query order detail api in a loop to get the status of the order until this order is successful.
    ///
    /// Before calling this API, please ensure you have completed your KYC or KYB, activated your fiat service, and verified your destination bank account on our website.
    ///
    /// you need to bind your bank account on web/app before using the corresponding account number
    ///
    /// Weight: 45000
    ///
    /// # Arguments
    ///
    /// - `params`: [`FiatWithdrawParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::FiatWithdrawResponse>`] 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/fiat/rest-api/Fiat-Withdraw).
    ///
    pub async fn fiat_withdraw(
        &self,
        params: FiatWithdrawParams,
    ) -> anyhow::Result<RestApiResponse<models::FiatWithdrawResponse>> {
        self.fiat_api_client.fiat_withdraw(params).await
    }

    /// Get Fiat Deposit/Withdraw History (`USER_DATA`)
    ///
    /// Get Fiat Deposit/Withdraw History
    ///
    /// * If beginTime and endTime are not sent, the recent 30-day data will be returned.
    ///
    /// Weight: 45000
    ///
    /// # Arguments
    ///
    /// - `params`: [`GetFiatDepositWithdrawHistoryParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::GetFiatDepositWithdrawHistoryResponse>`] 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/fiat/rest-api/Get-Fiat-Deposit-Withdraw-History).
    ///
    pub async fn get_fiat_deposit_withdraw_history(
        &self,
        params: GetFiatDepositWithdrawHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFiatDepositWithdrawHistoryResponse>> {
        self.fiat_api_client
            .get_fiat_deposit_withdraw_history(params)
            .await
    }

    /// Get Fiat Payments History (`USER_DATA`)
    ///
    /// Get Fiat Deposit/Withdraw History
    ///
    /// * If beginTime and endTime are not sent, the recent 30-day data will be returned.
    /// * paymentMethod: Only when requesting payments history for buy (transactionType=0), response contains paymentMethod representing the way of purchase. Now we have:
    /// * Cash Balance
    /// * Credit Card
    /// * Online Banking
    /// * Bank Transfer
    ///
    /// Weight: 1
    ///
    /// # Arguments
    ///
    /// - `params`: [`GetFiatPaymentsHistoryParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::GetFiatPaymentsHistoryResponse>`] 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/fiat/rest-api/Get-Fiat-Payments-History).
    ///
    pub async fn get_fiat_payments_history(
        &self,
        params: GetFiatPaymentsHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFiatPaymentsHistoryResponse>> {
        self.fiat_api_client.get_fiat_payments_history(params).await
    }

    /// Get Order `Detail(USER_DATA)`
    ///
    /// Get Order Detail
    ///
    /// Before calling this api, please make sure you have already completed your KYC or KYB, and already activated your fiat service on our website.
    ///
    /// Weight: 1
    ///
    /// # Arguments
    ///
    /// - `params`: [`GetOrderDetailParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::GetOrderDetailResponse>`] 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/fiat/rest-api/Get-Order-Detail).
    ///
    pub async fn get_order_detail(
        &self,
        params: GetOrderDetailParams,
    ) -> anyhow::Result<RestApiResponse<models::GetOrderDetailResponse>> {
        self.fiat_api_client.get_order_detail(params).await
    }
}
