use crate::event::{Event, EventHandler, EventType, EventError};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::{broadcast, RwLock};
use tokio::task::JoinHandle;
use tracing::{debug, error, info, warn};
use uuid::Uuid;

/// Premium channel-based event bus for true parallel event handling
/// 
/// This replaces the lock-based EventBus with a channel-based architecture
/// that enables:
/// - True parallel handler execution
/// - Non-blocking event publishing
/// - Built-in backpressure handling
/// - Better scalability
pub struct ConcurrentEventBus {
    /// Broadcast channel for event distribution
    event_tx: broadcast::Sender<Event>,
    
    /// Active handler tasks
    handler_tasks: Arc<RwLock<HashMap<Uuid, JoinHandle<()>>>>,
    
    /// Handlers registered for specific event types
    handlers: Arc<RwLock<HashMap<EventType, Vec<Arc<dyn EventHandler>>>>>,
    
    /// Global handlers that receive all events
    global_handlers: Arc<RwLock<Vec<Arc<dyn EventHandler>>>>,
    
    /// Event history for replay/debugging
    event_history: Arc<RwLock<Vec<Event>>>,
    
    /// Maximum history size
    max_history_size: usize,
    
    /// Channel capacity (for backpressure)
    channel_capacity: usize,
}

impl ConcurrentEventBus {
    /// Create a new concurrent event bus
    pub fn new(max_history_size: usize, channel_capacity: usize) -> Self {
        let (tx, _) = broadcast::channel(channel_capacity);
        
        Self {
            event_tx: tx,
            handler_tasks: Arc::new(RwLock::new(HashMap::new())),
            handlers: Arc::new(RwLock::new(HashMap::new())),
            global_handlers: Arc::new(RwLock::new(Vec::new())),
            event_history: Arc::new(RwLock::new(Vec::new())),
            max_history_size,
            channel_capacity,
        }
    }
    
    /// Register a handler for specific event types
    /// Each handler gets its own task that listens to the broadcast channel
    pub async fn subscribe(&self, handler: Arc<dyn EventHandler>) -> Uuid {
        let handler_id = Uuid::new_v4();
        let event_types = handler.interested_events();
        
        // Register handler in the handlers map
        {
            let mut handlers = self.handlers.write().await;
            for event_type in event_types.clone() {
                handlers
                    .entry(event_type.clone())
                    .or_insert_with(Vec::new)
                    .push(handler.clone());
            }
        }
        
        // Create a receiver for this handler
        let mut rx = self.event_tx.subscribe();
        let handler_clone = handler.clone();
        let handlers_map = self.handlers.clone();
        let event_tx_clone = self.event_tx.clone();
        
        // Spawn a task for this handler
        let task = tokio::spawn(async move {
            loop {
                match rx.recv().await {
                    Ok(event) => {
                        // Check if handler is interested in this event type
                        let should_handle = {
                            let handlers = handlers_map.read().await;
                            event_types.iter().any(|et| {
                                handlers.get(et).map_or(false, |hs| {
                                    hs.iter().any(|h| Arc::ptr_eq(h, &handler_clone))
                                })
                            })
                        };
                        
                        if should_handle {
                            match handler_clone.handle(&event).await {
                                Ok(new_events) => {
                                    // Emit new events generated by handler
                                    for new_event in new_events {
                                        if let Err(e) = event_tx_clone.send(new_event) {
                                            warn!("Failed to broadcast handler-generated event: {}", e);
                                        }
                                    }
                                }
                                Err(e) => {
                                    error!("Handler error: {}", e);
                                }
                            }
                        }
                    }
                    Err(broadcast::error::RecvError::Closed) => {
                        debug!("Event channel closed, handler task exiting");
                        break;
                    }
                    Err(broadcast::error::RecvError::Lagged(skipped)) => {
                        warn!("Handler lagged, skipped {} events", skipped);
                    }
                }
            }
        });
        
        // Store the task handle
        {
            let mut tasks = self.handler_tasks.write().await;
            tasks.insert(handler_id, task);
        }
        
        debug!("Registered concurrent handler: {}", handler_id);
        handler_id
    }
    
