use crate::repository::api::prelude::*;

/// Get available payment systems
pub async fn get_active_payment_systems() -> Result<Vec<PaymentSystem>> {
    let url = format!("{host}/payment_system?select=id,name&active=is.true",
                      host=&*BACKEND_API_URL);
    log::trace!("fetching {url}", url = url.red());

    let response = reqwest::Client::new()
        .get(&url)
        .header(
            "Authorization",
            get_auth_token().await?,
        )
        .send()
        .await?;

    match response.status() {
        reqwest::StatusCode::OK => {
            let payment_systems = response.json::<Vec<PaymentSystem>>().await?;
            Ok(payment_systems)
        }
        _ => Err(Report::msg(format!(
            "Failed to get active payment systems: {}",
            response.text().await?
        ))),
    }
}

/// Get tariff price by ID
pub async fn get_tariff_price(tariff_id: u32) -> Result<f64> {
    #[derive(Deserialize)]
    struct TariffPrice {
        price: String,
    }

    let url = format!("{host}/tariff?select=price&id=eq.{}", tariff_id, host=&*BACKEND_API_URL);
    log::trace!("fetching {url}", url = url.red());

    let response = reqwest::Client::new()
        .get(&url)
        .header(
            "Authorization",
            get_auth_token().await?,
        )
        .send()
        .await?;

    match response.status() {
        reqwest::StatusCode::OK => {
            let tariff = response.json::<Vec<TariffPrice>>().await?;
            Ok(tariff[0].price[1..].parse::<f64>().unwrap())
        }
        _ => Err(Report::msg(format!(
            "Failed to get tariff price: {}",
            response.text().await?
        ))),
    }
}

/// Get banners
pub async fn get_banners() -> Result<Vec<Banner>> {
    let url = format!("{host}/rpc/get_banners", host=&*BACKEND_API_URL);
    log::trace!("fetching {url}", url = url.red());

    let response = reqwest::Client::new()
        .get(&url)
        .header("Authorization", get_auth_token().await?)
        .send()
        .await?;

    let status = response.status();
    let response_body = response.text().await?;

    log::debug!("get banners response is `{}`", response_body);

    if !status.is_success() {
        return Err(Report::msg(format!(
            "Failed to get banners: {}",
            prettify_json_or_text(&response_body)
        )));
    }

    let banners = serde_json::from_str::<Vec<Banner>>(&response_body)?;
    Ok(banners)
}

/// Get banner blob data
pub async fn get_banner_blob(banner_id: i32) -> Result<Vec<u8>> {
    let url = format!("{host}/rpc/get_banner_blob?id={banner_id}", host=&*BACKEND_API_URL);
    log::trace!("fetching {url}", url = url.red());

    let response = reqwest::Client::new()
        .get(&url)
        .header("Authorization", get_auth_token().await?)
        .header("Accept", "application/octet-stream")
        .send()
        .await?;

    let status = response.status();

    if !status.is_success() {
        let error_text = response.text().await?;
        return Err(Report::msg(format!(
            "Failed to get banner blob: {}",
            prettify_json_or_text(&error_text)
        )));
    }

    let image_bytes = response.bytes().await?;
    Ok(image_bytes.to_vec())
}
