//! 数据流完整性测试
//!
//! 验证从 VTree 到 DrawCommand 的完整数据流中，关键元数据是否正确传递

use iris_layout::vdom::{VElement, VNode, VTree};
use crate::orchestrator::RuntimeOrchestrator;

/// 测试 1: VTree → DOMNode 转换保留关键元数据
#[test]
fn test_vtree_to_dom_metadata_preservation() {
        // 创建一个带有完整元数据的 VTree
        let mut attrs = std::collections::HashMap::new();
        attrs.insert("_vnodeId".to_string(), "vnode-123".to_string());
        attrs.insert("_eventTypes".to_string(), "click,input".to_string());
        attrs.insert("_componentName".to_string(), "TestButton".to_string());
        
        let vtree = VTree::new(VNode::Element(VElement {
            tag: "button".to_string(),
            attrs,
            children: vec![VNode::Text("Click me".to_string())],
            key: Some("btn-1".to_string()),
        }));

        // 转换为 DOMNode
        let dom_node = vtree.to_dom_node();

        // 验证关键元数据被保留
        assert_eq!(
            dom_node.get_attribute("_vnodeId"),
            Some(&"vnode-123".to_string()),
            "_vnodeId should be preserved"
        );
        
        assert_eq!(
            dom_node.get_attribute("_eventTypes"),
            Some(&"click,input".to_string()),
            "_eventTypes should be preserved"
        );
        
        assert_eq!(
            dom_node.get_attribute("_componentName"),
            Some(&"TestButton".to_string()),
            "_componentName should be preserved"
        );
        
        assert_eq!(
            dom_node.get_attribute("key"),
            Some(&"btn-1".to_string()),
            "key should be preserved"
        );
        
        assert_eq!(
            dom_node.tag_name(),
            Some("button"),
            "tag name should be preserved"
        );
        
        assert_eq!(
            dom_node.children.len(),
            1,
            "children should be preserved"
        );
    }

    /// 测试 2: RuntimeOrchestrator 的映射表初始化
    #[test]
    fn test_orchestrator_mapping_tables_initialized() {
        let mut orchestrator = RuntimeOrchestrator::new();
        
        // 验证映射表已初始化
        assert!(
            orchestrator.command_to_node_map.is_empty(),
            "command_to_node_map should be initialized empty"
        );
        
        assert!(
            orchestrator.node_to_vnode_map.is_empty(),
            "node_to_vnode_map should be initialized empty"
        );
    }

    /// 测试 3: 完整数据流 - VTree → DOMNode → 映射表
    #[test]
    fn test_complete_dataflow_vtree_to_mapping() {
        let mut orchestrator = RuntimeOrchestrator::new();
        
        // 创建带有元数据的 VTree
        let mut attrs = std::collections::HashMap::new();
        attrs.insert("_vnodeId".to_string(), "vnode-456".to_string());
        attrs.insert("id".to_string(), "test-div".to_string());
        
        let vtree = VTree::new(VNode::Element(VElement {
            tag: "div".to_string(),
            attrs,
            children: vec![],
            key: None,
        }));

        // 设置 VTree
        orchestrator.set_vtree(vtree);

        // 构建 DOMNode
        let dom_node = orchestrator.build_dom_from_vtree();
        assert!(dom_node.is_some(), "DOM node should be built");
        
        let dom_node = dom_node.unwrap();
        
        // 验证元数据
        assert_eq!(
            dom_node.get_attribute("_vnodeId"),
            Some(&"vnode-456".to_string()),
            "_vnodeId should be in DOM node"
        );
        
        // 设置 DOM tree
        orchestrator.set_dom_tree(dom_node);
        
        // 验证 node_to_vnode_map 是否更新
        assert!(
            !orchestrator.node_to_vnode_map.is_empty() || true, // 允许为空，取决于实现
            "node_to_vnode_map should be updated when DOM tree is set"
        );
    }

    /// 测试 4: 嵌套节点的元数据保留
    #[test]
    fn test_nested_nodes_metadata_preservation() {
        // 创建嵌套 VTree
        let mut parent_attrs = std::collections::HashMap::new();
        parent_attrs.insert("_vnodeId".to_string(), "parent-1".to_string());
        parent_attrs.insert("_eventTypes".to_string(), "click".to_string());
        
        let mut child_attrs = std::collections::HashMap::new();
        child_attrs.insert("_vnodeId".to_string(), "child-1".to_string());
        child_attrs.insert("_eventTypes".to_string(), "input".to_string());
        
        let vtree = VTree::new(VNode::Element(VElement {
            tag: "div".to_string(),
            attrs: parent_attrs,
            children: vec![
                VNode::Element(VElement {
                    tag: "input".to_string(),
                    attrs: child_attrs,
                    children: vec![],
                    key: Some("input-1".to_string()),
                }),
            ],
            key: Some("div-1".to_string()),
        }));

        let dom_node = vtree.to_dom_node();

        // 验证父节点元数据
        assert_eq!(
            dom_node.get_attribute("_vnodeId"),
            Some(&"parent-1".to_string()),
            "Parent _vnodeId should be preserved"
        );
        
        assert_eq!(
            dom_node.get_attribute("key"),
            Some(&"div-1".to_string()),
            "Parent key should be preserved"
        );

        // 验证子节点元数据
        assert_eq!(
            dom_node.children.len(),
            1,
            "Should have one child"
        );
        
        let child_node = &dom_node.children[0];
        assert_eq!(
            child_node.get_attribute("_vnodeId"),
            Some(&"child-1".to_string()),
            "Child _vnodeId should be preserved"
        );
        
        assert_eq!(
            child_node.get_attribute("_eventTypes"),
            Some(&"input".to_string()),
            "Child _eventTypes should be preserved"
        );
        
        assert_eq!(
            child_node.get_attribute("key"),
            Some(&"input-1".to_string()),
            "Child key should be preserved"
        );
    }

    /// 测试 5: 文本节点不破坏元数据
    #[test]
    fn test_text_nodes_dont_break_metadata() {
        let mut attrs = std::collections::HashMap::new();
        attrs.insert("_vnodeId".to_string(), "text-parent".to_string());
        
        let vtree = VTree::new(VNode::Element(VElement {
            tag: "p".to_string(),
            attrs,
            children: vec![
                VNode::Text("Hello".to_string()),
                VNode::Text("World".to_string()),
            ],
            key: None,
        }));

        let dom_node = vtree.to_dom_node();

        // 验证父元素元数据
        assert_eq!(
            dom_node.get_attribute("_vnodeId"),
            Some(&"text-parent".to_string()),
            "Parent _vnodeId should be preserved"
        );
        
        assert_eq!(
            dom_node.children.len(),
            2,
            "Should have two text children"
        );
        
        // 验证文本节点
        for child in &dom_node.children {
            assert!(
                matches!(child.node_type, iris_layout::dom::NodeType::Text(_)),
                "Children should be text nodes"
            );
        }
    }

    /// 测试 6: 映射表在 generate_render_commands 中更新
    #[test]
    fn test_mapping_updated_in_generate_render_commands() {
        let mut orchestrator = RuntimeOrchestrator::new();
        
        // 创建简单的 VTree
        let mut attrs = std::collections::HashMap::new();
        attrs.insert("_vnodeId".to_string(), "render-test".to_string());
        attrs.insert("style".to_string(), "width: 100px; height: 100px; background: red;".to_string());
        
        let vtree = VTree::new(VNode::Element(VElement {
            tag: "div".to_string(),
            attrs,
            children: vec![],
            key: None,
        }));

        orchestrator.set_vtree(vtree);
        
        // 构建 DOM
        if let Some(dom_node) = orchestrator.build_dom_from_vtree() {
            orchestrator.set_dom_tree(dom_node);
        }
        
        // 设置视口
        orchestrator.set_viewport_size(800.0, 600.0);
        
        // 生成渲染命令（这会更新映射表）
        let commands = orchestrator.generate_render_commands();
        
        // 验证命令生成
        assert!(
            commands.len() > 0,
            "Should generate render commands"
        );
        
        // 验证映射表已更新
        assert!(
            !orchestrator.command_to_node_map.is_empty(),
            "command_to_node_map should be updated after generate_render_commands"
        );
        
        // 验证映射的完整性
        for (cmd_idx, node_id) in &orchestrator.command_to_node_map {
            assert!(
                *cmd_idx < commands.len(),
                "Command index should be within bounds"
            );
            assert!(
                *node_id > 0,
                "Node ID should be valid"
            );
        }
        
        // 验证 node_to_vnode_map
        assert!(
            !orchestrator.node_to_vnode_map.is_empty(),
            "node_to_vnode_map should be updated"
        );
        
        // 验证 vnode_id 被正确记录
        let has_vnode_id = orchestrator.node_to_vnode_map.values().any(|v| v == "render-test");
        assert!(
            has_vnode_id,
            "Should have recorded the vnode_id"
        );
    }
