//!
//! 数据持久化服务客户端
//!

use crate::error::Result;
use common_contracts::dtos::CompanyProfileDto;
use common_contracts::config_models::{LlmProvidersConfig, DataSourcesConfig, AnalysisTemplateSets};

#[derive(Clone)]
pub struct PersistenceClient {
    client: reqwest::Client,
    base_url: String,
}

impl PersistenceClient {
    pub fn new(base_url: String) -> Self {
        Self {
            client: reqwest::Client::new(),
            base_url,
        }
    }

    pub async fn get_company_profile(&self, symbol: &str) -> Result<CompanyProfileDto> {
        let url = format!("{}/companies/{}", self.base_url, symbol);
        let profile = self
            .client
            .get(&url)
            .send()
            .await?
            .error_for_status()?
            .json::<CompanyProfileDto>()
            .await?;
        Ok(profile)
    }

    // --- Config Methods ---

    pub async fn get_llm_providers_config(&self) -> Result<LlmProvidersConfig> {
        let url = format!("{}/configs/llm_providers", self.base_url);
        let config = self
            .client
            .get(&url)
            .send()
            .await?
            .error_for_status()?
            .json::<LlmProvidersConfig>()
            .await?;
        Ok(config)
    }

    pub async fn update_llm_providers_config(
        &self,
        payload: &LlmProvidersConfig,
    ) -> Result<LlmProvidersConfig> {
        let url = format!("{}/configs/llm_providers", self.base_url);
        let updated_config = self
            .client
            .put(&url)
            .json(payload)
            .send()
            .await?
            .error_for_status()?
            .json::<LlmProvidersConfig>()
            .await?;
        Ok(updated_config)
    }

    pub async fn get_analysis_template_sets(&self) -> Result<AnalysisTemplateSets> {
        let url = format!("{}/configs/analysis_template_sets", self.base_url);
        let config = self
            .client
            .get(&url)
            .send()
            .await?
            .error_for_status()?
            .json::<AnalysisTemplateSets>()
            .await?;
        Ok(config)
    }

    pub async fn update_analysis_template_sets(
        &self,
        payload: &AnalysisTemplateSets,
    ) -> Result<AnalysisTemplateSets> {
        let url = format!("{}/configs/analysis_template_sets", self.base_url);
        let updated_config = self
            .client
            .put(&url)
            .json(payload)
            .send()
            .await?
            .error_for_status()?
            .json::<AnalysisTemplateSets>()
            .await?;
        Ok(updated_config)
    }

    pub async fn get_data_sources_config(&self) -> Result<DataSourcesConfig> {
        let url = format!("{}/configs/data_sources", self.base_url);
        let config = self
            .client
            .get(&url)
            .send()
            .await?
            .error_for_status()?
            .json::<DataSourcesConfig>()
            .await?;
        Ok(config)
    }

    pub async fn update_data_sources_config(&self, payload: &DataSourcesConfig) -> Result<DataSourcesConfig> {
        let url = format!("{}/configs/data_sources", self.base_url);
        let updated_config = self
            .client
            .put(&url)
            .json(payload)
            .send()
            .await?
            .error_for_status()?
            .json::<DataSourcesConfig>()
            .await?;
        Ok(updated_config)
    }
}
