use std::sync::Arc;
use tokio::sync::mpsc;

use common_contracts::{
    messages::FetchCompanyDataCommand,
    workflow_harness::StandardFetchWorkflow,
    abstraction::DataProviderLogic,
    dtos::{CompanyProfileDto, TimeSeriesFinancialDto},
};

use crate::{error::AppError, state::AppState};

/// Tushare 核心业务逻辑实现
pub struct TushareFetcher {
    state: Arc<AppState>,
}

impl TushareFetcher {
    pub fn new(state: Arc<AppState>) -> Self {
        Self { state }
    }
}

#[async_trait::async_trait]
impl DataProviderLogic for TushareFetcher {
    fn provider_id(&self) -> &str {
        "tushare"
    }

    fn supports_market(&self, market: &str) -> bool {
        // Tushare 仅支持中国市场
        market.to_uppercase() == "CN"
    }

    async fn fetch_data(&self, symbol: &str) -> anyhow::Result<(CompanyProfileDto, Vec<TimeSeriesFinancialDto>)> {
        let provider_option = self.state.get_provider().await;
        let provider = provider_option.ok_or_else(|| anyhow::anyhow!("Tushare provider not configured"))?;
            
        let (profile, financials) = provider.fetch_all_data(symbol).await
            .map_err(|e| anyhow::anyhow!("Tushare API error: {}", e))?;
            
        Ok((profile, financials))
    }
}

pub async fn run_tushare_workflow(
    state: Arc<AppState>,
    command: FetchCompanyDataCommand,
    completion_tx: mpsc::Sender<()>,
) -> Result<(), AppError> {
    let fetcher = Arc::new(TushareFetcher::new(state.clone()));
    
    // 使用通用工作流引擎
    StandardFetchWorkflow::run(
        state.clone(),
        fetcher,
        command,
        Some(completion_tx)
    ).await.map_err(|e| AppError::Internal(e.to_string()))?;

    Ok(())
}

#[cfg(test)]
mod integration_tests {
    use super::*;
    use crate::config::AppConfig;
    use crate::state::AppState;
    use secrecy::SecretString;
    use common_contracts::observability::{TaskProgress, ObservabilityTaskStatus};
    use common_contracts::symbol_utils::{CanonicalSymbol, Market};
    use uuid::Uuid;
    use chrono::Utc;

    #[tokio::test]
    async fn test_tushare_fetch_flow() {
        if std::env::var("NATS_ADDR").is_err() {
             println!("Skipping integration test (no environment)");
             return;
        }

        // 1. Environment
        let api_key = std::env::var("TUSHARE_API_KEY")
            .unwrap_or_else(|_| "f62b415de0a5a947fcb693b66cd299dd6242868bf04ad687800c7f3f".to_string());
        
        let api_url = std::env::var("TUSHARE_API_URL")
            .unwrap_or_else(|_| "http://api.tushare.pro".to_string());

        let config = AppConfig::load().expect("Failed to load config");
        let state = Arc::new(AppState::new(config.clone()));

        // 2. Manual Init Provider
        state.update_provider(
            Some(SecretString::new(api_key.into())),
            Some(api_url)
        ).await;

        // 3. Construct Command
        let request_id = Uuid::new_v4();
        let cmd = FetchCompanyDataCommand {
            request_id,
            symbol: CanonicalSymbol::new("600519", &Market::CN),
            market: "CN".to_string(),
            template_id: Some("default".to_string()),
            output_path: None,
        };
        
        // Init task
        state.tasks.insert(request_id, TaskProgress {
             request_id,
             task_name: "tushare:600519".to_string(),
             status: ObservabilityTaskStatus::Queued,
             progress_percent: 0,
             details: "Init".to_string(),
             started_at: Utc::now()
        });

        // 4. Run
        let (tx, mut rx) = mpsc::channel(1);
        let result = run_tushare_workflow(state.clone(), cmd, tx).await;

        // 5. Assert
        assert!(result.is_ok(), "Worker execution failed: {:?}", result.err());
        
        // Wait for completion signal
        let _ = rx.recv().await;
        
        let task = state.tasks.get(&request_id).expect("Task should exist");
        assert_eq!(task.status, ObservabilityTaskStatus::Completed);
    }
}
