"""
波浪系统模块
负责生成和管理各种类型的波浪效果
"""

import time
from typing import Dict, Any, List, Optional
import math
import numpy as np

class WaveSystem:
    """
    波浪系统
    负责生成和管理各种类型的波浪效果，包括风浪、涌浪、涟漪等
    """
    
    def __init__(self, plugin):
        """
        初始化波浪系统
        
        Args:
            plugin: 水体和流体模拟插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 波浪类型定义
        self.wave_types = {
            'wind_wave': {
                'name': '风浪',
                'description': '由风力产生的波浪',
                'frequency_range': (0.1, 1.0),  # Hz
                'amplitude_range': (0.01, 2.0),  # 米
                'speed_range': (1.0, 10.0),     # m/s
                'typical_wavelength': 10.0      # 米
            },
            'swell_wave': {
                'name': '涌浪',
                'description': '远处风暴产生的长周期波浪',
                'frequency_range': (0.05, 0.2),
                'amplitude_range': (0.5, 5.0),
                'speed_range': (5.0, 20.0),
                'typical_wavelength': 100.0
            },
            'ripple': {
                'name': '涟漪',
                'description': '小尺度的表面波纹',
                'frequency_range': (1.0, 10.0),
                'amplitude_range': (0.001, 0.05),
                'speed_range': (0.1, 1.0),
                'typical_wavelength': 0.1
            },
            'tsunami': {
                'name': '海啸',
                'description': '由地震或海底滑坡产生的巨大波浪',
                'frequency_range': (0.001, 0.01),
                'amplitude_range': (1.0, 50.0),
                'speed_range': (50.0, 200.0),
                'typical_wavelength': 100000.0
            },
            'ship_wave': {
                'name': '船行波',
                'description': '船舶运动产生的波浪',
                'frequency_range': (0.1, 2.0),
                'amplitude_range': (0.1, 1.0),
                'speed_range': (0.5, 5.0),
                'typical_wavelength': 5.0
            }
        }
        
        # 活跃波浪列表
        self.active_waves = []
        self.wave_counter = 0
        
        # 波浪谱配置
        self.wave_spectrum = {
            'type': 'pierson_moskowitz',  # 'pierson_moskowitz', 'jonswap', 'custom'
            'wind_speed': 10.0,            # m/s
            'fetch': 10000.0,              # 风区长度(米)
            'duration': 3600.0,            # 风持续时间(秒)
            'peak_frequency': 0.2,         # Hz
            'significant_wave_height': 1.0  # 有效波高(米)
        }
        
        # 动态波浪配置
        self.dynamic_config = {
            'max_waves': 32,
            'update_frequency': 60.0,      # Hz
            'last_update_time': 0.0,
            'time_scale': 1.0
        }
        
        # 环境影响因子
        self.environment_factors = {
            'wind_speed': 5.0,             # m/s
            'wind_direction': 0.0,         # 弧度
            'water_depth': 10.0,           # 米
            'current_velocity': (0.0, 0.0),  # (vx, vz) m/s
            'temperature': 20.0,           # °C
            'salinity': 35.0               # ppt
        }
        
        # 波浪统计
        self.wave_stats = {
            'total_waves': 0,
            'active_waves': 0,
            'total_energy': 0.0,
            'peak_wave_height': 0.0,
            'average_wave_period': 0.0
        }
        
        # 交互效果
        self.interaction_effects = {
            'splash_damping': 0.9,         # 溅起波浪的阻尼系数
            'wave_interference': True,     # 是否启用波浪干涉
            'nonlinear_effects': True,     # 是否启用非线性效应
            'breaking_waves': True         # 是否启用碎浪效果
        }
        
        print("✓ 波浪系统已创建")
        
    def initialize(self) -> bool:
        """
        初始化波浪系统
        
        Returns:
            是否初始化成功
        """
        try:
            # 创建一些初始波浪
            self._create_initial_waves()
            
            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
            print("✓ 波浪系统已禁用")
            
        except Exception as e:
            print(f"✗ 波浪系统禁用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def finalize(self):
        """清理波浪系统资源"""
        try:
            self.disable()
            self.active_waves.clear()
            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.dynamic_config['last_update_time'] += dt * self.dynamic_config['time_scale']
            
            # 更新活跃波浪
            self._update_active_waves(dt)
            
            # 根据环境条件生成新波浪
            self._generate_environment_waves(dt)
            
            # 更新统计信息
            self._update_wave_statistics()
            
        except Exception as e:
            print(f"✗ 波浪系统更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _create_initial_waves(self):
        """创建初始波浪"""
        try:
            # 创建几个默认波浪
            for i in range(3):
                wave_params = {
                    'type': 'wind_wave',
                    'amplitude': 0.5 + i * 0.2,
                    'wavelength': 10.0 + i * 5.0,
                    'speed': 2.0 + i * 0.5,
                    'direction': i * math.pi / 3,
                    'frequency': 0.3 + i * 0.1,
                    'phase': 0.0,
                    'damping': 0.01,
                    'lifetime': float('inf'),
                    'position': (0.0, 0.0)
                }
                
                self._add_wave(wave_params)
                
            print("✓ 初始波浪创建完成")
            
        except Exception as e:
            print(f"✗ 初始波浪创建失败: {e}")
            
    def _update_active_waves(self, dt: float):
        """
        更新活跃波浪
        
        Args:
            dt: 时间增量
        """
        try:
            time_value = self.dynamic_config['last_update_time']
            
            # 更新每个波浪
            waves_to_remove = []
            for wave in self.active_waves:
                # 更新相位
                wave['phase'] += wave['frequency'] * 2 * math.pi * dt
                
                # 应用阻尼
                wave['amplitude'] *= (1.0 - wave['damping'] * dt)
                
                # 检查生命周期
                if wave['lifetime'] != float('inf'):
                    wave['lifetime'] -= dt
                    if wave['lifetime'] <= 0:
                        waves_to_remove.append(wave)
                        
                # 更新位置（考虑水流速度）
                current_vx, current_vz = self.environment_factors['current_velocity']
                wave['position'] = (
                    wave['position'][0] + current_vx * dt,
                    wave['position'][1] + current_vz * dt
                )
                
            # 移除过期波浪
            for wave in waves_to_remove:
                self.active_waves.remove(wave)
                
        except Exception as e:
            print(f"✗ 活跃波浪更新失败: {e}")
            
    def _generate_environment_waves(self, dt: float):
        """
        根据环境条件生成波浪
        
        Args:
            dt: 时间增量
        """
        try:
            # 基于风速生成波浪
            wind_speed = self.environment_factors['wind_speed']
            wind_direction = self.environment_factors['wind_direction']
            
            # 简化的波浪生成逻辑
            # 实际实现中会使用更复杂的波浪谱模型
            wave_generation_probability = min(1.0, wind_speed / 20.0) * dt
            
            if np.random.random() < wave_generation_probability and len(self.active_waves) < self.dynamic_config['max_waves']:
                # 生成新波浪
                wave_type = 'wind_wave'
                wave_info = self.wave_types[wave_type]
                
                # 根据风速确定波浪参数
                amplitude = np.random.uniform(0.1, wind_speed / 5.0)
                wavelength = np.random.uniform(5.0, max(5.0, wind_speed * 2.0))
                speed = min(wind_speed, math.sqrt(9.81 * wavelength / (2 * math.pi)))  # 深水波速
                direction = wind_direction + np.random.uniform(-0.2, 0.2)  # 小角度偏移
                
                wave_params = {
                    'type': wave_type,
                    'amplitude': amplitude,
                    'wavelength': wavelength,
                    'speed': speed,
                    'direction': direction,
                    'frequency': speed / wavelength,
                    'phase': np.random.uniform(0, 2 * math.pi),
                    'damping': np.random.uniform(0.001, 0.01),
                    'lifetime': np.random.uniform(10.0, 60.0),
                    'position': (0.0, 0.0)
                }
                
                self._add_wave(wave_params)
                
        except Exception as e:
            print(f"✗ 环境波浪生成失败: {e}")
            
    def _add_wave(self, wave_params: Dict[str, Any]) -> int:
        """
        添加波浪
        
        Args:
            wave_params: 波浪参数
            
        Returns:
            波浪ID
        """
        try:
            wave_id = self.wave_counter
            self.wave_counter += 1
            
            wave_params['id'] = wave_id
            wave_params['creation_time'] = self.dynamic_config['last_update_time']
            
            self.active_waves.append(wave_params)
            
            return wave_id
            
        except Exception as e:
            print(f"✗ 波浪添加失败: {e}")
            return -1
            
    def _update_wave_statistics(self):
        """更新波浪统计信息"""
        try:
            total_energy = 0.0
            peak_height = 0.0
            total_period = 0.0
            
            for wave in self.active_waves:
                # 波浪能量 (简化的计算)
                energy = 0.5 * 1000.0 * 9.81 * wave['amplitude'] ** 2
                total_energy += energy
                
                # 峰值波高
                peak_height = max(peak_height, wave['amplitude'] * 2)  # 波峰到波谷
                
                # 平均周期
                if wave['frequency'] > 0:
                    total_period += 1.0 / wave['frequency']
                    
            self.wave_stats['total_waves'] = self.wave_counter
            self.wave_stats['active_waves'] = len(self.active_waves)
            self.wave_stats['total_energy'] = total_energy
            self.wave_stats['peak_wave_height'] = peak_height
            
            if len(self.active_waves) > 0:
                self.wave_stats['average_wave_period'] = total_period / len(self.active_waves)
            else:
                self.wave_stats['average_wave_period'] = 0.0
                
        except Exception as e:
            print(f"✗ 波浪统计更新失败: {e}")
            
    def create_wave(self, wave_type: str, parameters: Dict[str, Any]) -> int:
        """
        创建指定类型的波浪
        
        Args:
            wave_type: 波浪类型
            parameters: 波浪参数
            
        Returns:
            波浪ID
        """
        try:
            if wave_type not in self.wave_types:
                print(f"✗ 无效的波浪类型: {wave_type}")
                return -1
                
            # 获取波浪类型信息
            wave_info = self.wave_types[wave_type]
            
            # 默认参数
            default_params = {
                'type': wave_type,
                'amplitude': np.random.uniform(*wave_info['amplitude_range']),
                'wavelength': wave_info['typical_wavelength'],
                'speed': np.random.uniform(*wave_info['speed_range']),
                'direction': np.random.uniform(0, 2 * math.pi),
                'frequency': 0.0,
                'phase': 0.0,
                'damping': 0.01,
                'lifetime': float('inf'),
                'position': (0.0, 0.0)
            }
            
            # 更新默认参数
            default_params.update(parameters)
            
            # 计算频率（如果未提供）
            if default_params['frequency'] <= 0:
                if default_params['wavelength'] > 0:
                    default_params['frequency'] = default_params['speed'] / default_params['wavelength']
                else:
                    default_params['frequency'] = 0.1
                    
            # 添加波浪
            wave_id = self._add_wave(default_params)
            
            if wave_id >= 0:
                print(f"✓ {wave_info['name']} 已创建 (ID: {wave_id})")
                
            return wave_id
            
        except Exception as e:
            print(f"✗ 波浪创建失败: {e}")
            return -1
            
    def remove_wave(self, wave_id: int) -> bool:
        """
        移除波浪
        
        Args:
            wave_id: 波浪ID
            
        Returns:
            是否移除成功
        """
        try:
            for wave in self.active_waves:
                if wave['id'] == wave_id:
                    self.active_waves.remove(wave)
                    print(f"✓ 波浪已移除 (ID: {wave_id})")
                    return True
                    
            print(f"✗ 波浪不存在 (ID: {wave_id})")
            return False
            
        except Exception as e:
            print(f"✗ 波浪移除失败: {e}")
            return False
            
    def get_wave(self, wave_id: int) -> Optional[Dict[str, Any]]:
        """
        获取波浪信息
        
        Args:
            wave_id: 波浪ID
            
        Returns:
            波浪信息或None
        """
        try:
            for wave in self.active_waves:
                if wave['id'] == wave_id:
                    return wave.copy()
            return None
            
        except Exception as e:
            print(f"✗ 波浪信息获取失败: {e}")
            return None
            
    def get_all_waves(self) -> List[Dict[str, Any]]:
        """
        获取所有活跃波浪
        
        Returns:
            波浪列表
        """
        return [wave.copy() for wave in self.active_waves]
        
    def calculate_wave_height_at(self, x: float, z: float, time_value: float = None) -> float:
        """
        计算指定位置和时间的波浪高度
        
        Args:
            x, z: 位置坐标
            time_value: 时间值（如果为None则使用当前时间）
            
        Returns:
            波浪高度
        """
        try:
            if time_value is None:
                time_value = self.dynamic_config['last_update_time']
                
            total_height = 0.0
            
            # 计算每个波浪在该点的贡献
            for wave in self.active_waves:
                # 计算相对于波浪位置的距离
                dx = x - wave['position'][0]
                dz = z - wave['position'][1]
                
                # 计算在波浪传播方向上的投影距离
                direction = wave['direction']
                projection = dx * math.cos(direction) + dz * math.sin(direction)
                
                # 计算相位
                phase = wave['phase'] + 2 * math.pi * projection / wave['wavelength']
                
                # 计算波浪高度（正弦波）
                height = wave['amplitude'] * math.sin(phase)
                
                # 如果启用波浪干涉，直接叠加
                if self.interaction_effects['wave_interference']:
                    total_height += height
                else:
                    # 否则取最大值
                    total_height = max(total_height, height)
                    
            return total_height
            
        except Exception as e:
            print(f"✗ 波浪高度计算失败: {e}")
            return 0.0
            
    def calculate_wave_velocity_at(self, x: float, z: float, time_value: float = None) -> tuple:
        """
        计算指定位置和时间的波浪速度
        
        Args:
            x, z: 位置坐标
            time_value: 时间值（如果为None则使用当前时间）
            
        Returns:
            波浪速度 (vx, vz)
        """
        try:
            if time_value is None:
                time_value = self.dynamic_config['last_update_time']
                
            total_vx = 0.0
            total_vz = 0.0
            
            # 计算每个波浪在该点的速度贡献
            for wave in self.active_waves:
                # 计算相对于波浪位置的距离
                dx = x - wave['position'][0]
                dz = z - wave['position'][1]
                
                # 计算在波浪传播方向上的投影距离
                direction = wave['direction']
                projection = dx * math.cos(direction) + dz * math.sin(direction)
                
                # 计算相位
                phase = wave['phase'] + 2 * math.pi * projection / wave['wavelength']
                
                # 计算速度分量
                speed = wave['speed']
                vx = speed * math.cos(direction)
                vz = speed * math.sin(direction)
                
                # 考虑波浪振幅的影响
                velocity_factor = wave['amplitude'] * math.cos(phase)
                total_vx += vx * velocity_factor
                total_vz += vz * velocity_factor
                
            return (total_vx, total_vz)
            
        except Exception as e:
            print(f"✗ 波浪速度计算失败: {e}")
            return (0.0, 0.0)
            
    def generate_wave_spectrum(self) -> Dict[str, List[float]]:
        """
        生成波浪谱
        
        Returns:
            包含频率和能量密度的字典
        """
        try:
            spectrum_type = self.wave_spectrum['type']
            wind_speed = self.wave_spectrum['wind_speed']
            
            # 频率范围
            freq_min, freq_max = 0.01, 2.0
            num_points = 100
            frequencies = np.linspace(freq_min, freq_max, num_points)
            energy_densities = np.zeros(num_points)
            
            if spectrum_type == 'pierson_moskowitz':
                # Pierson-Moskowitz谱
                alpha = 8.1e-3
                beta = 0.74
                g = 9.81
                
                for i, f in enumerate(frequencies):
                    if f > 0:
                        omega = 2 * math.pi * f
                        energy_densities[i] = alpha * g**2 / omega**5 * math.exp(-beta * (g / (omega * wind_speed))**4)
                        
            elif spectrum_type == 'jonswap':
                # JONSWAP谱
                alpha = 0.076 * (wind_speed**2 / (g * 100))**0.22  # 简化计算
                beta = 0.74
                gamma = 3.3  # 峰值增强因子
                sigma = 0.07  # 谱宽参数
                
                fp = self.wave_spectrum['peak_frequency']
                omega_p = 2 * math.pi * fp
                
                for i, f in enumerate(frequencies):
                    if f > 0:
                        omega = 2 * math.pi * f
                        ratio = omega / omega_p
                        
                        # 谱宽参数
                        if ratio <= 1:
                            sigma_val = 0.07
                        else:
                            sigma_val = 0.09
                            
                        # 峰值增强函数
                        gamma_val = gamma ** math.exp(-0.5 * ((ratio - 1) / sigma_val)**2)
                        
                        energy_densities[i] = alpha * g**2 / omega**5 * math.exp(-beta * (g / (omega * wind_speed))**4) * gamma_val
                        
            return {
                'frequencies': frequencies.tolist(),
                'energy_densities': energy_densities.tolist()
            }
            
        except Exception as e:
            print(f"✗ 波浪谱生成失败: {e}")
            return {
                'frequencies': [],
                'energy_densities': []
            }
            
    def create_splash_wave(self, position: tuple, energy: float) -> List[int]:
        """
        创建溅起波浪效果
        
        Args:
            position: 溅起位置 (x, z)
            energy: 溅起能量
            
        Returns:
            创建的波浪ID列表
        """
        try:
            created_waves = []
            
            # 创建多个同心圆波浪来模拟溅起效果
            num_ripples = min(5, int(energy / 0.1))
            
            for i in range(num_ripples):
                amplitude = energy * 0.1 * (1.0 - i * 0.15)
                wavelength = 0.5 + i * 0.3
                speed = 1.0 + i * 0.5
                lifetime = 2.0 + i * 0.5
                
                wave_params = {
                    'type': 'ripple',
                    'amplitude': amplitude,
                    'wavelength': wavelength,
                    'speed': speed,
                    'direction': 0.0,  # 径向波
                    'frequency': speed / wavelength,
                    'phase': 0.0,
                    'damping': 0.5,
                    'lifetime': lifetime,
                    'position': position
                }
                
                wave_id = self._add_wave(wave_params)
                if wave_id >= 0:
                    created_waves.append(wave_id)
                    
            if created_waves:
                print(f"✓ 溅起波浪已创建 ({len(created_waves)} 个波浪)")
                
            return created_waves
            
        except Exception as e:
            print(f"✗ 溅起波浪创建失败: {e}")
            return []
            
    def update_environment_factors(self, factors: Dict[str, Any]):
        """
        更新环境因子
        
        Args:
            factors: 环境因子字典
        """
        try:
            self.environment_factors.update(factors)
            print(f"✓ 环境因子已更新: {factors}")
        except Exception as e:
            print(f"✗ 环境因子更新失败: {e}")
            
    def get_environment_factors(self) -> Dict[str, Any]:
        """
        获取环境因子
        
        Returns:
            环境因子字典
        """
        return self.environment_factors.copy()
        
    def set_wave_spectrum(self, spectrum: Dict[str, Any]):
        """
        设置波浪谱参数
        
        Args:
            spectrum: 波浪谱参数字典
        """
        try:
            self.wave_spectrum.update(spectrum)
            print(f"✓ 波浪谱参数已更新: {self.wave_spectrum}")
        except Exception as e:
            print(f"✗ 波浪谱参数设置失败: {e}")
            
    def get_wave_spectrum(self) -> Dict[str, Any]:
        """
        获取波浪谱参数
        
        Returns:
            波浪谱参数字典
        """
        return self.wave_spectrum.copy()
        
    def set_dynamic_config(self, config: Dict[str, Any]):
        """
        设置动态配置
        
        Args:
            config: 动态配置字典
        """
        try:
            self.dynamic_config.update(config)
            print(f"✓ 动态配置已更新: {self.dynamic_config}")
        except Exception as e:
            print(f"✗ 动态配置设置失败: {e}")
            
    def get_dynamic_config(self) -> Dict[str, Any]:
        """
        获取动态配置
        
        Returns:
            动态配置字典
        """
        return self.dynamic_config.copy()
        
    def get_wave_statistics(self) -> Dict[str, Any]:
        """
        获取波浪统计信息
        
        Returns:
            波浪统计字典
        """
        return self.wave_stats.copy()
        
    def reset_wave_statistics(self):
        """重置波浪统计信息"""
        try:
            self.wave_stats = {
                'total_waves': self.wave_counter,
                'active_waves': len(self.active_waves),
                'total_energy': 0.0,
                'peak_wave_height': 0.0,
                'average_wave_period': 0.0
            }
            print("✓ 波浪统计信息已重置")
        except Exception as e:
            print(f"✗ 波浪统计信息重置失败: {e}")
            
    def get_wave_types(self) -> List[str]:
        """
        获取所有波浪类型
        
        Returns:
            波浪类型列表
        """
        return list(self.wave_types.keys())
        
    def get_wave_type_info(self, wave_type: str) -> Optional[Dict[str, Any]]:
        """
        获取波浪类型信息
        
        Args:
            wave_type: 波浪类型
            
        Returns:
            波浪类型信息或None
        """
        return self.wave_types.get(wave_type)