use std::sync::Arc;
use crate::config::AppConfig;
use anyhow::Result;
use common_contracts::persistence_client::PersistenceClient;
use dashmap::DashMap;
use uuid::Uuid;
use tokio::sync::Mutex;
// use crate::workflow::WorkflowStateMachine; // Deprecated
use crate::dag_scheduler::DagScheduler;
use workflow_context::Vgcs;
use crate::logging::{LogBufferManager, LogEntry};
use tokio::sync::broadcast;

pub struct AppState {
    #[allow(dead_code)]
    pub config: AppConfig,
    #[allow(dead_code)]
    pub persistence_client: PersistenceClient,
    
    // Key: request_id
    // We use Mutex here because state transitions need to be atomic per workflow
    pub workflows: Arc<DashMap<Uuid, Arc<Mutex<DagScheduler>>>>,
    
    pub vgcs: Arc<Vgcs>,

    pub log_manager: Arc<LogBufferManager>,
    pub log_broadcast_tx: broadcast::Sender<LogEntry>,
}

impl AppState {
    pub async fn new(config: AppConfig, log_manager: Arc<LogBufferManager>, log_broadcast_tx: broadcast::Sender<LogEntry>) -> Result<Self> {
        let persistence_client = PersistenceClient::new(config.data_persistence_service_url.clone());
        let vgcs = Arc::new(Vgcs::new(&config.workflow_data_path));
        
        Ok(Self {
            config,
            persistence_client,
            workflows: Arc::new(DashMap::new()),
            vgcs,
            log_manager,
            log_broadcast_tx,
        })
    }
}
