"""
侵蚀处理器
负责模拟地形的侵蚀过程
"""

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

class ErosionProcessor:
    """
    侵蚀处理器
    负责模拟地形的侵蚀过程，包括水力侵蚀、热力侵蚀、风力侵蚀等
    """
    
    def __init__(self, plugin):
        """
        初始化侵蚀处理器
        
        Args:
            plugin: 程序化地形生成插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 侵蚀配置
        self.seed = plugin.config.get('seed', 12345)
        
        # 侵蚀参数
        self.erosion_params = {
            'water_erosion': {
                'enabled': True,
                'rate': 0.1,
                'solubility': 0.8,
                'evaporation': 0.01,
                'iterations': 50,
                'inertia': 0.05,
                'sediment_capacity': 0.5,
                'deposition_rate': 0.1
            },
            'thermal_erosion': {
                'enabled': True,
                'rate': 0.05,
                'angle_of_repose': 30.0,  # 度
                'iterations': 30
            },
            'wind_erosion': {
                'enabled': True,
                'rate': 0.02,
                'direction': 0.0,  # 弧度
                'iterations': 20
            },
            'chemical_erosion': {
                'enabled': False,
                'rate': 0.01,
                'iterations': 10
            },
            'glacial_erosion': {
                'enabled': False,
                'rate': 0.03,
                'iterations': 15
            }
        }
        
        # 侵蚀图层
        self.erosion_map = None
        self.sediment_map = None
        self.water_map = None
        self.flow_map = None
        
        # 统计信息
        self.stats = {
            'erosion_processed': 0,
            'total_processing_time': 0.0,
            'average_processing_time': 0.0,
            'total_erosion_amount': 0.0,
            'total_sediment_amount': 0.0
        }
        
        print("✓ 侵蚀处理器已创建")
        
    def initialize(self) -> bool:
        """
        初始化侵蚀处理器
        
        Returns:
            是否初始化成功
        """
        try:
            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.initialized = False
            print("✓ 侵蚀处理器资源已清理")
            
        except Exception as e:
            print(f"✗ 侵蚀处理器资源清理失败: {e}")
            import traceback
            traceback.print_exc()
            
    def update(self, dt: float):
        """
        更新侵蚀处理器状态
        
        Args:
            dt: 时间增量
        """
        # 处理更新逻辑
        pass
        
    def apply_erosion(self, heightmap: np.ndarray, seed: int = None) -> Dict[str, np.ndarray]:
        """
        应用侵蚀效果到高度图
        
        Args:
            heightmap: 高度图数据
            seed: 随机种子
            
        Returns:
            包含处理后高度图和侵蚀相关数据的字典
        """
        try:
            processing_start_time = time.time()
            
            if not self.enabled:
                print("✗ 侵蚀处理器未启用")
                return {
                    'heightmap': heightmap,
                    'erosion_map': np.zeros_like(heightmap, dtype=np.float32),
                    'sediment_map': np.zeros_like(heightmap, dtype=np.float32),
                    'water_map': np.zeros_like(heightmap, dtype=np.float32)
                }
                
            # 更新种子
            if seed is not None:
                self.seed = seed
                
            print("✓ 开始应用侵蚀效果...")
            
            # 初始化侵蚀图层
            self._initialize_erosion_layers(heightmap.shape)
            
            # 创建高度图副本进行处理
            processed_heightmap = heightmap.copy()
            
            # 应用各种侵蚀类型
            if self.erosion_params['water_erosion']['enabled']:
                print("  → 应用水力侵蚀...")
                processed_heightmap = self._apply_water_erosion(processed_heightmap)
                
            if self.erosion_params['thermal_erosion']['enabled']:
                print("  → 应用热力侵蚀...")
                processed_heightmap = self._apply_thermal_erosion(processed_heightmap)
                
            if self.erosion_params['wind_erosion']['enabled']:
                print("  → 应用风力侵蚀...")
                processed_heightmap = self._apply_wind_erosion(processed_heightmap)
                
            if self.erosion_params['chemical_erosion']['enabled']:
                print("  → 应用化学侵蚀...")
                processed_heightmap = self._apply_chemical_erosion(processed_heightmap)
                
            if self.erosion_params['glacial_erosion']['enabled']:
                print("  → 应用冰川侵蚀...")
                processed_heightmap = self._apply_glacial_erosion(processed_heightmap)
                
            # 更新统计信息
            processing_time = time.time() - processing_start_time
            self.stats['erosion_processed'] += 1
            self.stats['total_processing_time'] += processing_time
            self.stats['average_processing_time'] = self.stats['total_processing_time'] / self.stats['erosion_processed']
            
            print(f"✓ 侵蚀处理完成，耗时: {processing_time:.2f}秒")
            return {
                'heightmap': processed_heightmap,
                'erosion_map': self.erosion_map,
                'sediment_map': self.sediment_map,
                'water_map': self.water_map
            }
            
        except Exception as e:
            print(f"✗ 侵蚀处理失败: {e}")
            import traceback
            traceback.print_exc()
            return {
                'heightmap': heightmap,
                'erosion_map': np.zeros_like(heightmap, dtype=np.float32),
                'sediment_map': np.zeros_like(heightmap, dtype=np.float32),
                'water_map': np.zeros_like(heightmap, dtype=np.float32)
            }
            
    def _initialize_erosion_layers(self, shape: tuple):
        """初始化侵蚀相关图层"""
        try:
            height, width = shape
            self.erosion_map = np.zeros((height, width), dtype=np.float32)
            self.sediment_map = np.zeros((height, width), dtype=np.float32)
            self.water_map = np.zeros((height, width), dtype=np.float32)
            self.flow_map = np.zeros((height, width, 2), dtype=np.float32)  # x, y 流向
        except Exception as e:
            print(f"✗ 侵蚀图层初始化失败: {e}")
            
    def _apply_water_erosion(self, heightmap: np.ndarray) -> np.ndarray:
        """
        应用水力侵蚀
        
        Args:
            heightmap: 高度图数据
            
        Returns:
            处理后的高度图
        """
        try:
            processed = heightmap.copy()
            height, width = processed.shape
            
            # 获取水力侵蚀参数
            params = self.erosion_params['water_erosion']
            iterations = params['iterations']
            erosion_rate = params['rate']
            solubility = params['solubility']
            evaporation = params['evaporation']
            inertia = params['inertia']
            sediment_capacity = params['sediment_capacity']
            deposition_rate = params['deposition_rate']
            
            # 模拟多个迭代步骤
            for iteration in range(iterations):
                # 计算水流方向
                self._calculate_water_flow(processed)
                
                # 模拟侵蚀和沉积
                for y in range(height):
                    for x in range(width):
                        # 计算当前点的侵蚀量
                        erosion_amount = erosion_rate * solubility * self.water_map[y, x]
                        
                        # 应用侵蚀
                        if erosion_amount > 0:
                            processed[y, x] -= erosion_amount
                            self.erosion_map[y, x] += erosion_amount
                            self.sediment_map[y, x] += erosion_amount
                            
                        # 检查沉积（如果水流速度慢且携带沉积物过多）
                        sediment_ratio = self.sediment_map[y, x] / max(0.001, self.water_map[y, x])
                        if sediment_ratio > sediment_capacity:
                            deposition_amount = (sediment_ratio - sediment_capacity) * deposition_rate
                            processed[y, x] += deposition_amount
                            self.sediment_map[y, x] -= deposition_amount
                            
                # 应用蒸发
                self.water_map *= (1.0 - evaporation)
                
                # 确保高度值合理
                processed = np.clip(processed, 0.0, 1.0)
                
            # 更新统计信息
            self.stats['total_erosion_amount'] += np.sum(self.erosion_map)
            self.stats['total_sediment_amount'] += np.sum(self.sediment_map)
            
            return processed
            
        except Exception as e:
            print(f"✗ 水力侵蚀应用失败: {e}")
            return heightmap
            
    def _calculate_water_flow(self, heightmap: np.ndarray):
        """
        计算水流方向和累积
        
        Args:
            heightmap: 高度图数据
        """
        try:
            height, width = heightmap.shape
            
            # 简化的水流计算
            for y in range(height):
                for x in range(width):
                    # 增加降雨量
                    self.water_map[y, x] += 0.01
                    
                    # 计算流向（流向最低的邻居）
                    lowest_height = heightmap[y, x]
                    flow_x, flow_y = 0, 0
                    
                    # 检查8个邻居
                    for dy in [-1, 0, 1]:
                        for dx in [-1, 0, 1]:
                            if dy == 0 and dx == 0:
                                continue
                                
                            ny, nx = y + dy, x + dx
                            if 0 <= ny < height and 0 <= nx < width:
                                neighbor_height = heightmap[ny, nx] + self.water_map[ny, nx]
                                if neighbor_height < lowest_height:
                                    lowest_height = neighbor_height
                                    flow_x, flow_y = dx, dy
                                    
                    # 设置流向
                    self.flow_map[y, x, 0] = flow_x
                    self.flow_map[y, x, 1] = flow_y
                    
                    # 将水流移动到下一个位置
                    if flow_x != 0 or flow_y != 0:
                        ny, nx = y + int(flow_y), x + int(flow_x)
                        if 0 <= ny < height and 0 <= nx < width:
                            self.water_map[ny, nx] += self.water_map[y, x] * 0.8
                            self.water_map[y, x] *= 0.2
                            
        except Exception as e:
            print(f"✗ 水流计算失败: {e}")
            
    def _apply_thermal_erosion(self, heightmap: np.ndarray) -> np.ndarray:
        """
        应用热力侵蚀（重力侵蚀）
        
        Args:
            heightmap: 高度图数据
            
        Returns:
            处理后的高度图
        """
        try:
            processed = heightmap.copy()
            height, width = processed.shape
            
            # 获取热力侵蚀参数
            params = self.erosion_params['thermal_erosion']
            iterations = params['iterations']
            erosion_rate = params['rate']
            angle_of_repose = math.radians(params['angle_of_repose'])
            tan_repose = math.tan(angle_of_repose)
            
            # 模拟多个迭代步骤
            for iteration in range(iterations):
                new_heightmap = processed.copy()
                
                # 对每个点应用热力侵蚀
                for y in range(height):
                    for x in range(width):
                        current_height = processed[y, x]
                        
                        # 检查4个直接邻居
                        for dy, dx in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
                            ny, nx = y + dy, x + dx
                            if 0 <= ny < height and 0 <= nx < width:
                                neighbor_height = processed[ny, nx]
                                
                                # 计算高度差
                                height_diff = current_height - neighbor_height
                                
                                # 如果高度差超过角度限制
                                if height_diff > 0:
                                    # 计算最大稳定高度差
                                    max_diff = tan_repose * 1.0  # 假设网格间距为1
                                    
                                    # 如果超过最大稳定差值，则发生侵蚀
                                    if height_diff > max_diff:
                                        # 移动材料到较低位置
                                        move_amount = (height_diff - max_diff) * erosion_rate
                                        new_heightmap[y, x] -= move_amount
                                        new_heightmap[ny, nx] += move_amount
                                        
                                        # 更新侵蚀图
                                        self.erosion_map[y, x] += move_amount
                                        
                processed = new_heightmap
                
            return processed
            
        except Exception as e:
            print(f"✗ 热力侵蚀应用失败: {e}")
            return heightmap
            
    def _apply_wind_erosion(self, heightmap: np.ndarray) -> np.ndarray:
        """
        应用风力侵蚀
        
        Args:
            heightmap: 高度图数据
            
        Returns:
            处理后的高度图
        """
        try:
            processed = heightmap.copy()
            height, width = processed.shape
            
            # 获取风力侵蚀参数
            params = self.erosion_params['wind_erosion']
            iterations = params['iterations']
            erosion_rate = params['rate']
            wind_direction = params['direction']
            
            # 计算风向向量
            wind_dx = math.cos(wind_direction)
            wind_dy = math.sin(wind_direction)
            
            # 模拟多个迭代步骤
            for iteration in range(iterations):
                new_heightmap = processed.copy()
                
                # 对每个点应用风力侵蚀
                for y in range(height):
                    for x in range(width):
                        # 风从特定方向吹来
                        # 计算风的来源位置
                        source_x = int(x - wind_dx * 2)  # 2个单位距离
                        source_y = int(y - wind_dy * 2)
                        
                        # 如果来源位置有效
                        if 0 <= source_y < height and 0 <= source_x < width:
                            # 如果当前点比来源点高，则可能发生风蚀
                            height_diff = processed[y, x] - processed[source_y, source_x]
                            if height_diff > 0.01:  # 阈值
                                # 应用风力侵蚀
                                erosion_amount = erosion_rate * height_diff
                                new_heightmap[y, x] -= erosion_amount
                                self.erosion_map[y, x] += erosion_amount
                                
                processed = new_heightmap
                
            return processed
            
        except Exception as e:
            print(f"✗ 风力侵蚀应用失败: {e}")
            return heightmap
            
    def _apply_chemical_erosion(self, heightmap: np.ndarray) -> np.ndarray:
        """
        应用化学侵蚀
        
        Args:
            heightmap: 高度图数据
            
        Returns:
            处理后的高度图
        """
        try:
            processed = heightmap.copy()
            height, width = processed.shape
            
            # 获取化学侵蚀参数
            params = self.erosion_params['chemical_erosion']
            iterations = params['iterations']
            erosion_rate = params['rate']
            
            # 模拟多个迭代步骤
            for iteration in range(iterations):
                # 简化的化学侵蚀：基于高度和随机因素
                for y in range(height):
                    for x in range(width):
                        # 化学侵蚀通常影响较低的区域（如河流、湖泊）
                        if processed[y, x] < 0.3:  # 假设低地更容易发生化学侵蚀
                            # 添加随机因素
                            chemical_factor = np.random.random() * 0.5 + 0.5
                            erosion_amount = erosion_rate * chemical_factor * (0.3 - processed[y, x])
                            processed[y, x] -= erosion_amount
                            self.erosion_map[y, x] += erosion_amount
                            
            return processed
            
        except Exception as e:
            print(f"✗ 化学侵蚀应用失败: {e}")
            return heightmap
            
    def _apply_glacial_erosion(self, heightmap: np.ndarray) -> np.ndarray:
        """
        应用冰川侵蚀
        
        Args:
            heightmap: 高度图数据
            
        Returns:
            处理后的高度图
        """
        try:
            processed = heightmap.copy()
            height, width = processed.shape
            
            # 获取冰川侵蚀参数
            params = self.erosion_params['glacial_erosion']
            iterations = params['iterations']
            erosion_rate = params['rate']
            
            # 模拟多个迭代步骤
            for iteration in range(iterations):
                # 冰川侵蚀：平滑地形并创建U型谷
                new_heightmap = processed.copy()
                
                for y in range(height):
                    for x in range(width):
                        # 冰川通常在高海拔地区形成
                        if processed[y, x] > 0.7:  # 高海拔
                            # 平滑周围区域
                            total_height = 0.0
                            count = 0
                            
                            # 检查3x3邻域
                            for dy in [-1, 0, 1]:
                                for dx in [-1, 0, 1]:
                                    ny, nx = y + dy, x + dx
                                    if 0 <= ny < height and 0 <= nx < width:
                                        total_height += processed[ny, nx]
                                        count += 1
                                        
                            if count > 0:
                                average_height = total_height / count
                                # 应用冰川侵蚀（平滑化）
                                glacial_effect = erosion_rate * (processed[y, x] - average_height)
                                new_heightmap[y, x] -= glacial_effect
                                self.erosion_map[y, x] += abs(glacial_effect)
                                
                processed = new_heightmap
                
            return processed
            
        except Exception as e:
            print(f"✗ 冰川侵蚀应用失败: {e}")
            return heightmap
            
    def set_seed(self, seed: int):
        """
        设置随机种子
        
        Args:
            seed: 随机种子
        """
        self.seed = seed
        print(f"✓ 侵蚀处理器随机种子设置为: {seed}")
        
    def set_erosion_parameters(self, erosion_type: str, params: Dict[str, Any]):
        """
        设置侵蚀参数
        
        Args:
            erosion_type: 侵蚀类型
            params: 参数字典
        """
        if erosion_type in self.erosion_params:
            self.erosion_params[erosion_type].update(params)
            print(f"✓ {erosion_type} 侵蚀参数已更新: {self.erosion_params[erosion_type]}")
        else:
            print(f"✗ 无效的侵蚀类型: {erosion_type}")
            
    def enable_erosion_type(self, erosion_type: str, enabled: bool):
        """
        启用/禁用侵蚀类型
        
        Args:
            erosion_type: 侵蚀类型
            enabled: 是否启用
        """
        if erosion_type in self.erosion_params:
            self.erosion_params[erosion_type]['enabled'] = enabled
            state = "启用" if enabled else "禁用"
            print(f"✓ {erosion_type} 侵蚀已{state}")
        else:
            print(f"✗ 无效的侵蚀类型: {erosion_type}")
            
    def get_stats(self) -> Dict[str, Any]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        # 更新平均处理时间
        if self.stats['erosion_processed'] > 0:
            self.stats['average_processing_time'] = self.stats['total_processing_time'] / self.stats['erosion_processed']
        return self.stats.copy()
        
    def reset_stats(self):
        """重置统计信息"""
        self.stats = {
            'erosion_processed': 0,
            'total_processing_time': 0.0,
            'average_processing_time': 0.0,
            'total_erosion_amount': 0.0,
            'total_sediment_amount': 0.0
        }
        print("✓ 侵蚀处理器统计信息已重置")
        
    def get_erosion_map(self) -> np.ndarray:
        """
        获取侵蚀图
        
        Returns:
            侵蚀图数据
        """
        return self.erosion_map if self.erosion_map is not None else np.array([])
        
    def get_sediment_map(self) -> np.ndarray:
        """
        获取沉积物图
        
        Returns:
            沉积物图数据
        """
        return self.sediment_map if self.sediment_map is not None else np.array([])
        
    def get_water_map(self) -> np.ndarray:
        """
        获取水图
        
        Returns:
            水图数据
        """
        return self.water_map if self.water_map is not None else np.array([])
        
    def set_water_erosion_parameters(self, rate: float = None, solubility: float = None, 
                                  evaporation: float = None, inertia: float = None,
                                  sediment_capacity: float = None, deposition_rate: float = None):
        """
        设置水力侵蚀参数
        
        Args:
            rate: 侵蚀速率
            solubility: 溶解度
            evaporation: 蒸发率
            inertia: 惯性
            sediment_capacity: 沉积物容量
            deposition_rate: 沉积率
        """
        params = self.erosion_params['water_erosion']
        if rate is not None:
            params['rate'] = max(0.0, rate)
        if solubility is not None:
            params['solubility'] = max(0.0, min(1.0, solubility))
        if evaporation is not None:
            params['evaporation'] = max(0.0, min(1.0, evaporation))
        if inertia is not None:
            params['inertia'] = max(0.0, min(1.0, inertia))
        if sediment_capacity is not None:
            params['sediment_capacity'] = max(0.0, sediment_capacity)
        if deposition_rate is not None:
            params['deposition_rate'] = max(0.0, deposition_rate)
            
        print(f"✓ 水力侵蚀参数已更新: {params}")
        
    def set_thermal_erosion_parameters(self, rate: float = None, angle_of_repose: float = None):
        """
        设置热力侵蚀参数
        
        Args:
            rate: 侵蚀速率
            angle_of_repose: 休止角（度）
        """
        params = self.erosion_params['thermal_erosion']
        if rate is not None:
            params['rate'] = max(0.0, rate)
        if angle_of_repose is not None:
            params['angle_of_repose'] = max(0.0, angle_of_repose)
            
        print(f"✓ 热力侵蚀参数已更新: {params}")
        
    def set_wind_erosion_parameters(self, rate: float = None, direction: float = None):
        """
        设置风力侵蚀参数
        
        Args:
            rate: 侵蚀速率
            direction: 风向（弧度）
        """
        params = self.erosion_params['wind_erosion']
        if rate is not None:
            params['rate'] = max(0.0, rate)
        if direction is not None:
            params['direction'] = direction
            
        print(f"✓ 风力侵蚀参数已更新: {params}")
        
    def apply_selective_erosion(self, heightmap: np.ndarray, mask: np.ndarray, 
                               seed: int = None) -> Dict[str, np.ndarray]:
        """
        在指定区域应用侵蚀
        
        Args:
            heightmap: 高度图数据
            mask: 掩码（0-1范围，1表示完全应用侵蚀）
            seed: 随机种子
            
        Returns:
            包含处理后高度图和侵蚀相关数据的字典
        """
        try:
            processing_start_time = time.time()
            
            if not self.enabled:
                print("✗ 侵蚀处理器未启用")
                return {
                    'heightmap': heightmap,
                    'erosion_map': np.zeros_like(heightmap, dtype=np.float32),
                    'sediment_map': np.zeros_like(heightmap, dtype=np.float32),
                    'water_map': np.zeros_like(heightmap, dtype=np.float32)
                }
                
            # 更新种子
            if seed is not None:
                self.seed = seed
                
            print("✓ 开始应用选择性侵蚀...")
            
            # 确保掩码尺寸匹配
            if mask.shape != heightmap.shape:
                print("✗ 掩码尺寸与高度图不匹配")
                return {
                    'heightmap': heightmap,
                    'erosion_map': np.zeros_like(heightmap, dtype=np.float32),
                    'sediment_map': np.zeros_like(heightmap, dtype=np.float32),
                    'water_map': np.zeros_like(heightmap, dtype=np.float32)
                }
                
            # 初始化侵蚀图层
            self._initialize_erosion_layers(heightmap.shape)
            
            # 创建高度图副本进行处理
            processed_heightmap = heightmap.copy()
            
            # 在掩码区域应用侵蚀
            mask_indices = np.where(mask > 0.5)
            
            # 创建临时高度图只包含掩码区域
            temp_heightmap = heightmap.copy()
            
            # 应用各种侵蚀类型（只在掩码区域）
            if self.erosion_params['water_erosion']['enabled']:
                print("  → 应用水力侵蚀（选择性）...")
                temp_heightmap = self._apply_water_erosion_selective(temp_heightmap, mask)
                
            if self.erosion_params['thermal_erosion']['enabled']:
                print("  → 应用热力侵蚀（选择性）...")
                temp_heightmap = self._apply_thermal_erosion_selective(temp_heightmap, mask)
                
            if self.erosion_params['wind_erosion']['enabled']:
                print("  → 应用风力侵蚀（选择性）...")
                temp_heightmap = self._apply_wind_erosion_selective(temp_heightmap, mask)
                
            # 只更新掩码区域的值
            processed_heightmap[mask_indices] = temp_heightmap[mask_indices]
            
            # 更新统计信息
            processing_time = time.time() - processing_start_time
            self.stats['erosion_processed'] += 1
            self.stats['total_processing_time'] += processing_time
            self.stats['average_processing_time'] = self.stats['total_processing_time'] / self.stats['erosion_processed']
            
            print(f"✓ 选择性侵蚀处理完成，耗时: {processing_time:.2f}秒")
            return {
                'heightmap': processed_heightmap,
                'erosion_map': self.erosion_map,
                'sediment_map': self.sediment_map,
                'water_map': self.water_map
            }
            
        except Exception as e:
            print(f"✗ 选择性侵蚀处理失败: {e}")
            import traceback
            traceback.print_exc()
            return {
                'heightmap': heightmap,
                'erosion_map': np.zeros_like(heightmap, dtype=np.float32),
                'sediment_map': np.zeros_like(heightmap, dtype=np.float32),
                'water_map': np.zeros_like(heightmap, dtype=np.float32)
            }
            
    def _apply_water_erosion_selective(self, heightmap: np.ndarray, mask: np.ndarray) -> np.ndarray:
        """在选择区域应用水力侵蚀"""
        try:
            processed = heightmap.copy()
            height, width = processed.shape
            
            # 获取水力侵蚀参数
            params = self.erosion_params['water_erosion']
            iterations = params['iterations']
            erosion_rate = params['rate'] * 0.5  # 降低速率以适应选择性应用
            
            # 只在掩码区域应用侵蚀
            mask_indices = np.where(mask > 0.5)
            
            # 简化的选择性水力侵蚀
            for iteration in range(iterations):
                for y, x in zip(mask_indices[0], mask_indices[1]):
                    # 简单的侵蚀：降低高点，填充低点
                    if processed[y, x] > 0.8:  # 高点
                        erosion_amount = erosion_rate * mask[y, x]
                        processed[y, x] -= erosion_amount
                        self.erosion_map[y, x] += erosion_amount
                    elif processed[y, x] < 0.2:  # 低点
                        deposition_amount = erosion_rate * 0.5 * mask[y, x]
                        processed[y, x] += deposition_amount
                        self.sediment_map[y, x] += deposition_amount
                        
            return processed
            
        except Exception as e:
            print(f"✗ 选择性水力侵蚀应用失败: {e}")
            return heightmap
            
    def _apply_thermal_erosion_selective(self, heightmap: np.ndarray, mask: np.ndarray) -> np.ndarray:
        """在选择区域应用热力侵蚀"""
        try:
            processed = heightmap.copy()
            height, width = processed.shape
            
            # 获取热力侵蚀参数
            params = self.erosion_params['thermal_erosion']
            iterations = params['iterations']
            erosion_rate = params['rate'] * 0.5  # 降低速率以适应选择性应用
            
            # 只在掩码区域应用侵蚀
            mask_indices = np.where(mask > 0.5)
            
            # 简化的选择性热力侵蚀
            for iteration in range(iterations):
                for y, x in zip(mask_indices[0], mask_indices[1]):
                    # 检查直接邻居
                    for dy, dx in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
                        ny, nx = y + dy, x + dx
                        if 0 <= ny < height and 0 <= nx < width:
                            height_diff = processed[y, x] - processed[ny, nx]
                            if height_diff > 0.1:  # 显著高度差
                                move_amount = erosion_rate * height_diff * mask[y, x]
                                processed[y, x] -= move_amount
                                processed[ny, nx] += move_amount
                                self.erosion_map[y, x] += move_amount
                                
            return processed
            
        except Exception as e:
            print(f"✗ 选择性热力侵蚀应用失败: {e}")
            return heightmap
            
    def _apply_wind_erosion_selective(self, heightmap: np.ndarray, mask: np.ndarray) -> np.ndarray:
        """在选择区域应用风力侵蚀"""
        try:
            processed = heightmap.copy()
            height, width = processed.shape
            
            # 获取风力侵蚀参数
            params = self.erosion_params['wind_erosion']
            erosion_rate = params['rate'] * 0.5  # 降低速率以适应选择性应用
            wind_direction = params['direction']
            
            # 计算风向向量
            wind_dx = math.cos(wind_direction)
            wind_dy = math.sin(wind_direction)
            
            # 只在掩码区域应用侵蚀
            mask_indices = np.where(mask > 0.5)
            
            # 简化的选择性风力侵蚀
            for y, x in zip(mask_indices[0], mask_indices[1]):
                # 风从特定方向吹来
                source_x = int(x - wind_dx * 1)  # 1个单位距离
                source_y = int(y - wind_dy * 1)
                
                # 如果来源位置有效且也在掩码区域内
                if (0 <= source_y < height and 0 <= source_x < width and 
                    mask[source_y, source_x] > 0.5):
                    # 应用风力侵蚀
                    height_diff = processed[y, x] - processed[source_y, source_x]
                    if height_diff > 0.01:
                        erosion_amount = erosion_rate * height_diff * mask[y, x]
                        processed[y, x] -= erosion_amount
                        self.erosion_map[y, x] += erosion_amount
                        
            return processed
            
        except Exception as e:
            print(f"✗ 选择性风力侵蚀应用失败: {e}")
            return heightmap
            
    def blend_erosion_maps(self, erosion_maps: List[np.ndarray], weights: List[float] = None) -> np.ndarray:
        """
        混合多个侵蚀图
        
        Args:
            erosion_maps: 侵蚀图列表
            weights: 权重列表（如果为None，则平均分配权重）
            
        Returns:
            混合后的侵蚀图
        """
        try:
            if not erosion_maps:
                return np.array([])
                
            if len(erosion_maps) == 1:
                return erosion_maps[0].copy()
                
            # 确保所有侵蚀图尺寸相同
            base_shape = erosion_maps[0].shape
            for em in erosion_maps:
                if em.shape != base_shape:
                    raise ValueError("所有侵蚀图必须具有相同的尺寸")
                    
            # 处理权重
            if weights is None:
                weights = [1.0 / len(erosion_maps)] * len(erosion_maps)
            elif len(weights) != len(erosion_maps):
                raise ValueError("权重数量必须与侵蚀图数量相同")
                
            # 归一化权重
            total_weight = sum(weights)
            if total_weight > 0:
                weights = [w / total_weight for w in weights]
                
            # 混合侵蚀图
            blended = np.zeros(base_shape, dtype=np.float32)
            for i, (em, weight) in enumerate(zip(erosion_maps, weights)):
                blended += em * weight
                
            return blended
            
        except Exception as e:
            print(f"✗ 侵蚀图混合失败: {e}")
            import traceback
            traceback.print_exc()
            # 返回第一个侵蚀图的副本
            return erosion_maps[0].copy() if erosion_maps else np.array([])
            
    def smooth_erosion_map(self, erosion_map: np.ndarray, kernel_size: int = 3) -> np.ndarray:
        """
        平滑侵蚀图
        
        Args:
            erosion_map: 原始侵蚀图
            kernel_size: 平滑核大小
            
        Returns:
            平滑后的侵蚀图
        """
        try:
            if kernel_size < 1:
                return erosion_map
                
            smoothed = erosion_map.copy()
            height, width = smoothed.shape
            
            # 简单的均值滤波
            half_kernel = kernel_size // 2
            
            for y in range(height):
                for x in range(width):
                    total = 0.0
                    count = 0
                    
                    # 应用平滑核
                    for dy in range(-half_kernel, half_kernel + 1):
                        for dx in range(-half_kernel, half_kernel + 1):
                            ny, nx = y + dy, x + dx
                            if 0 <= ny < height and 0 <= nx < width:
                                total += erosion_map[ny, nx]
                                count += 1
                                
                    if count > 0:
                        smoothed[y, x] = total / count
                        
            return smoothed
            
        except Exception as e:
            print(f"✗ 侵蚀图平滑失败: {e}")
            return erosion_map
            
    def apply_erosion_intensity(self, heightmap: np.ndarray, intensity_map: np.ndarray, 
                              seed: int = None) -> Dict[str, np.ndarray]:
        """
        根据强度图应用侵蚀
        
        Args:
            heightmap: 高度图数据
            intensity_map: 侵蚀强度图（0-1范围）
            seed: 随机种子
            
        Returns:
            包含处理后高度图和侵蚀相关数据的字典
        """
        try:
            processing_start_time = time.time()
            
            if not self.enabled:
                print("✗ 侵蚀处理器未启用")
                return {
                    'heightmap': heightmap,
                    'erosion_map': np.zeros_like(heightmap, dtype=np.float32),
                    'sediment_map': np.zeros_like(heightmap, dtype=np.float32),
                    'water_map': np.zeros_like(heightmap, dtype=np.float32)
                }
                
            # 更新种子
            if seed is not None:
                self.seed = seed
                
            # 确保强度图尺寸匹配
            if intensity_map.shape != heightmap.shape:
                print("✗ 强度图尺寸与高度图不匹配")
                return {
                    'heightmap': heightmap,
                    'erosion_map': np.zeros_like(heightmap, dtype=np.float32),
                    'sediment_map': np.zeros_like(heightmap, dtype=np.float32),
                    'water_map': np.zeros_like(heightmap, dtype=np.float32)
                }
                
            print("✓ 开始应用强度控制的侵蚀...")
            
            # 初始化侵蚀图层
            self._initialize_erosion_layers(heightmap.shape)
            
            # 创建高度图副本进行处理
            processed_heightmap = heightmap.copy()
            
            # 根据强度图调整侵蚀参数
            base_water_params = self.erosion_params['water_erosion'].copy()
            base_thermal_params = self.erosion_params['thermal_erosion'].copy()
            base_wind_params = self.erosion_params['wind_erosion'].copy()
            
            # 对每个点根据强度应用侵蚀
            height, width = processed_heightmap.shape
            for y in range(height):
                for x in range(width):
                    intensity = intensity_map[y, x]
                    if intensity > 0.1:  # 只在强度大于阈值时应用侵蚀
                        # 调整侵蚀参数
                        self.erosion_params['water_erosion']['rate'] = base_water_params['rate'] * intensity
                        self.erosion_params['thermal_erosion']['rate'] = base_thermal_params['rate'] * intensity
                        self.erosion_params['wind_erosion']['rate'] = base_wind_params['rate'] * intensity
                        
                        # 应用局部侵蚀（简化版本）
                        if self.erosion_params['water_erosion']['enabled']:
                            # 简化的水力侵蚀
                            if processed_heightmap[y, x] > 0.8:
                                erosion_amount = self.erosion_params['water_erosion']['rate'] * 0.1
                                processed_heightmap[y, x] -= erosion_amount
                                self.erosion_map[y, x] += erosion_amount
                                
            # 恢复原始侵蚀参数
            self.erosion_params['water_erosion'] = base_water_params
            self.erosion_params['thermal_erosion'] = base_thermal_params
            self.erosion_params['wind_erosion'] = base_wind_params
            
            # 更新统计信息
            processing_time = time.time() - processing_start_time
            self.stats['erosion_processed'] += 1
            self.stats['total_processing_time'] += processing_time
            self.stats['average_processing_time'] = self.stats['total_processing_time'] / self.stats['erosion_processed']
            
            print(f"✓ 强度控制的侵蚀处理完成，耗时: {processing_time:.2f}秒")
            return {
                'heightmap': processed_heightmap,
                'erosion_map': self.erosion_map,
                'sediment_map': self.sediment_map,
                'water_map': self.water_map
            }
            
        except Exception as e:
            print(f"✗ 强度控制的侵蚀处理失败: {e}")
            import traceback
            traceback.print_exc()
            return {
                'heightmap': heightmap,
                'erosion_map': np.zeros_like(heightmap, dtype=np.float32),
                'sediment_map': np.zeros_like(heightmap, dtype=np.float32),
                'water_map': np.zeros_like(heightmap, dtype=np.float32)
            }
            
    def export_erosion_data(self, filename: str) -> bool:
        """
        导出侵蚀数据
        
        Args:
            filename: 文件名
            
        Returns:
            是否导出成功
        """
        try:
            import json
            
            erosion_data = {
                'parameters': self.erosion_params,
                'stats': self.stats,
                'timestamp': time.time()
            }
            
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(erosion_data, f, ensure_ascii=False, indent=2)
                
            print(f"✓ 侵蚀数据已导出到: {filename}")
            return True
            
        except Exception as e:
            print(f"✗ 侵蚀数据导出失败: {e}")
            return False
            
    def import_erosion_data(self, filename: str) -> bool:
        """
        导入侵蚀数据
        
        Args:
            filename: 文件名
            
        Returns:
            是否导入成功
        """
        try:
            import json
            
            with open(filename, 'r', encoding='utf-8') as f:
                erosion_data = json.load(f)
                
            # 更新参数
            if 'parameters' in erosion_data:
                self.erosion_params.update(erosion_data['parameters'])
                
            # 更新统计信息
            if 'stats' in erosion_data:
                self.stats.update(erosion_data['stats'])
                
            print(f"✓ 侵蚀数据已从 {filename} 导入")
            return True
            
        except Exception as e:
            print(f"✗ 侵蚀数据导入失败: {e}")
            return False
            
    def reset_erosion_maps(self):
        """重置侵蚀图层"""
        self.erosion_map = None
        self.sediment_map = None
        self.water_map = None
        self.flow_map = None
        print("✓ 侵蚀图层已重置")
        
    def get_erosion_types(self) -> List[str]:
        """
        获取可用的侵蚀类型
        
        Returns:
            侵蚀类型列表
        """
        return list(self.erosion_params.keys())
        
    def get_erosion_parameters(self, erosion_type: str) -> Dict[str, Any]:
        """
        获取指定侵蚀类型的参数
        
        Args:
            erosion_type: 侵蚀类型
            
        Returns:
            参数字典
        """
        return self.erosion_params.get(erosion_type, {}).copy()