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

pub async fn translate(hash: String, label: String, content: String, lable_lang: Language, lang: Language) -> Result<String> {
    let url = format!("{}/rpc/i18n.translate", &*BACKEND_API_URL);
    log::trace!("fetching {url}", url = url.red());

    let token = get_auth_token().await?;

    let body = serde_json::json!({
        "hash": hash,
        "label": label,
        "content": content,
        "lable_lang_code": lable_lang,
        "lang_code": lang,
    });

    let client = reqwest::Client::new();
    let response = client.post(&url)
        .header("authorization", &token)
        .header("content-type", "application/json")
        .header("accept", "text/plain")
        .json(&body)
        .send()
        .await?;

    let status = response.status();
    if status.as_u16() / 100 != 2 {
        let body = prettify_json_or_text(&response.text().await?);
        log::error!("failed to translate: {}", body);
        return Err(Report::msg(format!(
            "failed to translate: {}",
            body
        )));
    }

    Ok(response.text().await?)
}

pub async fn get_translation_dictionary(lang: Language) -> Result<HashMap<String, String>> {
    let url = format!("{}/rpc/i18n.dictionary?lang_code={lang}", &*BACKEND_API_URL, lang = lang);
    log::trace!("fetching {url}", url = url.red());

    let token = get_auth_token().await?;

    let client = reqwest::Client::new();
    let response = client.get(&url)
        .header("authorization", &token)
        .header("content-type", "application/json")
        .header("accept", "application/json")
        .send()
        .await?;

    let status = response.status();
    if status.as_u16() / 100 != 2 {
        return Err(Report::msg(format!(
            "failed to get translation dictionary: {}",
            response.text().await.unwrap_or_default()
        )));
    }

    let response_text = response.text().await?;
    let dictionary: HashMap<String, String> = serde_json::from_str(&response_text)?;

    Ok(dictionary)
}


pub async fn save_translation_usage(usage_data: HashMap<String, SystemTime>) -> Result<()> {
    let url = format!("{}/rpc/update_translation_usage", &*BACKEND_API_URL);
    log::trace!("fetching {url}", url = url.red());

    let token = get_auth_token().await?;

    let client = reqwest::Client::new();
    let response = client.post(&url)
        .header("authorization", &token)
        .header("content-type", "application/json")
        .header("accept", "application/json")
        .json(&usage_data)
        .send()
        .await?;

    let status = response.status();

    if status.as_u16() / 100 != 2 {
        return Err(Report::msg(format!(
            "Failed to send usage data to database: {}",
            response.text().await.unwrap_or_default()
        )));
    }

    Ok(())
}

pub async fn bulk_load_translations(translations: &[(String, String, String, Language)]) -> Result<()> {
    let url = format!("{}/rpc/i18n.load", &*BACKEND_API_URL);
    log::trace!("fetching {url}", url = url.red());

    let token = get_auth_token().await?;

    let translations_json: Vec<serde_json::Value> = translations
        .iter()
        .map(|(hash, label, content, lang)| {
            serde_json::json!({
                "hash": hash,
                "label": label,
                "content": content,
                "lang": lang
            })
        })
        .collect();

    let client = reqwest::Client::new();
    let response = client.post(&url)
        .header("authorization", &token)
        .header("content-type", "application/json")
        .header("accept", "application/json")
        .json(&translations_json)
        .send()
        .await?;

    let status = response.status();
    if status.as_u16() / 100 != 2 {
        let body = prettify_json_or_text(&response.text().await?);
        log::error!("failed to bulk load translations: {}", body);
        return Err(Report::msg(format!(
            "failed to bulk load translations: {}",
            body
        )));
    }

    let response_text = response.text().await?;
    let results: Vec<serde_json::Value> = serde_json::from_str(&response_text)?;
    
    for result in results {
        if let Some(status) = result.get("status").and_then(|s| s.as_str()) {
            if status == "error" {
                let hash = result.get("hash").and_then(|h| h.as_str()).unwrap_or("unknown");
                let error = result.get("error_message").and_then(|e| e.as_str()).unwrap_or("unknown error");
                log::warn!("Failed to load translation {}: {}", hash, error);
            }
        }
    }

    Ok(())
}