/*
 * 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 [`create_account_group`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum CreateAccountGroupError {
    Status400(),
    Status401(models::InlineObject),
    Status409(),
    UnknownValue(serde_json::Value),
}

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

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

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

/// Creates a new account group with a name and a list of social account IDs. Accounts can belong to different profiles; the caller must have access to every account's profile. Group names must be unique per user.
pub async fn create_account_group(
    configuration: &configuration::Configuration,
    create_account_group_request: models::CreateAccountGroupRequest,
) -> Result<models::CreateAccountGroup201Response, Error<CreateAccountGroupError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_body_create_account_group_request = create_account_group_request;

    let uri_str = format!("{}/v1/account-groups", 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_create_account_group_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::CreateAccountGroup201Response`"))),
            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::CreateAccountGroup201Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<CreateAccountGroupError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Permanently deletes an account group. The accounts themselves are not affected.
pub async fn delete_account_group(
    configuration: &configuration::Configuration,
    group_id: &str,
) -> Result<models::DeleteAccountGroup200Response, Error<DeleteAccountGroupError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_group_id = group_id;

    let uri_str = format!(
        "{}/v1/account-groups/{groupId}",
        configuration.base_path,
        groupId = crate::apis::urlencode(p_path_group_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::DeleteAccountGroup200Response`"))),
            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::DeleteAccountGroup200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<DeleteAccountGroupError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Returns all account groups visible to the authenticated user. Groups can contain accounts from multiple profiles. For API keys scoped to specific profiles, only groups whose accounts all live in allowed profiles are returned.
pub async fn list_account_groups(
    configuration: &configuration::Configuration,
) -> Result<models::ListAccountGroups200Response, Error<ListAccountGroupsError>> {
    let uri_str = format!("{}/v1/account-groups", 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::ListAccountGroups200Response`"))),
            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::ListAccountGroups200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<ListAccountGroupsError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Updates the name or account list of an existing group. You can rename the group, change its accounts, or both.
pub async fn update_account_group(
    configuration: &configuration::Configuration,
    group_id: &str,
    update_account_group_request: models::UpdateAccountGroupRequest,
) -> Result<models::UpdateAccountGroup200Response, Error<UpdateAccountGroupError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_group_id = group_id;
    let p_body_update_account_group_request = update_account_group_request;

    let uri_str = format!(
        "{}/v1/account-groups/{groupId}",
        configuration.base_path,
        groupId = crate::apis::urlencode(p_path_group_id)
    );
    let mut req_builder = configuration.client.request(reqwest::Method::PUT, &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_update_account_group_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::UpdateAccountGroup200Response`"))),
            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::UpdateAccountGroup200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<UpdateAccountGroupError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}
