"""
刚体动力学插件主管理器
整合所有物理功能模块，提供统一的接口
"""

from panda3d.core import Vec3, Point3
from .core.physics_world import PhysicsWorld
from .core.rigid_body import RigidBody
from .core.material import PhysicsMaterial, MATERIALS
from .constraints.constraint_manager import ConstraintManager
from .vehicles.vehicle_system import VehicleSystem
from .particles.particle_system import ParticleSystem
from .debug.debug_tools import PhysicsDebug, PhysicsProfiler
from .utils.physics_utils import PhysicsUtils, PhysicsConfigManager, PhysicsCollisionGroups


class RigidBodyPhysicsPlugin:
    """
    刚体动力学插件主管理器
    提供统一的物理系统接口
    """
    
    def __init__(self, world_node=None, config_file=None):
        """
        初始化物理插件
        
        Args:
            world_node: Panda3D世界节点（用于调试可视化）
            config_file (str): 配置文件路径
        """
        # 创建物理世界
        self.physics_world = PhysicsWorld()
        
        # 创建约束管理器
        self.constraint_manager = ConstraintManager()
        
        # 配置管理器
        self.config_manager = PhysicsConfigManager(config_file)
        
        # 调试工具
        self.debug_tools = None
        self.profiler = None
        if world_node:
            self.debug_tools = PhysicsDebug(self.physics_world, world_node)
            self.profiler = PhysicsProfiler(self.physics_world)
            
        # 活动对象列表
        self.vehicles = []
        self.particle_systems = []
        
        print("刚体动力学插件初始化完成")
        
    def create_rigid_body(self, node_path, shape_type='box', mass=1.0, 
                         body_type=RigidBody.DYNAMIC, material=None):
        """
        创建刚体
        
        Args:
            node_path: Panda3D节点路径
            shape_type (str): 碰撞形状类型
            mass (float): 质量
            body_type (int): 刚体类型
            material (PhysicsMaterial): 物理材质
            
        Returns:
            RigidBody: 刚体对象
        """
        # 创建刚体
        rigid_body = RigidBody(node_path, shape_type, mass, body_type)
        
        # 应用材质
        if material:
            material.apply_to_rigid_body(rigid_body)
        else:
            # 使用默认材质
            default_material = PhysicsMaterial('default')
            default_material.apply_to_rigid_body(rigid_body)
            
        # 添加到物理世界
        self.physics_world.add_rigid_body(rigid_body)
        
        return rigid_body
        
    def create_constraint(self, constraint_type, body_a, body_b, **kwargs):
        """
        创建约束
        
        Args:
            constraint_type (str): 约束类型
            body_a (RigidBody): 第一个刚体
            body_b (RigidBody): 第二个刚体
            **kwargs: 约束参数
            
        Returns:
            约束对象
        """
        if constraint_type == ConstraintManager.CONSTRAINT_POINT2POINT:
            constraint = self.constraint_manager.create_point2point_constraint(
                body_a, body_b, **kwargs)
        elif constraint_type == ConstraintManager.CONSTRAINT_HINGE:
            constraint = self.constraint_manager.create_hinge_constraint(
                body_a, body_b, **kwargs)
        elif constraint_type == ConstraintManager.CONSTRAINT_SLIDER:
            constraint = self.constraint_manager.create_slider_constraint(
                body_a, body_b, **kwargs)
        elif constraint_type == ConstraintManager.CONSTRAINT_CONETWIST:
            constraint = self.constraint_manager.create_cone_twist_constraint(
                body_a, body_b, **kwargs)
        elif constraint_type == ConstraintManager.CONSTRAINT_6DOF:
            constraint = self.constraint_manager.create_6dof_constraint(
                body_a, body_b, **kwargs)
        else:
            raise ValueError(f"未知的约束类型: {constraint_type}")
            
        # 添加到物理世界
        self.physics_world.add_constraint(constraint)
        
        return constraint
        
    def create_vehicle(self, chassis_body, wheel_configurations):
        """
        创建车辆
        
        Args:
            chassis_body (RigidBody): 底盘刚体
            wheel_configurations (list): 车轮配置列表
            
        Returns:
            VehicleSystem: 车辆系统对象
        """
        # 创建车辆系统
        vehicle = VehicleSystem(self.physics_world, chassis_body)
        
        # 添加车轮
        for wheel_config in wheel_configurations:
            vehicle.add_wheel(**wheel_config)
            
        # 保存车辆引用
        self.vehicles.append(vehicle)
        
        return vehicle
        
    def create_particle_system(self, max_particles=1000):
        """
        创建粒子系统
        
        Args:
            max_particles (int): 最大粒子数
            
        Returns:
            ParticleSystem: 粒子系统对象
        """
        # 创建粒子系统
        particle_system = ParticleSystem(self.physics_world, max_particles)
        
        # 保存粒子系统引用
        self.particle_systems.append(particle_system)
        
        # 添加到物理世界
        self.physics_world.add_particle_system(particle_system)
        
        return particle_system
        
    def update(self, dt):
        """
        更新物理系统
        
        Args:
            dt (float): 时间增量
        """
        # 更新物理世界
        self.physics_world.update(dt)
        
        # 更新粒子系统
        for particle_system in self.particle_systems:
            particle_system.update(dt)
            
        # 更新调试工具
        if self.debug_tools:
            self.debug_tools.update_debug_visualization()
            
        # 更新性能分析器
        if self.profiler:
            self.profiler.record_frame()
            
    def ray_test(self, from_pos, to_pos):
        """
        射线检测
        
        Args:
            from_pos (Point3): 起点
            to_pos (Point3): 终点
            
        Returns:
            BulletRayHit: 射线检测结果
        """
        return self.physics_world.ray_test(from_pos, to_pos)
        
    def get_performance_stats(self):
        """
        获取性能统计
        
        Returns:
            dict: 性能统计信息
        """
        stats = self.physics_world.get_performance_stats()
        
        # 添加对象计数
        stats['objects'] = {
            'rigid_bodies': len(self.physics_world.rigid_bodies),
            'constraints': len(self.physics_world.constraints),
            'vehicles': len(self.vehicles),
            'particle_systems': len(self.particle_systems)
        }
        
        return stats
        
    def enable_debug_visualization(self, enabled=True):
        """
        启用调试可视化
        
        Args:
            enabled (bool): 是否启用
        """
        if self.debug_tools:
            self.debug_tools.enable_debug(enabled)
            
    def set_debug_options(self, **kwargs):
        """
        设置调试选项
        
        Args:
            **kwargs: 调试选项
        """
        if self.debug_tools:
            self.debug_tools.set_debug_options(**kwargs)
            
    def get_predefined_material(self, material_name):
        """
        获取预定义材质
        
        Args:
            material_name (str): 材质名称
            
        Returns:
            PhysicsMaterial: 物理材质
        """
        return MATERIALS.get(material_name)
        
    def create_custom_material(self, name, properties):
        """
        创建自定义材质
        
        Args:
            name (str): 材质名称
            properties (dict): 材质属性
            
        Returns:
            PhysicsMaterial: 物理材质
        """
        return PhysicsMaterial(name, properties)
        
    def set_gravity(self, gravity):
        """
        设置重力
        
        Args:
            gravity (Vec3): 重力向量
        """
        self.physics_world.set_gravity(gravity)
        
    def set_time_step(self, time_step, max_substeps=10):
        """
        设置时间步长
        
        Args:
            time_step (float): 时间步长
            max_substeps (int): 最大子步数
        """
        self.physics_world.set_time_step(time_step, max_substeps)
        
    def get_collision_groups(self):
        """
        获取碰撞组工具
        
        Returns:
            PhysicsCollisionGroups: 碰撞组工具
        """
        return PhysicsCollisionGroups
        
    def save_config(self, config_file=None):
        """
        保存配置
        
        Args:
            config_file (str): 配置文件路径
        """
        if self.config_manager:
            self.config_manager.save_config(config_file)
            
    def load_config(self, config_file):
        """
        加载配置
        
        Args:
            config_file (str): 配置文件路径
        """
        if self.config_manager:
            self.config_manager.load_config(config_file)
            
    def clear_all(self):
        """
        清除所有物理对象
        """
        # 销毁所有车辆
        for vehicle in self.vehicles[:]:
            vehicle.destroy()
        self.vehicles.clear()
        
        # 销毁所有粒子系统
        for particle_system in self.particle_systems[:]:
            particle_system.destroy()
        self.particle_systems.clear()
        
        # 清除物理世界
        self.physics_world.clear()
        
        print("所有物理对象已清除")
        
    def destroy(self):
        """
        销毁物理插件
        """
        # 清除所有对象
        self.clear_all()
        
        # 销毁调试工具
        if self.debug_tools:
            self.debug_tools.destroy()
            
        # 销毁性能分析器
        if self.profiler:
            self.profiler.destroy()
            
        # 销毁物理世界
        del self.physics_world
        
        print("刚体动力学插件已销毁")