"""
物理材质系统高级功能扩展模块
提供更复杂的物理材质功能
"""

from panda3d.core import Vec3, Vec4, Point3
import math
import time
from collections import defaultdict


class PhysicsMaterialAdvanced:
    """
    物理材质高级功能扩展类
    提供更复杂的物理材质功能
    """
    
    @staticmethod
    def calculate_thermal_effect_advanced(material, time_delta, environment_temp=20.0, heat_sources=None):
        """
        计算高级热效应
        
        Args:
            material (PhysicsMaterial): 材质对象
            time_delta (float): 时间增量
            environment_temp (float): 环境温度
            heat_sources (list): 热源列表 [{'position': Point3, 'temperature': float, 'radius': float}]
            
        Returns:
            dict: 温度变化和相关效应
        """
        current_temp = material.state['temperature']
        conductivity = material.properties['thermal_conductivity']
        specific_heat = material.properties['specific_heat']
        heat_generation = material.properties.get('heat_generation', 0.0)
        thermal_expansion = material.properties.get('thermal_expansion', 0.0)
        
        # 基础热传导计算
        temp_difference = environment_temp - current_temp
        heat_transfer = temp_difference * conductivity * time_delta
        
        # 内部热量生成
        internal_heat = heat_generation * time_delta
        
        # 外部热源影响
        external_heat = 0.0
        if heat_sources:
            for source in heat_sources:
                # 简化的热源影响计算
                source_temp = source.get('temperature', 0.0)
                source_radius = source.get('radius', 1.0)
                distance_factor = max(0.1, source_radius)  # 简化距离影响
                external_heat += (source_temp - current_temp) * 0.1 / distance_factor * time_delta
        
        # 温度变化 = (热传导 + 内部热量 + 外部热源) / (质量 * 比热容)
        # 这里假设单位质量为1kg
        temp_change = (heat_transfer + internal_heat + external_heat) / specific_heat if specific_heat > 0 else 0
        
        # 考虑相变（简化实现）
        melting_point = material.properties.get('melting_point', 1000.0)
        phase_change_effect = 1.0
        if current_temp < melting_point <= current_temp + temp_change:
            # 材质开始熔化，吸收潜热
            latent_heat = material.properties.get('latent_heat_of_fusion', 0.0)
            if latent_heat > 0:
                temp_change *= 0.1  # 熔化过程中温度变化减缓
                phase_change_effect = 0.5  # 相变期间物理属性变化
                
        # 热膨胀效应
        expansion_factor = 1.0 + thermal_expansion * temp_change
        
        return {
            'temperature_change': temp_change,
            'expansion_factor': expansion_factor,
            'phase_change_effect': phase_change_effect,
            'total_heat': heat_transfer + internal_heat + external_heat
        }
        
    @staticmethod
    def calculate_environmental_effects(material, time_delta, weather_conditions=None):
        """
        计算环境效应对材质的影响
        
        Args:
            material (PhysicsMaterial): 材质对象
            time_delta (float): 时间增量
            weather_conditions (dict): 天气条件 {'rain': float, 'wind': float, 'humidity': float, 'uv': float}
            
        Returns:
            dict: 环境效应结果
        """
        if weather_conditions is None:
            weather_conditions = {'rain': 0.0, 'wind': 0.0, 'humidity': 0.5, 'uv': 0.0}
            
        # 获取材质属性
        weather_resistance = material.properties.get('weather_resistance', 1.0)
        corrosion_rate = material.properties.get('corrosion_rate', 0.0)
        uv_resistance = material.properties.get('uv_resistance', 1.0)
        aging_rate = material.properties.get('aging_rate', 0.0)
        
        # 雨水影响
        rain_intensity = weather_conditions.get('rain', 0.0)
        wetness_increase = rain_intensity * (1.0 - weather_resistance) * time_delta
        material.update_state(wetness=min(1.0, material.state['wetness'] + wetness_increase))
        
        # 湿度影响
        humidity = weather_conditions.get('humidity', 0.5)
        humidity_effect = (humidity - 0.5) * 0.1 * time_delta
        material.update_state(humidity=max(0.0, min(100.0, material.state['humidity'] + humidity_effect)))
        
        # 腐蚀影响
        corrosion_increase = rain_intensity * corrosion_rate * (1.0 - weather_resistance) * time_delta
        material.update_state(contamination=min(1.0, material.state['contamination'] + corrosion_increase))
        
        # UV老化影响
        uv_intensity = weather_conditions.get('uv', 0.0)
        uv_damage = uv_intensity * aging_rate * (1.0 - uv_resistance) * time_delta
        material.update_state(wear=min(1.0, material.state['wear'] + uv_damage))
        
        # 风力影响（清洁效果）
        wind_speed = weather_conditions.get('wind', 0.0)
        dirt_removal = wind_speed * 0.01 * time_delta
        material.update_state(dirtiness=max(0.0, material.state['dirtiness'] - dirt_removal))
        
        return {
            'wetness_change': wetness_increase,
            'humidity_change': humidity_effect,
            'corrosion_change': corrosion_increase,
            'uv_damage': uv_damage,
            'dirt_removal': dirt_removal
        }
        
    @staticmethod
    def calculate_material_interaction(material_a, material_b, velocity, normal_force, time_delta):
        """
        计算两种材质之间的复杂交互
        
        Args:
            material_a (PhysicsMaterial): 材质A
            material_b (PhysicsMaterial): 材质B
            velocity (Vec3): 相对速度
            normal_force (float): 法向力
            time_delta (float): 时间增量
            
        Returns:
            dict: 交互结果
        """
        speed = velocity.length()
        
        # 获取交互系数
        interaction_coeff = material_a.get_interaction_coefficient(material_b.name)
        
        # 计算磨损
        wear_a = material_a.calculate_wear_rate(velocity, normal_force, time_delta)
        wear_b = material_b.calculate_wear_rate(velocity, normal_force, time_delta)
        
        # 考虑交互系数
        effective_wear_a = wear_a * interaction_coeff
        effective_wear_b = wear_b * interaction_coeff
        
        # 更新材质状态
        material_a.update_state(wear=min(1.0, material_a.state['wear'] + effective_wear_a))
        material_b.update_state(wear=min(1.0, material_b.state['wear'] + effective_wear_b))
        
        # 计算热量生成（摩擦生热）
        friction_heat = normal_force * speed * 0.1 * time_delta * interaction_coeff
        
        # 平分热量
        heat_a = friction_heat * 0.5
        heat_b = friction_heat * 0.5
        
        # 更新温度状态
        material_a.update_state(temperature=material_a.state['temperature'] + heat_a * 0.01)
        material_b.update_state(temperature=material_b.state['temperature'] + heat_b * 0.01)
        
        # 计算电荷积累
        charge_a = material_a.calculate_electrical_effect(time_delta)
        charge_b = material_b.calculate_electrical_effect(time_delta)
        
        # 摩擦电效应
        triboelectric_effect = speed * normal_force * 0.001 * time_delta
        material_a.update_state(charge=material_a.state['charge'] + triboelectric_effect)
        material_b.update_state(charge=material_b.state['charge'] - triboelectric_effect)
        
        return {
            'wear_a': effective_wear_a,
            'wear_b': effective_wear_b,
            'heat_generated': friction_heat,
            'charge_a': triboelectric_effect,
            'charge_b': -triboelectric_effect,
            'interaction_coefficient': interaction_coeff
        }
        
    @staticmethod
    def simulate_material_aging(material, time_delta, environmental_factors=None):
        """
        模拟材质老化过程
        
        Args:
            material (PhysicsMaterial): 材质对象
            time_delta (float): 时间增量
            environmental_factors (dict): 环境因素
            
        Returns:
            dict: 老化效应
        """
        if environmental_factors is None:
            environmental_factors = {}
            
        aging_rate = material.properties.get('aging_rate', 0.0)
        weather_resistance = material.properties.get('weather_resistance', 1.0)
        
        # 基础老化
        base_aging = aging_rate * time_delta
        
        # 环境加速老化
        environmental_aging = 0.0
        for factor, intensity in environmental_factors.items():
            if factor == 'temperature':
                # 高温加速老化
                if intensity > 50:  # 超过50度
                    environmental_aging += (intensity - 50) * 0.001 * time_delta
            elif factor == 'humidity':
                # 高湿度影响
                if intensity > 0.8:  # 湿度超过80%
                    environmental_aging += (intensity - 0.8) * 0.1 * time_delta
            elif factor == 'chemical_exposure':
                # 化学暴露
                environmental_aging += intensity * 0.05 * time_delta
                
        # 总老化效应
        total_aging = base_aging + environmental_aging
        
        # 应用老化效应到材质属性
        current_wear = material.state['wear']
        new_wear = min(1.0, current_wear + total_aging)
        material.update_state(wear=new_wear)
        
        # 老化对物理属性的影响
        aging_factor = new_wear  # 简化处理，磨损程度等于老化程度
        
        # 老化对摩擦系数的影响
        friction_change = aging_factor * 0.1  # 老化增加摩擦变化
        
        # 老化对弹性的影响
        restitution_degradation = aging_factor * 0.2  # 老化降低弹性
        
        return {
            'aging_amount': total_aging,
            'friction_change': friction_change,
            'restitution_degradation': restitution_degradation,
            'new_wear_level': new_wear
        }
        
    @staticmethod
    def calculate_fluid_interaction(material, fluid_properties, velocity, time_delta):
        """
        计算材质与流体的交互
        
        Args:
            material (PhysicsMaterial): 材质对象
            fluid_properties (dict): 流体属性 {'density': float, 'viscosity': float, 'temperature': float}
            velocity (Vec3): 相对速度
            time_delta (float): 时间增量
            
        Returns:
            dict: 流体交互结果
        """
        speed = velocity.length()
        fluid_density = fluid_properties.get('density', 1000.0)
        fluid_viscosity = fluid_properties.get('viscosity', 0.001)
        fluid_temp = fluid_properties.get('temperature', 20.0)
        
        # 浮力计算
        material_density = material.properties['density']
        buoyancy_force = fluid_density * 9.81 * (material_density / fluid_density)
        
        # 阻力计算
        drag_coefficient = material.properties.get('drag_coefficient', 0.5)
        drag_force = 0.5 * fluid_density * speed * speed * drag_coefficient
        
        # 粘性阻力
        viscous_drag = fluid_viscosity * speed * material.properties.get('surface_area', 1.0)
        
        # 热交换
        material_temp = material.state['temperature']
        temp_difference = fluid_temp - material_temp
        heat_transfer = temp_difference * material.properties.get('thermal_conductivity', 1.0) * time_delta
        
        # 更新材质温度
        specific_heat = material.properties.get('specific_heat', 1000.0)
        if specific_heat > 0:
            temp_change = heat_transfer / specific_heat
            material.update_state(temperature=material_temp + temp_change)
            
        # 浸湿效应
        wetness_increase = min(1.0, speed * 0.01 * time_delta)
        material.update_state(wetness=min(1.0, material.state['wetness'] + wetness_increase))
        
        return {
            'buoyancy_force': buoyancy_force,
            'drag_force': drag_force,
            'viscous_drag': viscous_drag,
            'heat_transfer': heat_transfer,
            'wetness_increase': wetness_increase
        }