//! [TSM.ID].[11031972] — Platform X Ecosystem
//! Bridge router for message routing between native and webview

use crate::{BridgeMessage, BridgeError, Result, Platform};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

pub type BridgeCallback = Box<dyn Fn(&BridgeMessage) -> Result<String> + Send + Sync>;

pub struct BridgeRouter {
    routes: Arc<Mutex<HashMap<String, Vec<BridgeCallback>>>>,
    platform: Platform,
    message_log: Arc<Mutex<Vec<BridgeMessage>>>,
    max_log_size: usize,
}

impl BridgeRouter {
    pub fn new(platform: Platform, max_log_size: usize) -> Self {
        Self {
            routes: Arc::new(Mutex::new(HashMap::new())),
            platform,
            message_log: Arc::new(Mutex::new(Vec::new())),
            max_log_size,
        }
    }

    pub fn register(&self, target: &str, callback: BridgeCallback) -> Result<()> {
        let mut routes = self.routes.lock().map_err(|e| BridgeError::SerializationFailed(e.to_string()))?;
        routes.entry(target.to_string()).or_default().push(callback);
        Ok(())
    }

    pub fn route(&self, msg: &BridgeMessage) -> Result<Vec<String>> {
        let routes = self.routes.lock().map_err(|e| BridgeError::SerializationFailed(e.to_string()))?;
        let callbacks = routes.get(&msg.target).ok_or_else(|| BridgeError::InvalidTarget(msg.target.clone()))?;
        let mut results = Vec::new();
        for cb in callbacks {
            results.push(cb(msg)?);
        }
        let mut log = self.message_log.lock().map_err(|e| BridgeError::SerializationFailed(e.to_string()))?;
        if log.len() < self.max_log_size {
            log.push(msg.clone());
        }
        Ok(results)
    }

    pub fn platform(&self) -> &Platform { &self.platform }

    pub fn log_count(&self) -> usize {
        self.message_log.lock().map(|l| l.len()).unwrap_or(0)
    }
}
