"""
粒子效果系统
负责管理天气和季节的粒子效果，如雨滴、雪花、雾气等
"""

import time
import random
from typing import Dict, Any, List, Optional, Tuple
import math

class ParticleEffects:
    """
    粒子效果系统
    负责管理天气和季节的粒子效果，包括粒子生成、更新和渲染
    """
    
    def __init__(self, plugin):
        """
        初始化粒子效果系统
        
        Args:
            plugin: 天气和季节系统插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 粒子类型配置
        self.particle_types = {
            'rain_drop': {
                'name': '雨滴',
                'shape': 'line',  # 'point', 'line', 'sprite'
                'size_range': (0.1, 0.5),
                'speed_range': (10.0, 25.0),
                'lifetime_range': (0.5, 2.0),
                'color': (0.7, 0.7, 1.0, 0.8),
                'gravity': 9.8,
                'wind_influence': 0.5,
                'spawn_rate': 100,  # 每秒生成数量
                'max_particles': 2000
            },
            'snow_flake': {
                'name': '雪花',
                'shape': 'sprite',
                'size_range': (0.2, 1.0),
                'speed_range': (0.5, 3.0),
                'lifetime_range': (3.0, 8.0),
                'color': (1.0, 1.0, 1.0, 0.9),
                'gravity': 0.1,
                'wind_influence': 1.0,
                'spawn_rate': 80,
                'max_particles': 1500
            },
            'hail_stone': {
                'name': '冰雹',
                'shape': 'sprite',
                'size_range': (0.3, 1.5),
                'speed_range': (15.0, 30.0),
                'lifetime_range': (1.0, 4.0),
                'color': (0.9, 0.9, 1.0, 0.95),
                'gravity': 12.0,
                'wind_influence': 0.3,
                'spawn_rate': 50,
                'max_particles': 1000
            },
            'fog_particle': {
                'name': '雾气',
                'shape': 'sprite',
                'size_range': (5.0, 15.0),
                'speed_range': (0.1, 0.5),
                'lifetime_range': (8.0, 20.0),
                'color': (0.8, 0.8, 0.8, 0.2),
                'gravity': 0.0,
                'wind_influence': 0.8,
                'spawn_rate': 20,
                'max_particles': 500
            },
            'leaf_particle': {
                'name': '落叶',
                'shape': 'sprite',
                'size_range': (0.5, 2.0),
                'speed_range': (1.0, 5.0),
                'lifetime_range': (5.0, 15.0),
                'color': (0.6, 0.5, 0.3, 0.7),
                'gravity': 1.0,
                'wind_influence': 1.5,
                'spawn_rate': 10,
                'max_particles': 200
            },
            'dust_particle': {
                'name': '尘土',
                'shape': 'sprite',
                'size_range': (0.1, 0.8),
                'speed_range': (0.5, 3.0),
                'lifetime_range': (2.0, 8.0),
                'color': (0.8, 0.7, 0.6, 0.5),
                'gravity': 0.2,
                'wind_influence': 1.2,
                'spawn_rate': 30,
                'max_particles': 800
            }
        }
        
        # 粒子池
        self.particle_pool = []
        self.active_particles = []
        
        # 粒子发射器
        self.particle_emitters = {}
        
        # 粒子系统配置
        self.system_config = {
            'max_total_particles': 10000,
            'lod_levels': {
                'low': 0.3,
                'medium': 0.6,
                'high': 1.0
            },
            'quality_level': 'medium',
            'distance_fade': True,
            'collision_detection': False,
            'particle_lod_distance': 50.0
        }
        
        # 粒子物理配置
        self.physics_config = {
            'gravity': (0.0, -9.8, 0.0),
            'air_resistance': 0.1,
            'wind_vector': (1.0, 0.0, 0.0),
            'wind_strength': 1.0
        }
        
        # 粒子更新配置
        self.update_interval = 0.016  # 60 FPS
        self.last_update_time = 0.0
        self.accumulator = 0.0
        
        # 统计信息
        self.stats = {
            'particles_spawned': 0,
            'particles_destroyed': 0,
            'active_particles': 0,
            'emitters_active': 0,
            'total_update_time': 0.0
        }
        
        print("✓ 粒子效果系统已创建")
        
    def initialize(self) -> bool:
        """
        初始化粒子效果系统
        
        Returns:
            是否初始化成功
        """
        try:
            # 初始化粒子池
            self._initialize_particle_pool()
            
            self.initialized = True
            print("✓ 粒子效果系统初始化完成")
            return True
            
        except Exception as e:
            print(f"✗ 粒子效果系统初始化失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def enable(self) -> bool:
        """
        启用粒子效果系统
        
        Returns:
            是否启用成功
        """
        try:
            if not self.initialized:
                print("✗ 粒子效果系统未初始化")
                return False
                
            self.enabled = True
            print("✓ 粒子效果系统已启用")
            return True
            
        except Exception as e:
            print(f"✗ 粒子效果系统启用失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def disable(self):
        """禁用粒子效果系统"""
        try:
            self.enabled = False
            self._clear_all_particles()
            print("✓ 粒子效果系统已禁用")
            
        except Exception as e:
            print(f"✗ 粒子效果系统禁用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def finalize(self):
        """清理粒子效果系统资源"""
        try:
            self.disable()
            self.initialized = False
            print("✓ 粒子效果系统资源已清理")
            
        except Exception as e:
            print(f"✗ 粒子效果系统资源清理失败: {e}")
            import traceback
            traceback.print_exc()
            
    def update(self, dt: float):
        """
        更新粒子效果系统状态
        
        Args:
            dt: 时间增量
        """
        try:
            if not self.enabled:
                return
                
            # 累积时间
            self.accumulator += dt
            
            # 固定时间步长更新
            while self.accumulator >= self.update_interval:
                self._update_particles(self.update_interval)
                self._update_emitters(self.update_interval)
                self.accumulator -= self.update_interval
                
            # 更新统计信息
            self.stats['total_update_time'] += dt
            
        except Exception as e:
            print(f"✗ 粒子效果系统更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _initialize_particle_pool(self):
        """初始化粒子池"""
        try:
            pool_size = self.system_config['max_total_particles']
            
            for i in range(pool_size):
                particle = {
                    'id': i,
                    'type': None,
                    'position': [0.0, 0.0, 0.0],
                    'velocity': [0.0, 0.0, 0.0],
                    'size': 1.0,
                    'color': [1.0, 1.0, 1.0, 1.0],
                    'lifetime': 1.0,
                    'age': 0.0,
                    'active': False,
                    'gravity': 0.0,
                    'wind_influence': 0.0
                }
                self.particle_pool.append(particle)
                
            print(f"✓ 粒子池初始化完成，大小: {pool_size}")
            
        except Exception as e:
            print(f"✗ 粒子池初始化失败: {e}")
            
    def _update_particles(self, dt: float):
        """更新粒子"""
        try:
            # 获取当前风力
            wind_vector = self.physics_config['wind_vector']
            wind_strength = self.physics_config['wind_strength']
            
            # 获取重力
            gravity = self.physics_config['gravity']
            
            particles_to_remove = []
            
            for particle in self.active_particles:
                if not particle['active']:
                    continue
                    
                # 更新年龄
                particle['age'] += dt
                
                # 检查是否超出生命周期
                if particle['age'] >= particle['lifetime']:
                    particles_to_remove.append(particle)
                    continue
                    
                # 应用重力
                particle['velocity'][0] += gravity[0] * particle['gravity'] * dt
                particle['velocity'][1] += gravity[1] * particle['gravity'] * dt
                particle['velocity'][2] += gravity[2] * particle['gravity'] * dt
                
                # 应用风力影响
                wind_effect = wind_strength * particle['wind_influence']
                particle['velocity'][0] += wind_vector[0] * wind_effect * dt
                particle['velocity'][1] += wind_vector[1] * wind_effect * dt
                particle['velocity'][2] += wind_vector[2] * wind_effect * dt
                
                # 更新位置
                particle['position'][0] += particle['velocity'][0] * dt
                particle['position'][1] += particle['velocity'][1] * dt
                particle['position'][2] += particle['velocity'][2] * dt
                
                # 应用空气阻力
                air_resistance = self.physics_config['air_resistance']
                particle['velocity'][0] *= (1.0 - air_resistance * dt)
                particle['velocity'][1] *= (1.0 - air_resistance * dt)
                particle['velocity'][2] *= (1.0 - air_resistance * dt)
                
            # 移除死亡粒子
            for particle in particles_to_remove:
                self._deactivate_particle(particle)
                
        except Exception as e:
            print(f"✗ 粒子更新失败: {e}")
            
    def _update_emitters(self, dt: float):
        """更新粒子发射器"""
        try:
            # 根据当前天气激活相应的粒子发射器
            self._update_weather_emitters()
            
            # 更新所有激活的发射器
            for emitter_name, emitter in self.particle_emitters.items():
                if emitter['active']:
                    self._spawn_particles_from_emitter(emitter, dt)
                    
        except Exception as e:
            print(f"✗ 发射器更新失败: {e}")
            
    def _update_weather_emitters(self):
        """根据当前天气更新粒子发射器"""
        try:
            if not self.plugin.weather_manager:
                return
                
            current_weather = self.plugin.weather_manager.get_current_weather()
            weather_info = self.plugin.weather_manager.get_weather_info(current_weather)
            
            if not weather_info:
                return
                
            # 获取天气对应的粒子效果
            particle_effect = weather_info.get('particle_effect')
            
            # 检查是否需要激活或更新粒子发射器
            if particle_effect and particle_effect in self.particle_types:
                # 检查发射器是否已经存在
                if particle_effect not in self.particle_emitters:
                    # 创建粒子发射器
                    self._create_particle_emitter(particle_effect)
                else:
                    # 确保发射器处于激活状态
                    self.particle_emitters[particle_effect]['active'] = True
            else:
                # 停用所有天气相关的发射器
                for emitter_name in list(self.particle_emitters.keys()):
                    if emitter_name in self.particle_types:
                        self.particle_emitters[emitter_name]['active'] = False
                        
        except Exception as e:
            print(f"✗ 天气发射器更新失败: {e}")
            
    def _create_particle_emitter(self, particle_type: str):
        """
        创建粒子发射器
        
        Args:
            particle_type: 粒子类型
        """
        try:
            if particle_type not in self.particle_types:
                return
                
            emitter_config = self.particle_types[particle_type]
            
            emitter = {
                'name': particle_type,
                'type': particle_type,
                'config': emitter_config,
                'position': [0.0, 50.0, 0.0],  # 默认在空中
                'area': [100.0, 0.0, 100.0],   # 发射区域大小
                'active': True,
                'last_spawn_time': 0.0,
                'spawn_accumulator': 0.0
            }
            
            self.particle_emitters[particle_type] = emitter
            print(f"✓ 粒子发射器已创建: {emitter_config['name']}")
            
        except Exception as e:
            print(f"✗ 粒子发射器创建失败: {e}")
            
    def _spawn_particles_from_emitter(self, emitter: Dict[str, Any], dt: float):
        """
        从发射器生成粒子
        
        Args:
            emitter: 发射器数据
            dt: 时间增量
        """
        try:
            config = emitter['config']
            
            # 计算应该生成的粒子数量
            emitter['spawn_accumulator'] += dt
            spawn_interval = 1.0 / config['spawn_rate']
            
            particles_to_spawn = int(emitter['spawn_accumulator'] / spawn_interval)
            emitter['spawn_accumulator'] -= particles_to_spawn * spawn_interval
            
            # 限制生成数量不超过最大粒子数
            active_count = len([p for p in self.active_particles if p['type'] == emitter['type']])
            max_particles = config['max_particles']
            
            particles_to_spawn = min(particles_to_spawn, max_particles - active_count)
            
            # 生成粒子
            for i in range(particles_to_spawn):
                self._spawn_particle(emitter)
                
        except Exception as e:
            print(f"✗ 粒子生成失败: {e}")
            
    def _spawn_particle(self, emitter: Dict[str, Any]):
        """
        生成单个粒子
        
        Args:
            emitter: 发射器数据
        """
        try:
            # 检查是否还有可用的粒子
            available_particle = None
            for particle in self.particle_pool:
                if not particle['active']:
                    available_particle = particle
                    break
                    
            if not available_particle:
                # 粒子池已满，移除最老的粒子
                if self.active_particles:
                    oldest_particle = self.active_particles[0]
                    self._deactivate_particle(oldest_particle)
                    available_particle = oldest_particle
                else:
                    return  # 无法生成新粒子
                    
            config = emitter['config']
            
            # 初始化粒子属性
            available_particle['type'] = emitter['type']
            available_particle['active'] = True
            
            # 随机位置（在发射器区域内）
            half_area = [emitter['area'][i] / 2 for i in range(3)]
            available_particle['position'][0] = emitter['position'][0] + random.uniform(-half_area[0], half_area[0])
            available_particle['position'][1] = emitter['position'][1]  # Y轴保持不变
            available_particle['position'][2] = emitter['position'][2] + random.uniform(-half_area[2], half_area[2])
            
            # 随机速度
            speed = random.uniform(config['speed_range'][0], config['speed_range'][1])
            angle = random.uniform(0, 2 * math.pi)
            available_particle['velocity'][0] = math.cos(angle) * speed
            available_particle['velocity'][1] = -random.uniform(0.5, 1.0) * speed  # 主要向下
            available_particle['velocity'][2] = math.sin(angle) * speed
            
            # 随机大小
            available_particle['size'] = random.uniform(config['size_range'][0], config['size_range'][1])
            
            # 颜色
            available_particle['color'] = list(config['color'])
            
            # 生命周期
            available_particle['lifetime'] = random.uniform(config['lifetime_range'][0], config['lifetime_range'][1])
            available_particle['age'] = 0.0
            
            # 物理属性
            available_particle['gravity'] = config['gravity']
            available_particle['wind_influence'] = config['wind_influence']
            
            # 添加到激活列表
            if available_particle not in self.active_particles:
                self.active_particles.append(available_particle)
                
            # 更新统计信息
            self.stats['particles_spawned'] += 1
            
        except Exception as e:
            print(f"✗ 单个粒子生成失败: {e}")
            
    def _deactivate_particle(self, particle: Dict[str, Any]):
        """
        停用粒子
        
        Args:
            particle: 粒子数据
        """
        try:
            particle['active'] = False
            
            # 从激活列表中移除
            if particle in self.active_particles:
                self.active_particles.remove(particle)
                
            # 更新统计信息
            self.stats['particles_destroyed'] += 1
            
        except Exception as e:
            print(f"✗ 粒子停用失败: {e}")
            
    def _clear_all_particles(self):
        """清除所有粒子"""
        try:
            for particle in self.active_particles:
                particle['active'] = False
                
            self.active_particles.clear()
            print("✓ 所有粒子已清除")
            
        except Exception as e:
            print(f"✗ 粒子清除失败: {e}")
            
    def get_active_particles(self) -> List[Dict[str, Any]]:
        """
        获取激活的粒子列表
        
        Returns:
            激活的粒子列表
        """
        return [p for p in self.active_particles if p['active']]
        
    def get_particle_types_list(self) -> List[str]:
        """
        获取所有粒子类型列表
        
        Returns:
            粒子类型名称列表
        """
        return list(self.particle_types.keys())
        
    def get_particle_type_info(self, particle_type: str) -> Optional[Dict[str, Any]]:
        """
        获取粒子类型信息
        
        Args:
            particle_type: 粒子类型名称
            
        Returns:
            粒子类型信息字典或None
        """
        try:
            if particle_type in self.particle_types:
                return self.particle_types[particle_type].copy()
            return None
            
        except Exception as e:
            print(f"✗ 粒子类型信息获取失败: {e}")
            return None
            
    def create_custom_emitter(self, emitter_name: str, config: Dict[str, Any]):
        """
        创建自定义粒子发射器
        
        Args:
            emitter_name: 发射器名称
            config: 发射器配置
        """
        try:
            emitter = {
                'name': emitter_name,
                'type': 'custom',
                'config': config,
                'position': config.get('position', [0.0, 0.0, 0.0]),
                'area': config.get('area', [10.0, 0.0, 10.0]),
                'active': config.get('active', True),
                'last_spawn_time': 0.0,
                'spawn_accumulator': 0.0
            }
            
            self.particle_emitters[emitter_name] = emitter
            print(f"✓ 自定义粒子发射器已创建: {emitter_name}")
            
        except Exception as e:
            print(f"✗ 自定义粒子发射器创建失败: {e}")
            
    def activate_emitter(self, emitter_name: str):
        """
        激活粒子发射器
        
        Args:
            emitter_name: 发射器名称
        """
        try:
            if emitter_name in self.particle_emitters:
                self.particle_emitters[emitter_name]['active'] = True
                print(f"✓ 粒子发射器已激活: {emitter_name}")
            else:
                print(f"✗ 粒子发射器不存在: {emitter_name}")
                
        except Exception as e:
            print(f"✗ 粒子发射器激活失败: {e}")
            
    def deactivate_emitter(self, emitter_name: str):
        """
        停用粒子发射器
        
        Args:
            emitter_name: 发射器名称
        """
        try:
            if emitter_name in self.particle_emitters:
                self.particle_emitters[emitter_name]['active'] = False
                print(f"✓ 粒子发射器已停用: {emitter_name}")
            else:
                print(f"✗ 粒子发射器不存在: {emitter_name}")
                
        except Exception as e:
            print(f"✗ 粒子发射器停用失败: {e}")
            
    def set_emitter_position(self, emitter_name: str, position: Tuple[float, float, float]):
        """
        设置发射器位置
        
        Args:
            emitter_name: 发射器名称
            position: 位置坐标(x, y, z)
        """
        try:
            if emitter_name in self.particle_emitters:
                self.particle_emitters[emitter_name]['position'] = list(position)
                print(f"✓ 发射器位置已设置: {emitter_name} = {position}")
            else:
                print(f"✗ 粒子发射器不存在: {emitter_name}")
                
        except Exception as e:
            print(f"✗ 发射器位置设置失败: {e}")
            
    def set_emitter_area(self, emitter_name: str, area: Tuple[float, float, float]):
        """
        设置发射器区域大小
        
        Args:
            emitter_name: 发射器名称
            area: 区域大小(x, y, z)
        """
        try:
            if emitter_name in self.particle_emitters:
                self.particle_emitters[emitter_name]['area'] = list(area)
                print(f"✓ 发射器区域已设置: {emitter_name} = {area}")
            else:
                print(f"✗ 粒子发射器不存在: {emitter_name}")
                
        except Exception as e:
            print(f"✗ 发射器区域设置失败: {e}")
            
    def set_physics_config(self, config: Dict[str, Any]):
        """
        设置物理配置
        
        Args:
            config: 物理配置字典
        """
        self.physics_config.update(config)
        print(f"✓ 物理配置已更新: {self.physics_config}")
        
    def get_physics_config(self) -> Dict[str, Any]:
        """
        获取物理配置
        
        Returns:
            物理配置字典
        """
        return self.physics_config.copy()
        
    def set_system_config(self, config: Dict[str, Any]):
        """
        设置系统配置
        
        Args:
            config: 系统配置字典
        """
        self.system_config.update(config)
        print(f"✓ 系统配置已更新: {self.system_config}")
        
    def get_system_config(self) -> Dict[str, Any]:
        """
        获取系统配置
        
        Returns:
            系统配置字典
        """
        return self.system_config.copy()
        
    def set_update_interval(self, interval: float):
        """
        设置更新间隔
        
        Args:
            interval: 更新间隔(秒)
        """
        self.update_interval = max(0.001, min(0.1, interval))
        print(f"✓ 粒子更新间隔设置为: {interval} 秒")
        
    def get_stats(self) -> Dict[str, Any]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        self.stats['active_particles'] = len(self.active_particles)
        self.stats['emitters_active'] = len([e for e in self.particle_emitters.values() if e['active']])
        return self.stats.copy()
        
    def reset_stats(self):
        """重置统计信息"""
        self.stats = {
            'particles_spawned': 0,
            'particles_destroyed': 0,
            'active_particles': 0,
            'emitters_active': 0,
            'total_update_time': 0.0
        }
        print("✓ 粒子效果系统统计信息已重置")
        
    def is_emitter_active(self, emitter_name: str) -> bool:
        """
        检查发射器是否激活
        
        Args:
            emitter_name: 发射器名称
            
        Returns:
            发射器是否激活
        """
        if emitter_name in self.particle_emitters:
            return self.particle_emitters[emitter_name]['active']
        return False