use crate::error::ProviderError;
use reqwest::Client;
use secrecy::{ExposeSecret, SecretString};
use serde::Serialize;

#[derive(Clone)]
pub struct LlmClient {
    client: Client,
    api_url: String,
    api_key: SecretString,
    model: String,
}

#[derive(Serialize)]
struct LlmRequest {
    model: String,
    prompt: String,
}


impl LlmClient {
    pub fn new(api_url: String, api_key: SecretString, model: String) -> Self {
        Self {
            client: Client::new(),
            api_url,
            api_key,
            model,
        }
    }

    pub async fn generate_text(&self, prompt: String) -> Result<String, ProviderError> {
        let request_payload = LlmRequest {
            model: self.model.clone(),
            prompt,
        };

        let res = self
            .client
            .post(&self.api_url)
            .bearer_auth(self.api_key.expose_secret())
            .json(&request_payload)
            .send()
            .await?;

        if !res.status().is_success() {
            let status = res.status();
            let error_text = res
                .text()
                .await
                .unwrap_or_else(|_| "Unknown LLM API error".to_string());
            return Err(ProviderError::LlmApi(format!(
                "LLM API request failed with status {}: {}",
                status,
                error_text
            )));
        }

        // This part needs to be adapted to the actual LLM provider's response format
        let response_data: serde_json::Value = res.json().await?;
        let text = response_data["choices"][0]["text"]
            .as_str()
            .unwrap_or("")
            .to_string();

        Ok(text)
    }
}