    /// Register a global handler that receives all events
    pub async fn subscribe_global(&self, handler: Arc<dyn EventHandler>) -> Uuid {
        let handler_id = Uuid::new_v4();
        
        // Register in global handlers
        {
            let mut global_handlers = self.global_handlers.write().await;
            global_handlers.push(handler.clone());
        }
        
        // Create a receiver for this handler
        let mut rx = self.event_tx.subscribe();
        let handler_clone = handler.clone();
        let event_tx_clone = self.event_tx.clone();
        
        // Spawn a task for this handler
        let task = tokio::spawn(async move {
            loop {
                match rx.recv().await {
                    Ok(event) => {
                        // Global handlers receive all events
                        match handler_clone.handle(&event).await {
                            Ok(new_events) => {
                                // Emit new events generated by handler
                                for new_event in new_events {
                                    if let Err(e) = event_tx_clone.send(new_event) {
                                        warn!("Failed to broadcast global handler-generated event: {}", e);
                                    }
                                }
                            }
                            Err(e) => {
                                error!("Global handler error: {}", e);
                            }
                        }
                    }
                    Err(broadcast::error::RecvError::Closed) => {
                        debug!("Event channel closed, global handler task exiting");
                        break;
                    }
                    Err(broadcast::error::RecvError::Lagged(skipped)) => {
                        warn!("Global handler lagged, skipped {} events", skipped);
                    }
                }
            }
        });
        
        // Store the task handle
        {
            let mut tasks = self.handler_tasks.write().await;
            tasks.insert(handler_id, task);
        }
        
        debug!("Registered concurrent global handler: {}", handler_id);
        handler_id
    }
    
    /// Publish an event to all interested handlers (non-blocking)
    pub async fn publish(&self, event: Event) -> Result<Vec<Event>, EventError> {
        // Store in history
        {
            let mut history = self.event_history.write().await;
            history.push(event.clone());
            
            // Trim history if needed
            if history.len() > self.max_history_size {
                history.remove(0);
            }
        }
        
        info!("Publishing event: {:?} from {} (concurrent)", event.event_type, event.source);
        
        // Broadcast event to all subscribers (non-blocking)
        match self.event_tx.send(event.clone()) {
            Ok(_) => {
                // Event was sent successfully
                // All handler tasks will process it in parallel
                Ok(Vec::new())
            }
            Err(broadcast::error::SendError(_)) => {
                // No receivers (shouldn't happen in normal operation)
                warn!("No receivers for event broadcast");
                Ok(Vec::new())
            }
        }
    }
    
    /// Get event history (for replay/debugging)
    pub async fn get_history(&self, limit: Option<usize>) -> Vec<Event> {
        let history = self.event_history.read().await;
        let limit = limit.unwrap_or(history.len());
        history.iter().rev().take(limit).cloned().collect()
    }
    
    /// Clear event history
    pub async fn clear_history(&self) {
        let mut history = self.event_history.write().await;
        history.clear();
    }
    
    /// Get count of registered handlers
    pub async fn handler_count(&self) -> usize {
        let handlers = self.handlers.read().await;
        handlers.values().map(|v| v.len()).sum::<usize>() + 
        self.global_handlers.read().await.len()
    }
    
    /// Unsubscribe a handler by ID
    pub async fn unsubscribe(&self, handler_id: Uuid) {
        let mut tasks = self.handler_tasks.write().await;
        if let Some(task) = tasks.remove(&handler_id) {
            task.abort();
            debug!("Unsubscribed handler: {}", handler_id);
        }
    }
    
    /// Shutdown the event bus and all handler tasks
    pub async fn shutdown(&self) {
        // Drop the sender to close the channel
        drop(self.event_tx.clone());
        
        // Abort all handler tasks
        let mut tasks = self.handler_tasks.write().await;
        for (id, task) in tasks.drain() {
            task.abort();
            debug!("Aborted handler task: {}", id);
        }
        
        info!("Concurrent event bus shut down");
    }
}

impl Default for ConcurrentEventBus {
    fn default() -> Self {
        Self::new(10000, 1000)
    }
}

