use std::sync::Arc;
use parking_lot::RwLock;
use std::collections::HashMap;
use crate::domain::{Event, EventHandler};
use tokio::sync::mpsc;

pub struct EventBus {
    handlers: Arc<RwLock<HashMap<String, Vec<Arc<dyn EventHandler>>>>>,
    sender: mpsc::UnboundedSender<Event>,
}

impl EventBus {
    pub fn new() -> (Self, mpsc::UnboundedReceiver<Event>) {
        let (sender, receiver) = mpsc::unbounded_channel();
        let bus = Self {
            handlers: Arc::new(RwLock::new(HashMap::new())),
            sender,
        };
        (bus, receiver)
    }
    
    pub fn subscribe(&self, event_type: String, handler: Arc<dyn EventHandler>) {
        let mut handlers = self.handlers.write();
        handlers.entry(event_type).or_insert_with(Vec::new).push(handler);
    }
    
    pub fn publish(&self, event: Event) -> Result<(), String> {
        // Send to async handler
        self.sender.send(event.clone())
            .map_err(|_| "Failed to send event".to_string())?;
            
        // Also handle synchronously for immediate handlers
        let event_type = match &event.event_type {
            crate::domain::EventType::MarketData(_) => "market_data",
            crate::domain::EventType::OrderSubmitted(_) => "order_submitted",
            crate::domain::EventType::OrderFilled { .. } => "order_filled",
            crate::domain::EventType::OrderCancelled { .. } => "order_cancelled",
            crate::domain::EventType::OrderRejected { .. } => "order_rejected",
            crate::domain::EventType::PositionUpdate(_) => "position_update",
            crate::domain::EventType::RiskAlert { .. } => "risk_alert",
            crate::domain::EventType::SystemStatus { .. } => "system_status",
        };
        
        let handlers = self.handlers.read();
        if let Some(event_handlers) = handlers.get(event_type) {
            for handler in event_handlers {
                handler.handle_event(&event);
            }
        }
        
        Ok(())
    }
}

// Simple event processor that runs in the background
pub struct EventProcessor {
    receiver: mpsc::UnboundedReceiver<Event>,
    handlers: Arc<RwLock<HashMap<String, Vec<Arc<dyn EventHandler>>>>>,
}

impl EventProcessor {
    pub fn new(
        receiver: mpsc::UnboundedReceiver<Event>,
        handlers: Arc<RwLock<HashMap<String, Vec<Arc<dyn EventHandler>>>>>,
    ) -> Self {
        Self { receiver, handlers }
    }
    
    pub async fn run(mut self) {
        while let Some(event) = self.receiver.recv().await {
            // Process event asynchronously
            let event_type = match &event.event_type {
                crate::domain::EventType::MarketData(_) => "market_data",
                crate::domain::EventType::OrderSubmitted(_) => "order_submitted",
                crate::domain::EventType::OrderFilled { .. } => "order_filled",
                crate::domain::EventType::OrderCancelled { .. } => "order_cancelled",
                crate::domain::EventType::OrderRejected { .. } => "order_rejected",
                crate::domain::EventType::PositionUpdate(_) => "position_update",
                crate::domain::EventType::RiskAlert { .. } => "risk_alert",
                crate::domain::EventType::SystemStatus { .. } => "system_status",
            };
            
            let handlers = self.handlers.read();
            if let Some(event_handlers) = handlers.get(event_type) {
                for handler in event_handlers {
                    handler.handle_event(&event);
                }
            }
        }
    }
}