//! NATS→WebSocket bridge for real-time task status updates.
//!
//! Subscribes to `provisioning.tasks.*.status` via JetStream durable consumer
//! and re-broadcasts each event to all connected WebSocket clients, eliminating
//! polling between control-center and orchestrator.

use std::sync::Arc;

use futures::StreamExt;
use platform_nats::NatsBridge;
use serde::{Deserialize, Serialize};
use tracing::{error, info, warn};
use uuid::Uuid;

use crate::handlers::websocket::{WebSocketEvent, WebSocketManager};

const STREAM_NAME: &str = "TASKS";
const CONSUMER_NAME: &str = "cc-task-status-bridge";

#[derive(Debug, Clone, Serialize, Deserialize)]
struct TaskStatusPayload {
    pub task_id: String,
    pub status: String,
    pub progress: Option<u32>,
    pub message: Option<String>,
}

/// Spawn the NATS→WebSocket bridge as a background tokio task.
pub fn spawn_nats_bridge(nats: Arc<NatsBridge>, ws_manager: Arc<WebSocketManager>) {
    tokio::spawn(async move {
        run_bridge(nats, ws_manager).await;
    });
}

async fn run_bridge(nats: Arc<NatsBridge>, ws_manager: Arc<WebSocketManager>) {
    let mut messages = match nats.subscribe_pull(STREAM_NAME, CONSUMER_NAME).await {
        Ok(m) => m,
        Err(e) => {
            error!("NATS bridge: subscribe failed — {e}");
            return;
        }
    };

    info!("NATS→WebSocket bridge running on stream {STREAM_NAME}");

    while let Some(msg_result) = messages.next().await {
        match msg_result {
            Ok(msg) => {
                match serde_json::from_slice::<TaskStatusPayload>(&msg.payload) {
                    Ok(payload) => {
                        let event = WebSocketEvent {
                            event_type: "task_status_update".to_string(),
                            data: serde_json::json!({
                                "task_id": payload.task_id,
                                "status": payload.status,
                                "progress": payload.progress,
                                "message": payload.message,
                            }),
                            timestamp: chrono::Utc::now(),
                            target_user: None,
                        };
                        ws_manager.broadcast_event(event).await;
                    }
                    Err(e) => {
                        warn!("NATS bridge: deserialize failed — {e}");
                    }
                }
                if let Err(e) = msg.ack().await {
                    warn!("NATS bridge: ack failed — {e}");
                }
            }
            Err(e) => {
                error!("NATS bridge: message error — {e}");
            }
        }
    }
}
