use serde::{Serialize, Deserialize};
use std::collections::HashMap;
use std::ops::{Deref, DerefMut};
use service_kit::api_dto;

// 单个启用的模型
#[api_dto]
pub struct LlmModel {
    pub model_id: String,           // e.g., "gpt-4o"
    pub name: Option<String>,       // 别名，用于UI显示
    pub is_active: bool,            // 是否在UI中可选
}

// 单个LLM供应商的完整配置
#[api_dto]
pub struct LlmProvider {
    pub name: String,               // "OpenAI 官方"
    pub api_base_url: String,
    pub api_key: String,            // 直接明文存储
    pub models: Vec<LlmModel>,      // 该供应商下我们启用的模型列表
}

// 整个LLM Provider注册中心的数据结构
// Key: provider_id, e.g., "openai_official"
#[api_dto]
#[serde(transparent)]
#[derive(Default)]
#[schema(value_type = HashMap<String, LlmProvider>)]
pub struct LlmProvidersConfig(pub HashMap<String, LlmProvider>);

impl LlmProvidersConfig {
    pub fn new() -> Self {
        Self(HashMap::new())
    }
}

impl Deref for LlmProvidersConfig {
    type Target = HashMap<String, LlmProvider>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for LlmProvidersConfig {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

// --- Analysis Module Config (NEW TEMPLATE-BASED STRUCTURE) ---

/// Top-level configuration object for all analysis templates.
/// Key: Template ID (e.g., "standard_fundamentals")
#[api_dto]
#[serde(transparent)]
#[derive(Default)]
#[schema(value_type = HashMap<String, AnalysisTemplateSet>)]
pub struct AnalysisTemplateSets(pub HashMap<String, AnalysisTemplateSet>);

impl AnalysisTemplateSets {
    pub fn new() -> Self {
        Self(HashMap::new())
    }
}

impl Deref for AnalysisTemplateSets {
    type Target = HashMap<String, AnalysisTemplateSet>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for AnalysisTemplateSets {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

/// A single, self-contained set of analysis modules representing a complete workflow.
/// e.g., "Standard Fundamental Analysis"
#[api_dto]
#[derive(PartialEq)]
pub struct AnalysisTemplateSet {
    /// Human-readable name for the template set.
    pub name: String,
    /// All analysis modules contained within this template set.
    /// Key: Module ID (e.g., "fundamental_analysis")
    pub modules: HashMap<String, AnalysisModuleConfig>,
}

/// Summary of an analysis template (for listing purposes).
#[api_dto]
pub struct AnalysisTemplateSummary {
    pub id: String,
    pub name: String,
}

/// Configuration for a single analysis module.
pub use crate::configs::AnalysisModuleConfig;

// --- Analysis Module Config (OLD DEPRECATED STRUCTURE) ---

// This is the old, flat structure for analysis modules.
// It is DEPRECATED and will be removed once all services are migrated
// to the new AnalysisTemplateSets model.
pub type AnalysisModulesConfig = HashMap<String, OldAnalysisModuleConfig>;

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct OldAnalysisModuleConfig {
    pub name: String,
    pub provider_id: String,
    pub model_id: String,
    pub prompt_template: String,
    pub dependencies: Vec<String>,
}


#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct SystemConfig {
    pub llm_providers: LlmProvidersConfig,
    pub analysis_modules: AnalysisModulesConfig,
}

#[api_dto]
#[derive(PartialEq)]
pub enum DataSourceProvider {
    Tushare,
    Finnhub,
    Alphavantage,
    Yfinance,
}

#[api_dto]
#[derive(PartialEq)]
pub struct DataSourceConfig {
    pub provider: DataSourceProvider,
    pub api_key: Option<String>,
    pub api_url: Option<String>,
    pub enabled: bool,
}

// 数据源配置集合（集中、强类型、单一来源）
#[api_dto]
#[serde(transparent)]
#[derive(Default)]
#[schema(value_type = HashMap<String, DataSourceConfig>)]
pub struct DataSourcesConfig(pub HashMap<String, DataSourceConfig>);

impl DataSourcesConfig {
    pub fn new() -> Self {
        Self(HashMap::new())
    }
}

impl Deref for DataSourcesConfig {
    type Target = HashMap<String, DataSourceConfig>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for DataSourcesConfig {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}
