/*
 * 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.1
 * 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};

/// 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 [`purchase_whats_app_phone_number`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PurchaseWhatsAppPhoneNumberError {
    Status400(),
    Status401(models::InlineObject),
    Status403(),
    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),
}

/// Retrieve the current status of a purchased phone number. Used to poll for Meta pre-verification completion after purchase.
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,
        }))
    }
}

/// 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,
        }))
    }
}
