/*! 🔗 SimpleIntentBox - P2P通信Box
 * 
 * ## 📝 概要  
 * ピア・ツー・ピア通信機能を提供する軽量実装Box。
 * ノード間のメッセージ配信、イベント通知、
 * 分散アプリケーション構築に使用。
 * 
 * ## 🛠️ 利用可能メソッド
 * - `send(target, message)` - メッセージ送信
 * - `on(event, callback)` - イベントリスナー登録
 * - `emit(event, data)` - イベント発火
 * - `connect(nodeId)` - ノード接続
 * - `disconnect(nodeId)` - ノード切断
 * - `getConnectedNodes()` - 接続中ノード一覧
 * - `setNodeId(id)` - 自ノードID設定
 * - `broadcast(message)` - 全ノードにブロードキャスト
 * 
 * ## 💡 使用例
 * ```nyash
 * local intent
 * intent = new SimpleIntentBox()
 * 
 * // ノード設定
 * intent.setNodeId("node1")
 * 
 * // リスナー登録
 * intent.on("message", "handleMessage")
 * intent.on("join", "handleNodeJoin")
 * 
 * // メッセージ送信
 * intent.send("node2", "Hello from node1!")
 * 
 * // ブロードキャスト
 * intent.broadcast("System announcement")
 * ```
 * 
 * ## 🎮 実用例 - チャットアプリ
 * ```nyash
 * static box ChatNode {
 *     init { intent, username, messages }
 *     
 *     main() {
 *         me.intent = new SimpleIntentBox()
 *         me.username = "User1"
 *         me.messages = []
 *         
 *         // ノード初期化
 *         me.intent.setNodeId(me.username)
 *         me.setupEventHandlers()
 *         
 *         // チャットルームに参加
 *         me.joinChatRoom()
 *     }
 *     
 *     setupEventHandlers() {
 *         // メッセージ受信
 *         me.intent.on("chat_message", "onChatMessage")
 *         // ユーザー参加
 *         me.intent.on("user_joined", "onUserJoined")
 *         // ユーザー退出
 *         me.intent.on("user_left", "onUserLeft")
 *     }
 *     
 *     sendMessage(text) {
 *         local msg
 *         msg = new MapBox()
 *         msg.set("from", me.username)
 *         msg.set("text", text)
 *         msg.set("timestamp", new TimeBox().now())
 *         
 *         me.intent.broadcast("chat_message", msg)
 *     }
 *     
 *     onChatMessage(sender, message) {
 *         me.messages.push(message)
 *         print("[" + message.get("from") + "] " + message.get("text"))
 *     }
 * }
 * ```
 * 
 * ## 🌐 分散計算例
 * ```nyash
 * static box DistributedWorker {
 *     init { intent, node_id, tasks }
 *     
 *     main() {
 *         me.intent = new SimpleIntentBox()
 *         me.node_id = "worker_" + RandomBox.randInt(1000, 9999)
 *         me.tasks = []
 *         
 *         me.intent.setNodeId(me.node_id)
 *         me.registerAsWorker()
 *     }
 *     
 *     registerAsWorker() {
 *         // タスク受信リスナー
 *         me.intent.on("task_assign", "processTask")
 *         // 結果送信完了リスナー
 *         me.intent.on("result_received", "onResultReceived")
 *         
 *         // ワーカー登録通知
 *         me.intent.broadcast("worker_ready", me.node_id)
 *     }
 *     
 *     processTask(coordinator, task) {
 *         print("Processing task: " + task.get("id"))
 *         
 *         // 重い計算処理...
 *         local result
 *         result = heavyCalculation(task.get("data"))
 *         
 *         // 結果を送信
 *         me.intent.send(coordinator, result)
 *     }
 * }
 * ```
 * 
 * ## 🎯 ゲーム用マルチプレイヤー
 * ```nyash
 * static box GameClient {
 *     init { intent, player_id, game_state }
 *     
 *     main() {
 *         me.intent = new SimpleIntentBox()
 *         me.player_id = "player_" + me.generateId()
 *         me.game_state = new MapBox()
 *         
 *         me.connectToGame()
 *     }
 *     
 *     connectToGame() {
 *         me.intent.setNodeId(me.player_id)
 *         
 *         // ゲームイベント
 *         me.intent.on("player_move", "onPlayerMove")
 *         me.intent.on("game_update", "onGameUpdate")
 *         me.intent.on("player_joined", "onPlayerJoined")
 *         
 *         // ゲーム参加
 *         me.intent.broadcast("join_game", me.player_id)
 *     }
 *     
 *     movePlayer(x, y) {
 *         local move_data
 *         move_data = new MapBox()
 *         move_data.set("player", me.player_id)
 *         move_data.set("x", x)
 *         move_data.set("y", y)
 *         
 *         me.intent.broadcast("player_move", move_data)
 *     }
 * }
 * ```
 * 
 * ## ⚠️ 注意
 * - 現在は最小限実装（フル機能開発中）
 * - ネットワーク通信は未実装（ローカル通信のみ）
 * - メッセージ配信は同一プロセス内限定
 * - 本格P2P実装は将来バージョンで提供予定
 */

use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase};
use std::any::Any;
use std::sync::RwLock;
use std::collections::HashMap;

#[derive(Debug)]
pub struct SimpleIntentBox {
    base: BoxBase,
    // ノードID -> コールバック関数のマップ
    listeners: RwLock<HashMap<String, Vec<String>>>, // 仮実装
}

impl Clone for SimpleIntentBox {
    fn clone(&self) -> Self {
        let listeners_val = self.listeners.read().unwrap().clone();
        
        Self {
            base: BoxBase::new(), // New unique ID for clone
            listeners: RwLock::new(listeners_val),
        }
    }
}

impl SimpleIntentBox {
    pub fn new() -> Self {
        SimpleIntentBox {
            base: BoxBase::new(),
            listeners: RwLock::new(HashMap::new()),
        }
    }
}

impl BoxCore for SimpleIntentBox {
    fn box_id(&self) -> u64 {
        self.base.id
    }
    
    fn parent_type_id(&self) -> Option<std::any::TypeId> {
        self.base.parent_type_id
    }
    
    fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "SimpleIntentBox(id: {}))", self.base.id)
    }
    
    fn as_any(&self) -> &dyn Any {
        self
    }
    
    fn as_any_mut(&mut self) -> &mut dyn Any {
        self
    }
}

impl NyashBox for SimpleIntentBox {
    fn to_string_box(&self) -> StringBox {
        StringBox::new("IntentBox")
    }
    
    fn equals(&self, other: &dyn NyashBox) -> BoolBox {
        if let Some(other_intent) = other.as_any().downcast_ref::<SimpleIntentBox>() {
            BoolBox::new(self.base.id == other_intent.base.id)
        } else {
            BoolBox::new(false)
        }
    }
    
    fn type_name(&self) -> &'static str {
        "IntentBox"
    }
    
    fn clone_box(&self) -> Box<dyn NyashBox> {
        Box::new(self.clone())
    }
    
    /// 仮実装: clone_boxと同じ（後で修正）
    fn share_box(&self) -> Box<dyn NyashBox> {
        self.clone_box()
    }
    
}

impl std::fmt::Display for SimpleIntentBox {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        self.fmt_box(f)
    }
}