import sys
from pathlib import Path
import ruamel.yaml

# Add the utils directory to the Python path
utils_path = Path(__file__).parent
sys.path.append(str(utils_path))

from yaml_utils import load_unity_yaml, convert_to_plain_python_types

def build_virtual_tree(file_path, object_map, guid_map):
    """
    Parses a Unity scene/prefab's data to build a nested dictionary 
    representing the GameObject hierarchy with resolved component names and correct children.
    """
    nodes = {}
    transform_to_gameobject = {}
    child_to_parent_transform = {}

    # --- Pass 1: Create all nodes and map all relationships ---
    for file_id, obj_data in object_map.items():
        if 'GameObject' in obj_data:
            go_info = obj_data['GameObject']
            
            resolved_components = []
            for comp_ref in go_info.get('m_Component', []):
                comp_id = str(comp_ref['component']['fileID'])
                if comp_id not in object_map:
                    continue

                comp_data = object_map[comp_id]
                if 'MonoBehaviour' in comp_data:
                    script_guid = comp_data['MonoBehaviour'].get('m_Script', {}).get('guid')
                    if script_guid:
                        resolved_components.append({"script": {"guid": script_guid}})
                else:
                    comp_name = next((key for key in comp_data if key != 'm_ObjectHideFlags'), None)
                    if comp_name:
                        resolved_components.append(comp_name)

            nodes[file_id] = {
                'fileID': file_id,
                'm_Name': go_info.get('m_Name'),
                'm_IsActive': go_info.get('m_IsActive', 1),
                'm_TagString': go_info.get('m_TagString'),
                'm_Layer': go_info.get('m_Layer'),
                'm_Components': resolved_components,
                'm_Children': []
            }
        
        elif 'Transform' in obj_data:
            # Map the parent-child relationship between transforms
            father_id = str(obj_data['Transform'].get('m_Father', {}).get('fileID', '0'))
            if father_id != '0':
                child_to_parent_transform[file_id] = father_id
            
            # Map the transform back to its owning GameObject
            gameobject_id = str(obj_data['Transform'].get('m_GameObject', {}).get('fileID', '0'))
            if gameobject_id != '0':
                transform_to_gameobject[file_id] = gameobject_id

    # --- Pass 2: Build the hierarchy ---
    root_nodes = []
    for transform_id, gameobject_id in transform_to_gameobject.items():
        if gameobject_id in nodes:
            parent_transform_id = child_to_parent_transform.get(transform_id)
            if parent_transform_id and parent_transform_id in transform_to_gameobject:
                parent_gameobject_id = transform_to_gameobject[parent_transform_id]
                if parent_gameobject_id in nodes:
                    # This is a child, append it to its parent
                    nodes[parent_gameobject_id]['m_Children'].append(nodes[gameobject_id])
            else:
                # This is a root GameObject
                root_nodes.append(nodes[gameobject_id])

    return root_nodes
