/*
 * 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_google_business_location_details`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetGoogleBusinessLocationDetailsError {
    Status400(models::ErrorResponse),
    Status401(models::ErrorResponse),
    Status404(models::InlineObject1),
    UnknownValue(serde_json::Value),
}

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

/// Returns detailed GBP location info (hours, description, phone, website, categories, services). Use readMask to request specific fields.
pub async fn get_google_business_location_details(
    configuration: &configuration::Configuration,
    account_id: &str,
    location_id: Option<&str>,
    read_mask: Option<&str>,
) -> Result<
    models::GetGoogleBusinessLocationDetails200Response,
    Error<GetGoogleBusinessLocationDetailsError>,
> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_account_id = account_id;
    let p_query_location_id = location_id;
    let p_query_read_mask = read_mask;

    let uri_str = format!(
        "{}/v1/accounts/{accountId}/gmb-location-details",
        configuration.base_path,
        accountId = crate::apis::urlencode(p_path_account_id)
    );
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    if let Some(ref param_value) = p_query_location_id {
        req_builder = req_builder.query(&[("locationId", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_read_mask {
        req_builder = req_builder.query(&[("readMask", &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::GetGoogleBusinessLocationDetails200Response`"))),
            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::GetGoogleBusinessLocationDetails200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<GetGoogleBusinessLocationDetailsError> =
            serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Updates GBP location details. The updateMask field is required and specifies which fields to update. This endpoint proxies Google's Business Information API locations.patch, so any valid updateMask field is supported. Common fields: regularHours, specialHours, profile.description, websiteUri, phoneNumbers, categories, serviceItems.
pub async fn update_google_business_location_details(
    configuration: &configuration::Configuration,
    account_id: &str,
    update_google_business_location_details_request: models::UpdateGoogleBusinessLocationDetailsRequest,
    location_id: Option<&str>,
) -> Result<
    models::UpdateGoogleBusinessLocationDetails200Response,
    Error<UpdateGoogleBusinessLocationDetailsError>,
> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_account_id = account_id;
    let p_body_update_google_business_location_details_request =
        update_google_business_location_details_request;
    let p_query_location_id = location_id;

    let uri_str = format!(
        "{}/v1/accounts/{accountId}/gmb-location-details",
        configuration.base_path,
        accountId = crate::apis::urlencode(p_path_account_id)
    );
    let mut req_builder = configuration.client.request(reqwest::Method::PUT, &uri_str);

    if let Some(ref param_value) = p_query_location_id {
        req_builder = req_builder.query(&[("locationId", &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());
    };
    req_builder = req_builder.json(&p_body_update_google_business_location_details_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::UpdateGoogleBusinessLocationDetails200Response`"))),
            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::UpdateGoogleBusinessLocationDetails200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<UpdateGoogleBusinessLocationDetailsError> =
            serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}
