use std::sync::Arc;
use async_nats::Client;
use anyhow::Result;
use tracing::{info, error};
use futures::StreamExt;
use crate::state::AppState;
use common_contracts::messages::{StartWorkflowCommand, SyncStateCommand};
use common_contracts::workflow_types::WorkflowTaskEvent;
use common_contracts::subjects::NatsSubject;
use crate::workflow::WorkflowEngine;

pub async fn run(state: Arc<AppState>, nats: Client) -> Result<()> {
    info!("Message Consumer started. Subscribing to topics...");

    // Topic 1: Workflow Commands (Start)
    // Note: NatsSubject::WorkflowCommandStart string representation is "workflow.commands.start"
    let mut start_sub = nats.subscribe(NatsSubject::WorkflowCommandStart.to_string()).await?;
    
    // Topic 1b: Workflow Commands (Sync State)
    let mut sync_sub = nats.subscribe(NatsSubject::WorkflowCommandSyncState.to_string()).await?;

    // Topic 2: Workflow Task Events (Generic)
    // Note: NatsSubject::WorkflowEventTaskCompleted string representation is "workflow.evt.task_completed"
    let mut task_sub = nats.subscribe(NatsSubject::WorkflowEventTaskCompleted.to_string()).await?;

    let engine = Arc::new(WorkflowEngine::new(state.clone(), nats.clone()));

    // --- Task 1: Start Workflow ---
    let engine1 = engine.clone();
    tokio::spawn(async move {
        while let Some(msg) = start_sub.next().await {
            if let Ok(cmd) = serde_json::from_slice::<StartWorkflowCommand>(&msg.payload) {
                info!("Received StartWorkflow: {:?}", cmd);
                if let Err(e) = engine1.handle_start_workflow(cmd).await {
                    error!("Failed to handle StartWorkflow: {}", e);
                }
            } else {
                error!("Failed to parse StartWorkflowCommand");
            }
        }
    });

    // --- Task 1b: Sync State ---
    let engine_sync = engine.clone();
    tokio::spawn(async move {
        while let Some(msg) = sync_sub.next().await {
            if let Ok(cmd) = serde_json::from_slice::<SyncStateCommand>(&msg.payload) {
                info!("Received SyncStateCommand: request_id={}", cmd.request_id);
                if let Err(e) = engine_sync.handle_sync_state(cmd).await {
                    error!("Failed to handle SyncStateCommand: {}", e);
                }
            } else {
                error!("Failed to parse SyncStateCommand");
            }
        }
    });

    // --- Task 2: Task Completed Events ---
    let engine2 = engine.clone();
    tokio::spawn(async move {
        while let Some(msg) = task_sub.next().await {
            if let Ok(evt) = serde_json::from_slice::<WorkflowTaskEvent>(&msg.payload) {
                info!("Received TaskCompleted: task_id={}", evt.task_id);
                if let Err(e) = engine2.handle_task_completed(evt).await {
                    error!("Failed to handle TaskCompleted: {}", e);
                }
            } else {
                error!("Failed to parse WorkflowTaskEvent");
            }
        }
    });

    Ok(())
}
