use std::sync::Arc;

use common_contracts::messages::GenerateReportCommand;
use futures::StreamExt;
use tracing::{error, info};

use crate::{state::AppState, worker::run_report_generation_workflow};

const SUBJECT_NAME: &str = "analysis.commands.generate_report";

pub async fn subscribe_to_commands(
    app_state: AppState,
    nats_client: async_nats::Client,
) -> Result<(), anyhow::Error> {
    let mut subscriber = nats_client.subscribe(SUBJECT_NAME.to_string()).await?;
    info!(
        "Consumer started, waiting for commands on subject '{}'",
        SUBJECT_NAME
    );

    while let Some(message) = subscriber.next().await {
        info!("Received NATS command for report generation. Payload size: {} bytes", message.payload.len());
        let state_clone = app_state.clone();
        tokio::spawn(async move {
            match serde_json::from_slice::<GenerateReportCommand>(&message.payload) {
                Ok(command) => {
                    info!(
                        "Command triggered analysis for symbol: {}, template: {}, request_id: {}",
                        command.symbol, command.template_id, command.request_id
                    );
                    if let Err(e) = run_report_generation_workflow(Arc::new(state_clone), command).await
                    {
                        error!("Error running report generation workflow: {:?}", e);
                    }
                }
                Err(e) => {
                    error!("Failed to deserialize GenerateReportCommand: {}. Payload: {:?}", e, message.payload);
                }
            }
        });
    }

    Ok(())
}
