/*
 * Binance Gift Card REST API
 *
 * OpenAPI Specification for the Binance Gift Card 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,
}

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

        Self {
            configuration,
            market_data_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
    /// * `params` - A map of 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,
        params: BTreeMap<String, Value>,
    ) -> anyhow::Result<RestApiResponse<R>> {
        send_request::<R>(&self.configuration, endpoint, method, 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
    /// * `params` - A map of 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,
        params: BTreeMap<String, Value>,
    ) -> anyhow::Result<RestApiResponse<R>> {
        send_request::<R>(&self.configuration, endpoint, method, params, None, true).await
    }

    /// Create a dual-token gift card(fixed value, discount feature)(TRADE)
    ///
    /// * This API is for creating a dual-token ( stablecoin-denominated) Binance Gift Card. You may create a gift card using USDT as baseToken, that is redeemable to another designated token (faceToken). For example, you can create a fixed-value BTC gift card and pay with 100 USDT plus 1 USDT fee. This gift card can keep the value fixed at 100 USDT before redemption, and will be redeemable to BTC equivalent to 100 USDT upon redemption.
    /// * Once successfully created, the amount of baseToken (e.g. USDT) in the fixed-value gift card along with the fee would be deducted from your funding wallet.
    ///
    ///
    /// * To get started with, please make sure:
    /// * You have a Binance account
    /// * You have passed KYB
    /// * You have a sufﬁcient balance(Gift Card amount and fee amount) in your Binance funding wallet
    /// * You need Enable Withdrawals for the API Key which requests this endpoint.
    ///
    /// Weight: 1
    ///
    /// # Arguments
    ///
    /// - `params`: [`CreateADualTokenGiftCardParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::CreateADualTokenGiftCardResponse>`] 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/gift_card/market-data/Create-a-dual-token-gift-card).
    ///
    pub async fn create_a_dual_token_gift_card(
        &self,
        params: CreateADualTokenGiftCardParams,
    ) -> anyhow::Result<RestApiResponse<models::CreateADualTokenGiftCardResponse>> {
        self.market_data_api_client
            .create_a_dual_token_gift_card(params)
            .await
    }

    /// Create a single-token gift card (`USER_DATA`)
    ///
    /// This API is for creating a Binance Gift Card.
    ///
    /// To get started with, please make sure:
    ///
    /// * You have a Binance account
    /// * You have passed KYB
    /// * You have a sufﬁcient balance(Gift Card amount and fee amount) in your Binance funding wallet
    /// * You need `Enable Withdrawals` for the API Key which requests this endpoint.
    ///
    /// Weight: 1
    ///
    /// # Arguments
    ///
    /// - `params`: [`CreateASingleTokenGiftCardParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::CreateASingleTokenGiftCardResponse>`] 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/gift_card/market-data/Create-a-single-token-gift-card).
    ///
    pub async fn create_a_single_token_gift_card(
        &self,
        params: CreateASingleTokenGiftCardParams,
    ) -> anyhow::Result<RestApiResponse<models::CreateASingleTokenGiftCardResponse>> {
        self.market_data_api_client
            .create_a_single_token_gift_card(params)
            .await
    }

    /// Fetch RSA Public `Key(USER_DATA)`
    ///
    /// This API is for fetching the RSA Public Key.
    /// This RSA Public key will be used to encrypt the card code.
    ///
    /// **Please note that the RSA Public key fetched is valid only for the current day.**
    ///
    /// Weight: 1
    ///
    /// # Arguments
    ///
    /// - `params`: [`FetchRsaPublicKeyParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::FetchRsaPublicKeyResponse>`] 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/gift_card/market-data/Fetch-RSA-Public-Key).
    ///
    pub async fn fetch_rsa_public_key(
        &self,
        params: FetchRsaPublicKeyParams,
    ) -> anyhow::Result<RestApiResponse<models::FetchRsaPublicKeyResponse>> {
        self.market_data_api_client
            .fetch_rsa_public_key(params)
            .await
    }

    /// Fetch Token `Limit(USER_DATA)`
    ///
    /// This API is to help you verify which tokens are available for you to create Stablecoin-Denominated gift cards as mentioned in section 2 and its’ limitation.
    ///
    /// Weight: 1
    ///
    /// # Arguments
    ///
    /// - `params`: [`FetchTokenLimitParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::FetchTokenLimitResponse>`] 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/gift_card/market-data/Fetch-Token-Limit).
    ///
    pub async fn fetch_token_limit(
        &self,
        params: FetchTokenLimitParams,
    ) -> anyhow::Result<RestApiResponse<models::FetchTokenLimitResponse>> {
        self.market_data_api_client.fetch_token_limit(params).await
    }

    /// Redeem a Binance Gift `Card(USER_DATA)`
    ///
    /// This API is for redeeming a Binance Gift Card
    /// Once redeemed, the coins will be deposited in your funding wallet.
    ///
    /// * Parameter code can be sent in two formats:
    /// * Plaintext
    /// * Encrypted
    ///
    /// * Sending code in Encrypted format provides more security than sending it as a plaintext. To send card code in encrypted format the following steps must be followed:
    /// * Fetch RSA public key from api stated below.
    /// * Use the below algorithm to encrypt the card code using the RSA public key fetched above: `RSA/ECB/OAEPWithSHA-256AndMGF1Padding`
    /// **A sample code snippet (JAVA) is stated below for reference, the same approach can be used for different languages like C#, PERL, PYTHON, SHELL etc.:**
    ///
    /// Weight: 1
    ///
    /// # Arguments
    ///
    /// - `params`: [`RedeemABinanceGiftCardParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::RedeemABinanceGiftCardResponse>`] 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/gift_card/market-data/Redeem-a-Binance-Gift-Card).
    ///
    pub async fn redeem_a_binance_gift_card(
        &self,
        params: RedeemABinanceGiftCardParams,
    ) -> anyhow::Result<RestApiResponse<models::RedeemABinanceGiftCardResponse>> {
        self.market_data_api_client
            .redeem_a_binance_gift_card(params)
            .await
    }

    /// Verify Binance Gift Card by Gift Card `Number(USER_DATA)`
    ///
    /// This API is for verifying whether the Binance Gift Card is valid or not by entering Gift Card Number.
    ///
    /// **Please note that if you enter the wrong Gift Card Number 5 times within an hour, you will no longer be able to verify any Gift Card Number for that hour.**
    ///
    /// Weight: 1
    ///
    /// # Arguments
    ///
    /// - `params`: [`VerifyBinanceGiftCardByGiftCardNumberParams`]
    ///   The parameters for this operation.
    ///
    /// # Returns
    ///
    /// [`RestApiResponse<models::VerifyBinanceGiftCardByGiftCardNumberResponse>`] 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/gift_card/market-data/Verify-Binance-Gift-Card-by-Gift-Card-Number).
    ///
    pub async fn verify_binance_gift_card_by_gift_card_number(
        &self,
        params: VerifyBinanceGiftCardByGiftCardNumberParams,
    ) -> anyhow::Result<RestApiResponse<models::VerifyBinanceGiftCardByGiftCardNumberResponse>>
    {
        self.market_data_api_client
            .verify_binance_gift_card_by_gift_card_number(params)
            .await
    }
}
