"""
软体物理和布料模拟插件主入口
提供完整的软体物理和布料模拟功能
"""

from panda3d.core import Vec3
from plugins.plugin_interface_spec import BasePlugin
from .core.cloth_manager import ClothManager
from .core.soft_body_manager import SoftBodyManager
from .core.cloth_physics import ClothPhysics
from .core.soft_body_physics import SoftBodyPhysics
from .materials.cloth_materials import ClothMaterialManager
from .utils.mesh_generator import MeshGenerator
from .debug.cloth_debug import PhysicsDebugManager
import json
import os


class Plugin(BasePlugin):
    """
    软体物理和布料模拟插件
    提供布料模拟和软体物理功能，支持多种材质、形状和物理效应
    """
    
    def __init__(self, plugin_manager, name: str = "soft_body_cloth_physics"):
        super().__init__(plugin_manager, name)
        
        # 核心管理器
        self.cloth_manager = None
        self.soft_body_manager = None
        self.cloth_physics = None
        self.soft_body_physics = None
        self.material_manager = None
        self.mesh_generator = None
        self.debug_manager = None
        
        # 配置
        self.config = {
            'gravity': Vec3(0, 0, -9.81),
            'time_step': 1.0/60.0,
            'sub_steps': 4,
            'default_cloth_density': 0.5,
            'default_soft_body_density': 1.0,
            'enable_debug_visualization': False,
            'debug_flags': {
                'show_mesh': True,
                'show_anchors': True,
                'show_forces': False,
                'show_velocities': False,
                'show_normals': False,
                'show_tears': True,
                'show_collisions': False,
                'show_bounding_box': False
            },
            'performance': {
                'max_cloth_objects': 50,
                'max_soft_body_objects': 50,
                'update_frequency': 60,
                'sub_steps': 4
            },
            'physics': {
                'air_density': 1.225,
                'water_density': 1000.0,
                'water_offset': 0.0,
                'water_normal': Vec3(0, 0, 1)
            },
            'wind': {
                'enabled': False,
                'velocity': Vec3(0, 0, 0),
                'turbulence': 0.0,
                'frequency': 1.0
            }
        }
        
        # 状态
        self.initialized = False
        self.performance_stats = {
            'total_cloth_objects': 0,
            'total_soft_body_objects': 0,
            'simulation_time': 0.0,
            'update_count': 0
        }
        
    def initialize(self) -> bool:
        """
        初始化插件
        
        Returns:
            是否初始化成功
        """
        try:
            print(f"正在初始化 {self.name} 插件...")
            
            # 获取世界对象
            world = self.plugin_manager.world
            
            # 初始化所有管理器
            self.cloth_manager = ClothManager(world)
            self.soft_body_manager = SoftBodyManager(world)
            self.cloth_physics = ClothPhysics(world)
            self.soft_body_physics = SoftBodyPhysics(world)
            self.material_manager = ClothMaterialManager()
            self.mesh_generator = MeshGenerator()
            self.debug_manager = PhysicsDebugManager(world.render)
            
            # 加载配置
            self._load_config()
            
            # 应用配置
            self._apply_config()
            
            # 启用调试可视化（如果配置中启用）
            if self.config['enable_debug_visualization']:
                self.debug_manager.enable()
                # 设置调试标志
                for flag, value in self.config['debug_flags'].items():
                    if flag == 'show_mesh':
                        self.debug_manager.set_cloth_visibility(mesh=value)
                        self.debug_manager.set_soft_body_visibility(mesh=value)
                    elif flag == 'show_anchors':
                        self.debug_manager.set_cloth_visibility(anchors=value)
                    elif flag == 'show_forces':
                        self.debug_manager.set_cloth_visibility(forces=value)
                        self.debug_manager.set_soft_body_visibility(forces=value)
                    elif flag == 'show_velocities':
                        self.debug_manager.set_cloth_visibility(velocities=value)
                        self.debug_manager.set_soft_body_visibility(velocities=value)
                    elif flag == 'show_normals':
                        self.debug_manager.set_cloth_visibility(normals=value)
                    elif flag == 'show_tears':
                        self.debug_manager.set_cloth_visibility(tears=value)
                    elif flag == 'show_collisions':
                        self.debug_manager.set_cloth_visibility(collisions=value)
                        self.debug_manager.set_soft_body_visibility(collisions=value)
                    elif flag == 'show_bounding_box':
                        self.debug_manager.set_cloth_visibility(bounding_box=value)
                        
            # 设置性能参数
            self.cloth_manager.max_cloth_objects = self.config['performance']['max_cloth_objects']
            self.cloth_manager.cloth_update_frequency = self.config['performance']['update_frequency']
            self.soft_body_manager.max_soft_body_objects = self.config['performance']['max_soft_body_objects']
            self.soft_body_manager.soft_body_update_frequency = self.config['performance']['update_frequency']
            
            # 设置风力参数
            self._apply_wind_config()
            
            self.initialized = True
            print(f"✓ {self.name} 插件初始化成功")
            return True
            
        except Exception as e:
            print(f"✗ {self.name} 插件初始化失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def enable(self) -> bool:
        """
        启用插件
        
        Returns:
            是否启用成功
        """
        try:
            if not self.initialized:
                print("⚠ 插件未初始化，无法启用")
                return False
                
            # 启用所有管理器
            if self.cloth_manager:
                self.cloth_manager.enable()
            if self.soft_body_manager:
                self.soft_body_manager.enable()
            if self.cloth_physics:
                # 无需特殊启用
                pass
            if self.soft_body_physics:
                # 无需特殊启用
                pass
            if self.debug_manager:
                self.debug_manager.enable()
                
            self.enabled = True
            print(f"✓ {self.name} 插件已启用")
            return True
            
        except Exception as e:
            print(f"✗ {self.name} 插件启用失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def disable(self) -> bool:
        """
        禁用插件
        
        Returns:
            是否禁用成功
        """
        try:
            # 禁用所有管理器
            if self.cloth_manager:
                self.cloth_manager.disable()
            if self.soft_body_manager:
                self.soft_body_manager.disable()
            if self.debug_manager:
                self.debug_manager.disable()
                
            self.enabled = False
            print(f"✓ {self.name} 插件已禁用")
            return True
            
        except Exception as e:
            print(f"✗ {self.name} 插件禁用失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def finalize(self):
        """
        清理插件资源
        """
        try:
            # 清理所有管理器
            if self.cloth_manager:
                self.cloth_manager.cleanup()
                self.cloth_manager = None
            if self.soft_body_manager:
                self.soft_body_manager.cleanup()
                self.soft_body_manager = None
            if self.cloth_physics:
                self.cloth_physics = None
            if self.soft_body_physics:
                self.soft_body_physics = None
            if self.material_manager:
                self.material_manager = None
            if self.mesh_generator:
                self.mesh_generator = None
            if self.debug_manager:
                self.debug_manager.cleanup()
                self.debug_manager = None
                
            print(f"✓ {self.name} 插件资源已清理")
            
        except Exception as e:
            print(f"✗ {self.name} 插件清理失败: {e}")
            import traceback
            traceback.print_exc()
            
    def get_info(self):
        """
        获取插件信息
        
        Returns:
            插件信息字典
        """
        info = super().get_info()
        info.update({
            "name": "SoftBodyClothPhysics",
            "version": "1.0.0",
            "author": "iFlow Team",
            "description": "提供软体物理和布料模拟功能的插件",
            "features": [
                "布料物理模拟",
                "软体物理模拟", 
                "多种布料材质类型",
                "参数实时调节",
                "调试可视化",
                "风力模拟",
                "撕裂和碰撞检测",
                "高级网格生成"
            ],
            "dependencies": [
                "panda3d",
                "panda3d.bullet"
            ],
            "capabilities": {
                "cloth_types": self.material_manager.get_all_material_types() if self.material_manager else [],
                "mesh_generation": [
                    "cloth_patch",
                    "sphere",
                    "box",
                    "capsule",
                    "cylinder",
                    "rope",
                    "torus",
                    "custom"
                ],
                "debug_visualization": [
                    "mesh",
                    "anchors",
                    "forces",
                    "velocities",
                    "normals",
                    "tears",
                    "collisions",
                    "bounding_box"
                ]
            }
        })
        return info
        
    def update(self, dt: float):
        """
        更新插件（每帧调用）
        
        Args:
            dt: 时间增量
        """
        if not self.enabled or not self.initialized:
            return
            
        # 更新所有管理器
        if self.cloth_manager:
            self.cloth_manager.update_all_cloths(dt)
        if self.soft_body_manager:
            self.soft_body_manager.update_all_soft_bodies(dt)
        if self.cloth_physics:
            self.cloth_physics.update_wind(dt)
        if self.debug_manager:
            # 更新可视化
            if self.cloth_manager:
                self.debug_manager.update_all_visualizations(
                    self.cloth_manager.cloth_objects,
                    self.soft_body_manager.soft_body_objects if self.soft_body_manager else []
                )
                
        # 更新性能统计
        self.performance_stats['update_count'] += 1
        if self.cloth_manager:
            self.performance_stats['total_cloth_objects'] = len(self.cloth_manager.cloth_objects)
        if self.soft_body_manager:
            self.performance_stats['total_soft_body_objects'] = len(self.soft_body_manager.soft_body_objects)
            
    def get_performance_stats(self) -> dict:
        """
        获取性能统计信息
        
        Returns:
            性能统计信息字典
        """
        stats = self.performance_stats.copy()
        
        # 添加管理器统计
        if self.cloth_manager:
            cloth_stats = self.cloth_manager.get_cloth_stats()
            stats.update(cloth_stats)
            
        if self.soft_body_manager:
            soft_stats = self.soft_body_manager.get_soft_body_stats()
            stats.update(soft_stats)
            
        if self.debug_manager:
            debug_stats = self.debug_manager.get_debug_stats()
            stats['debug_stats'] = debug_stats
            
        return stats
        
    def create_cloth(self, parent_node, cloth_type: str, 
                    width: float, height: float,
                    resolution_x: int, resolution_y: int,
                    params: dict = None,
                    behavior_mode: str = None) -> dict:
        """
        创建布料对象
        
        Args:
            parent_node: 父节点
            cloth_type: 布料类型
            width: 宽度
            height: 高度
            resolution_x: X分辨率
            resolution_y: Y分辨率
            params: 参数
            behavior_mode: 行为模式
            
        Returns:
            布料对象信息
        """
        if not self.initialized or not self.cloth_manager:
            return None
            
        return self.cloth_manager.create_cloth_patch(
            parent_node, width, height, resolution_x, resolution_y, params
        )
        
    def create_soft_body(self, parent_node, soft_type: str,
                        shape_type: str = "sphere",
                        **kwargs) -> dict:
        """
        创建软体对象
        
        Args:
            parent_node: 父节点
            soft_type: 软体类型
            shape_type: 形状类型
            **kwargs: 形状参数
            
        Returns:
            软体对象信息
        """
        if not self.initialized or not self.soft_body_manager:
            return None
            
        return self.soft_body_manager.create_soft_body_from_mesh(
            parent_node, soft_type, shape_type, **kwargs
        )
        
    def set_config(self, key: str, value):
        """
        设置配置参数
        
        Args:
            key: 配置键
            value: 配置值
        """
        if key in self.config:
            self.config[key] = value
            if key == 'gravity':
                self._apply_config()
            elif key == 'enable_debug_visualization':
                if value and self.debug_manager:
                    self.debug_manager.enable()
                elif not value and self.debug_manager:
                    self.debug_manager.disable()
                    
    def get_config(self, key: str = None):
        """
        获取配置参数
        
        Args:
            key: 配置键（如果为None则返回整个配置）
            
        Returns:
            配置值或整个配置字典
        """
        if key:
            return self.config.get(key)
        return self.config.copy()
        
    def _load_config(self):
        """
        从配置文件加载配置
        """
        try:
            config_path = os.path.join(
                os.path.dirname(__file__), 
                "config", 
                "cloth_settings.json"
            )
            
            if os.path.exists(config_path):
                with open(config_path, 'r', encoding='utf-8') as f:
                    file_config = json.load(f)
                    
                # 合并配置
                self._merge_config(self.config, file_config.get('plugin', {}))
                
        except Exception as e:
            print(f"⚠ 加载配置文件失败: {e}")
            
    def _merge_config(self, target: dict, source: dict):
        """
        合并配置字典
        
        Args:
            target: 目标字典
            source: 源字典
        """
        for key, value in source.items():
            if isinstance(value, dict) and key in target and isinstance(target[key], dict):
                self._merge_config(target[key], value)
            else:
                target[key] = value
                
    def _apply_config(self):
        """
        应用配置设置
        """
        if self.cloth_manager:
            self.cloth_manager.set_gravity(self.config['gravity'])
        if self.soft_body_manager:
            self.soft_body_manager.set_gravity(self.config['gravity'])
        if self.cloth_physics:
            self.cloth_physics.update_soft_body_world_info(
                air_density=self.config['physics']['air_density'],
                water_density=self.config['physics']['water_density'],
                water_offset=self.config['physics']['water_offset'],
                water_normal=self.config['physics']['water_normal'],
                gravity=self.config['gravity']
            )
        if self.soft_body_physics:
            self.soft_body_physics.update_soft_body_world_info(
                air_density=self.config['physics']['air_density'],
                water_density=self.config['physics']['water_density'],
                water_offset=self.config['physics']['water_offset'],
                water_normal=self.config['physics']['water_normal'],
                gravity=self.config['gravity']
            )
            
    def _apply_wind_config(self):
        """
        应用风力配置
        """
        if self.cloth_physics and self.config['wind']['enabled']:
            self.cloth_physics.set_wind_parameters(
                enabled=self.config['wind']['enabled'],
                velocity=self.config['wind']['velocity'],
                turbulence=self.config['wind']['turbulence'],
                frequency=self.config['wind']['frequency']
            )