use uuid::Uuid;
use crate::symbol_utils::CanonicalSymbol;
use crate::subjects::{NatsSubject, SubjectMessage};
use std::collections::HashMap;
use service_kit::api_dto;
use crate::configs::LlmConfig;

// --- Commands ---

// Topic: workflow.commands.start
/// Command to initiate a new workflow.
/// Published by: `api-gateway`
/// Consumed by: `workflow-orchestrator`
#[api_dto]
pub struct StartWorkflowCommand {
    pub request_id: Uuid,
    pub symbol: CanonicalSymbol,
    pub market: String,
    pub template_id: String,
}

impl SubjectMessage for StartWorkflowCommand {
    fn subject(&self) -> NatsSubject {
        NatsSubject::WorkflowCommandStart
    }
}

// Topic: workflow.commands.sync_state
/// Command to request a state snapshot for re-alignment.
/// Published by: `api-gateway` (on client connect/reconnect)
/// Consumed by: `workflow-orchestrator`
#[api_dto]
pub struct SyncStateCommand {
    pub request_id: Uuid,
}

impl SubjectMessage for SyncStateCommand {
    fn subject(&self) -> NatsSubject {
        NatsSubject::WorkflowCommandSyncState
    }
}

/// Command to trigger data fetching.
/// Published by: `workflow-orchestrator` (previously api-gateway)
/// Consumed by: `*-provider-services`
#[api_dto]
pub struct FetchCompanyDataCommand {
    pub request_id: Uuid,
    pub symbol: CanonicalSymbol,
    pub market: String,
    pub template_id: Option<String>, // Optional trigger for analysis
    pub output_path: Option<String>,  // New: Unified I/O Binding
}

impl SubjectMessage for FetchCompanyDataCommand {
    fn subject(&self) -> NatsSubject {
        NatsSubject::DataFetchCommands
    }
}

/// Command to start a full report generation workflow.
/// Published by: `workflow-orchestrator` (previously api-gateway)
/// Consumed by: `report-generator-service`
#[api_dto]
pub struct GenerateReportCommand {
    pub request_id: Uuid,
    pub symbol: CanonicalSymbol,
    pub template_id: String,
    /// The task_id in the workflow DAG that triggered this. 
    /// Used for reporting progress/content back to the specific node.
    pub task_id: Option<String>,
    pub module_id: Option<String>,
    
    // --- New Fields for Refactored Context Mechanism ---
    pub commit_hash: Option<String>,
    pub input_bindings: Option<Vec<String>>, // Resolved physical paths
    pub output_path: Option<String>,
    pub llm_config: Option<LlmConfig>,
    pub analysis_prompt: Option<String>,
}

impl SubjectMessage for GenerateReportCommand {
    fn subject(&self) -> NatsSubject {
        NatsSubject::AnalysisCommandGenerateReport
    }
}

// --- Events ---

/// Metadata produced by a task execution.
#[api_dto]
pub struct TaskMetadata {
    /// The primary output file path (e.g. analysis report)
    pub output_path: Option<String>,
    /// The execution trace log path
    pub execution_log_path: Option<String>,
    /// Additional arbitrary metadata
    pub extra: HashMap<String, serde_json::Value>,
}

/// Comprehensive snapshot state for a single task
#[api_dto]
pub struct TaskStateSnapshot {
    pub task_id: String,
    pub status: TaskStatus,
    pub logs: Vec<String>, // Historical logs for this task
    pub content: Option<String>, // Current streamed content buffer
    pub input_commit: Option<String>,
    pub output_commit: Option<String>,
    pub metadata: Option<TaskMetadata>,
}

// Topic: events.workflow.{request_id}
/// Unified event stream for frontend consumption.
#[api_dto]
#[serde(tag = "type", content = "payload")] 
pub enum WorkflowEvent {
    // 1. 流程初始化 (携带完整的任务依赖图)
    WorkflowStarted { 
        timestamp: i64, 
        // 定义所有任务及其依赖关系，前端可据此绘制流程图或进度条
        task_graph: WorkflowDag 
    },
    
    // 2. 任务状态变更 (核心事件)
    TaskStateChanged {
        task_id: String, // e.g., "fetch:tushare", "process:clean_financials", "module:swot_analysis"
        task_type: TaskType, // DataFetch | DataProcessing | Analysis
        status: TaskStatus, // Pending, Scheduled, Running, Completed, Failed, Skipped
        message: Option<String>,
        timestamp: i64,
        progress: Option<u8>, // 0-100
        // New fields for Context Inspector
        input_commit: Option<String>,
        output_commit: Option<String>,
    },
    
