/*
 * Zernio API
 *
 * API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
 *
 * The version of the OpenAPI document: 1.0.4
 * Contact: support@zernio.com
 * Generated by: https://openapi-generator.tech
 */

use super::{configuration, ContentType, Error};
use crate::{apis::ResponseContent, models};
use reqwest;
use serde::{de::Error as _, Deserialize, Serialize};
use tokio::fs::File as TokioFile;
use tokio_util::codec::{BytesCodec, FramedRead};

/// struct for typed errors of method [`get_whats_app_number_info`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetWhatsAppNumberInfoError {
    Status400(),
    Status401(models::InlineObject),
    Status404(),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`get_whats_app_number_kyc_form`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetWhatsAppNumberKycFormError {
    Status400(),
    Status401(models::InlineObject),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`get_whats_app_phone_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetWhatsAppPhoneNumberError {
    Status401(models::InlineObject),
    Status404(models::InlineObject1),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`get_whats_app_phone_numbers`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetWhatsAppPhoneNumbersError {
    Status401(models::InlineObject),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`list_whats_app_number_countries`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ListWhatsAppNumberCountriesError {
    Status401(models::InlineObject),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`purchase_whats_app_phone_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PurchaseWhatsAppPhoneNumberError {
    Status400(),
    Status401(models::InlineObject),
    Status403(),
    Status402(),
    Status422(),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`release_whats_app_phone_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ReleaseWhatsAppPhoneNumberError {
    Status400(),
    Status401(models::InlineObject),
    Status404(models::InlineObject1),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`search_available_whats_app_numbers`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SearchAvailableWhatsAppNumbersError {
    Status400(),
    Status401(models::InlineObject),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`submit_whats_app_number_kyc`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SubmitWhatsAppNumberKycError {
    Status400(),
    Status409(),
    Status401(models::InlineObject),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`upload_whats_app_number_kyc_document`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UploadWhatsAppNumberKycDocumentError {
    Status400(),
    Status401(models::InlineObject),
    UnknownValue(serde_json::Value),
}

/// Live snapshot of a connected number straight from Meta: the phone-number node (display number, display name + approval, quality rating, messaging-limit tier, throughput, official-business badge, connection status, health_status) and its owning WhatsApp Business Account (name, business verification, timezone, health_status). Fetched live because Meta updates quality/tier/name/health over time; the call also refreshes the cached values shown on the connection card.
pub async fn get_whats_app_number_info(
    configuration: &configuration::Configuration,
    account_id: &str,
) -> Result<models::GetWhatsAppNumberInfo200Response, Error<GetWhatsAppNumberInfoError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_query_account_id = account_id;

    let uri_str = format!("{}/v1/whatsapp/number-info", configuration.base_path);
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    req_builder = req_builder.query(&[("accountId", &p_query_account_id.to_string())]);
    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetWhatsAppNumberInfo200Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetWhatsAppNumberInfo200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<GetWhatsAppNumberInfoError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// For a Tier 3/4 country, the fields the end customer must provide (Telnyx regulatory requirements) before a number can be ordered: text, date, address, or file (document) per requirement.
pub async fn get_whats_app_number_kyc_form(
    configuration: &configuration::Configuration,
    country: &str,
    profile_id: &str,
) -> Result<models::GetWhatsAppNumberKycForm200Response, Error<GetWhatsAppNumberKycFormError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_query_country = country;
    let p_query_profile_id = profile_id;

    let uri_str = format!("{}/v1/whatsapp/phone-numbers/kyc", configuration.base_path);
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    req_builder = req_builder.query(&[("country", &p_query_country.to_string())]);
    req_builder = req_builder.query(&[("profileId", &p_query_profile_id.to_string())]);
    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetWhatsAppNumberKycForm200Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetWhatsAppNumberKycForm200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<GetWhatsAppNumberKycFormError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Retrieve the current status of a purchased phone number. Poll this to track Meta pre-verification (US sync path) and, for regulated (Tier 3/4) numbers, the async lifecycle: pending_regulatory → active (or regulatory_declined). When a regulated number has an Onfido ID step, `onfidoVerificationUrl` appears here once the order is placed — forward it to the end user. (Or subscribe to the whatsapp.number.* webhooks instead of polling.)
pub async fn get_whats_app_phone_number(
    configuration: &configuration::Configuration,
    phone_number_id: &str,
) -> Result<models::GetWhatsAppPhoneNumber200Response, Error<GetWhatsAppPhoneNumberError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_phone_number_id = phone_number_id;

    let uri_str = format!(
        "{}/v1/whatsapp/phone-numbers/{phoneNumberId}",
        configuration.base_path,
        phoneNumberId = crate::apis::urlencode(p_path_phone_number_id)
    );
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetWhatsAppPhoneNumber200Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetWhatsAppPhoneNumber200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<GetWhatsAppPhoneNumberError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// List all WhatsApp phone numbers purchased by the authenticated user. By default, released numbers are excluded.
pub async fn get_whats_app_phone_numbers(
    configuration: &configuration::Configuration,
    status: Option<&str>,
    profile_id: Option<&str>,
) -> Result<models::GetWhatsAppPhoneNumbers200Response, Error<GetWhatsAppPhoneNumbersError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_query_status = status;
    let p_query_profile_id = profile_id;

    let uri_str = format!("{}/v1/whatsapp/phone-numbers", configuration.base_path);
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    if let Some(ref param_value) = p_query_status {
        req_builder = req_builder.query(&[("status", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_profile_id {
        req_builder = req_builder.query(&[("profileId", &param_value.to_string())]);
    }
    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetWhatsAppPhoneNumbers200Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetWhatsAppPhoneNumbers200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<GetWhatsAppPhoneNumbersError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// The WhatsApp number countries available to purchase, each with its flat monthly price (cents), regulatory tier, whether it needs end-user KYC (Tier 3/4), and whether outbound calling is available (not BIC-blocked). Drives the country picker. Tier-4 countries appear only when enabled.
pub async fn list_whats_app_number_countries(
    configuration: &configuration::Configuration,
) -> Result<models::ListWhatsAppNumberCountries200Response, Error<ListWhatsAppNumberCountriesError>>
{
    let uri_str = format!(
        "{}/v1/whatsapp/phone-numbers/countries",
        configuration.base_path
    );
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListWhatsAppNumberCountries200Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListWhatsAppNumberCountries200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<ListWhatsAppNumberCountriesError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Initiate purchasing a WhatsApp phone number. Payment-first flow: the user does not pick a specific number. The system either creates a Stripe Checkout Session (first number) or increments the existing subscription quantity and provisions inline (subsequent numbers).  Requires a paid plan. The maximum number of phone numbers is determined by the user's plan.
pub async fn purchase_whats_app_phone_number(
    configuration: &configuration::Configuration,
    purchase_whats_app_phone_number_request: models::PurchaseWhatsAppPhoneNumberRequest,
) -> Result<models::PurchaseWhatsAppPhoneNumber200Response, Error<PurchaseWhatsAppPhoneNumberError>>
{
    // add a prefix to parameters to efficiently prevent name collisions
    let p_body_purchase_whats_app_phone_number_request = purchase_whats_app_phone_number_request;

    let uri_str = format!(
        "{}/v1/whatsapp/phone-numbers/purchase",
        configuration.base_path
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };
    req_builder = req_builder.json(&p_body_purchase_whats_app_phone_number_request);

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PurchaseWhatsAppPhoneNumber200Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PurchaseWhatsAppPhoneNumber200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<PurchaseWhatsAppPhoneNumberError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Release a purchased phone number. This will: 1. Disconnect any linked WhatsApp social account 2. Decrement the Stripe subscription quantity (or cancel if last number) 3. Release the number from Telnyx 4. Mark the number as released
pub async fn release_whats_app_phone_number(
    configuration: &configuration::Configuration,
    phone_number_id: &str,
) -> Result<models::ReleaseWhatsAppPhoneNumber200Response, Error<ReleaseWhatsAppPhoneNumberError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_phone_number_id = phone_number_id;

    let uri_str = format!(
        "{}/v1/whatsapp/phone-numbers/{phoneNumberId}",
        configuration.base_path,
        phoneNumberId = crate::apis::urlencode(p_path_phone_number_id)
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::DELETE, &uri_str);

    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ReleaseWhatsAppPhoneNumber200Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ReleaseWhatsAppPhoneNumber200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<ReleaseWhatsAppPhoneNumberError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Search the provider's inventory for numbers available to purchase in a country (default US). Optional filters narrow the results. The country must be offerable (see GET /v1/whatsapp/phone-numbers/countries).
pub async fn search_available_whats_app_numbers(
    configuration: &configuration::Configuration,
    country: Option<&str>,
    r#type: Option<&str>,
    prefix: Option<&str>,
    locality: Option<&str>,
    contains: Option<&str>,
    limit: Option<i32>,
) -> Result<
    models::SearchAvailableWhatsAppNumbers200Response,
    Error<SearchAvailableWhatsAppNumbersError>,
> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_query_country = country;
    let p_query_type = r#type;
    let p_query_prefix = prefix;
    let p_query_locality = locality;
    let p_query_contains = contains;
    let p_query_limit = limit;

    let uri_str = format!(
        "{}/v1/whatsapp/phone-numbers/available",
        configuration.base_path
    );
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    if let Some(ref param_value) = p_query_country {
        req_builder = req_builder.query(&[("country", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_type {
        req_builder = req_builder.query(&[("type", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_prefix {
        req_builder = req_builder.query(&[("prefix", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_locality {
        req_builder = req_builder.query(&[("locality", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_contains {
        req_builder = req_builder.query(&[("contains", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_limit {
        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
    }
    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SearchAvailableWhatsAppNumbers200Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SearchAvailableWhatsAppNumbers200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<SearchAvailableWhatsAppNumbersError> =
            serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Submit the end customer's KYC (textual values, uploaded documents, address) for a Tier 3/4 country. Documents are streamed straight to the number provider and are not stored by Zernio. Builds + submits a regulatory requirement group and claims a pending_regulatory slot; the number is ordered + activated once the provider approves (asynchronous). A customer may hold several same-country numbers in review at once; a double-submit of the SAME attempt is deduped via `submissionId`.
pub async fn submit_whats_app_number_kyc(
    configuration: &configuration::Configuration,
    submit_whats_app_number_kyc_request: models::SubmitWhatsAppNumberKycRequest,
) -> Result<models::SubmitWhatsAppNumberKyc200Response, Error<SubmitWhatsAppNumberKycError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_body_submit_whats_app_number_kyc_request = submit_whats_app_number_kyc_request;

    let uri_str = format!("{}/v1/whatsapp/phone-numbers/kyc", configuration.base_path);
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };
    req_builder = req_builder.json(&p_body_submit_whats_app_number_kyc_request);

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SubmitWhatsAppNumberKyc200Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SubmitWhatsAppNumberKyc200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<SubmitWhatsAppNumberKycError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Upload ONE document and get back its provider document id, to reference from POST /v1/whatsapp/phone-numbers/kyc via `documents[].documentId`. Send the RAW file bytes as the request body (not base64); put the filename in the `X-Filename` header. Uploading documents one-per-request keeps each request under the ~4.5MB body limit. The document streams straight to the number provider and is not stored by Zernio.
pub async fn upload_whats_app_number_kyc_document(
    configuration: &configuration::Configuration,
    x_filename: &str,
    body: std::path::PathBuf,
) -> Result<
    models::UploadWhatsAppNumberKycDocument200Response,
    Error<UploadWhatsAppNumberKycDocumentError>,
> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_header_x_filename = x_filename;
    let p_body_body = body;

    let uri_str = format!(
        "{}/v1/whatsapp/phone-numbers/kyc/upload-document",
        configuration.base_path
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    req_builder = req_builder.header("X-Filename", p_header_x_filename.to_string());
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };
    let file = TokioFile::open(p_body_body).await?;
    let stream = FramedRead::new(file, BytesCodec::new());
    req_builder = req_builder.body(reqwest::Body::wrap_stream(stream));

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UploadWhatsAppNumberKycDocument200Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UploadWhatsAppNumberKycDocument200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<UploadWhatsAppNumberKycDocumentError> =
            serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}