    // 3. 任务流式输出 (用于 LLM 打字机效果)
    TaskStreamUpdate {
        task_id: String,
        content_delta: String,
        index: u32 
    },

    // 3.5. 任务日志 (用于实时展示详细执行过程)
    TaskLog {
        task_id: String,
        level: String, // INFO, WARN, ERROR
        message: String,
        timestamp: i64,
    },
    
    // 4. 流程整体结束
    WorkflowCompleted {
        result_summary: Option<serde_json::Value>,
        end_timestamp: i64
    },
    
    WorkflowFailed {
        reason: String,
        is_fatal: bool,
        end_timestamp: i64
    },
    
    // 5. 状态快照 (用于重连/丢包恢复)
    // 当前端重连或显式发送 SyncStateCommand 时，Orchestrator 发送此事件
    WorkflowStateSnapshot {
        timestamp: i64,
        task_graph: WorkflowDag,
        tasks_status: HashMap<String, TaskStatus>, // 当前所有任务的最新状态
        tasks_output: HashMap<String, Option<String>>, // (可选) 已完成任务的关键输出摘要 (commit hash)
        tasks_metadata: HashMap<String, TaskMetadata>, // (New) 任务的关键元数据
        
        /// New: Detailed state for each task including logs and content buffer
        #[serde(default)]
        task_states: HashMap<String, TaskStateSnapshot>,
        
        logs: Vec<String>, // (New) 当前Session的历史日志回放 (Global)
    }
}

#[api_dto]
pub struct WorkflowDag {
    pub nodes: Vec<TaskNode>,
    pub edges: Vec<TaskDependency> // from -> to
}

#[api_dto]
pub struct TaskDependency {
    pub from: String,
    pub to: String,
}

#[api_dto]
pub struct TaskNode {
    pub id: String,
    pub name: String,
    pub display_name: Option<String>,
    pub r#type: TaskType,
    pub initial_status: TaskStatus
}

#[api_dto]
#[derive(Copy, PartialEq)]
pub enum TaskType {
    DataFetch,      // 创造原始上下文
    DataProcessing, // 消耗并转换上下文 (New)
    Analysis        // 读取上下文生成新内容
}

#[api_dto]
#[derive(Copy, PartialEq)]
pub enum TaskStatus {
    Pending,    // 等待依赖
    Scheduled,  // 依赖满足，已下发给 Worker
    Running,    // Worker 正在执行
    Completed,  // 执行成功
    Failed,     // 执行失败
    Skipped     // 因上游失败或策略原因被跳过
}

#[api_dto]
pub struct CompanyProfilePersistedEvent {
    pub request_id: Uuid,
    pub symbol: CanonicalSymbol,
}

#[api_dto]
pub struct FinancialsPersistedEvent {
    pub request_id: Uuid,
    pub symbol: CanonicalSymbol,
    pub years_updated: Vec<u16>,
    pub template_id: Option<String>, // Pass-through for analysis trigger
    // Identity fix: Mandatory provider ID
    #[serde(default)]
    pub provider_id: Option<String>,
    // Output pass-through: Optional data preview/summary
    #[serde(default)]
    pub data_summary: Option<String>,
}

impl SubjectMessage for FinancialsPersistedEvent {
    fn subject(&self) -> NatsSubject {
        NatsSubject::DataFinancialsPersisted
    }
}

#[api_dto]
pub struct DataFetchFailedEvent {
    pub request_id: Uuid,
    pub symbol: CanonicalSymbol,
    pub error: String,
    // Identity fix: Mandatory provider ID
    #[serde(default)]
    pub provider_id: Option<String>,
}

impl SubjectMessage for DataFetchFailedEvent {
    fn subject(&self) -> NatsSubject {
        NatsSubject::DataFetchFailed
    }
}

// Topic: events.analysis.report_generated
/// Event emitted when a report generation task (or sub-module) is completed.
/// Consumed by: `workflow-orchestrator`
#[api_dto]
pub struct ReportGeneratedEvent {
    pub request_id: Uuid,
    pub symbol: CanonicalSymbol,
    pub module_id: String, // Which part of the analysis finished
    pub content_snapshot: Option<String>, // Optional short preview
    pub model_id: Option<String>,
}

impl SubjectMessage for ReportGeneratedEvent {
    fn subject(&self) -> NatsSubject {
        NatsSubject::AnalysisReportGenerated
    }
}

// Topic: events.analysis.report_failed
#[api_dto]
pub struct ReportFailedEvent {
    pub request_id: Uuid,
    pub symbol: CanonicalSymbol,
    pub module_id: String,
    pub error: String,
}

impl SubjectMessage for ReportFailedEvent {
    fn subject(&self) -> NatsSubject {
        NatsSubject::AnalysisReportFailed
    }
}
