"""
植被生成器
负责根据环境条件和生态规则生成植被分布
"""

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

class VegetationSpawner:
    """
    植被生成器
    负责根据环境条件、地形特征和生态规则生成植被分布
    """
    
    def __init__(self, plugin):
        """
        初始化植被生成器
        
        Args:
            plugin: 植被和生态系统插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 植被分布算法
        self.distribution_algorithms = {
            'random': {
                'name': '随机分布',
                'description': '完全随机的植被分布'
            },
            'clustered': {
                'name': '聚集分布',
                'description': '植被以群落形式聚集分布'
            },
            'gradient': {
                'name': '梯度分布',
                'description': '根据环境因子梯度分布植被'
            },
            'competitive': {
                'name': '竞争分布',
                'description': '考虑植物间竞争关系的分布'
            },
            'environmental': {
                'name': '环境适应分布',
                'description': '基于环境适应性的分布'
            }
        }
        
        # 生成配置
        self.spawn_config = {
            'algorithm': 'environmental',     # 默认算法
            'density': 1.0,                  # 植被密度
            'clumping_factor': 0.7,          # 聚集因子
            'random_seed': 12345,            # 随机种子
            'spawn_area': ((-100, -100), (100, 100)),  # 生成区域
            'max_instances': 10000           # 最大实例数
        }
        
        # 环境因子权重
        self.environment_weights = {
            'temperature': 0.25,
            'humidity': 0.25,
            'soil_fertility': 0.25,
            'light_level': 0.15,
            'water_level': 0.10
        }
        
        # 植被生态位偏好
        self.ecological_preferences = {
            'grass': {
                'temperature_preference': (10, 30),
                'humidity_preference': (40, 80),
                'fertility_preference': (0.3, 1.0),
                'light_preference': (0.5, 1.0),
                'water_preference': (0.4, 0.8)
            },
            'bush': {
                'temperature_preference': (5, 25),
                'humidity_preference': (30, 70),
                'fertility_preference': (0.4, 1.0),
                'light_preference': (0.6, 1.0),
                'water_preference': (0.3, 0.7)
            },
            'tree': {
                'temperature_preference': (0, 30),
                'humidity_preference': (40, 90),
                'fertility_preference': (0.5, 1.0),
                'light_preference': (0.7, 1.0),
                'water_preference': (0.5, 1.0)
            },
            'flower': {
                'temperature_preference': (15, 25),
                'humidity_preference': (50, 80),
                'fertility_preference': (0.6, 1.0),
                'light_preference': (0.8, 1.0),
                'water_preference': (0.6, 0.9)
            },
            'fern': {
                'temperature_preference': (10, 20),
                'humidity_preference': (70, 100),
                'fertility_preference': (0.4, 0.8),
                'light_preference': (0.2, 0.6),
                'water_preference': (0.7, 1.0)
            },
            'cactus': {
                'temperature_preference': (20, 40),
                'humidity_preference': (10, 30),
                'fertility_preference': (0.1, 0.5),
                'light_preference': (0.8, 1.0),
                'water_preference': (0.1, 0.3)
            },
            'moss': {
                'temperature_preference': (5, 20),
                'humidity_preference': (80, 100),
                'fertility_preference': (0.1, 0.6),
                'light_preference': (0.1, 0.4),
                'water_preference': (0.8, 1.0)
            },
            'vine': {
                'temperature_preference': (15, 30),
                'humidity_preference': (60, 90),
                'fertility_preference': (0.3, 0.8),
                'light_preference': (0.4, 0.8),
                'water_preference': (0.6, 0.9)
            }
        }
        
        # 空间分布参数
        self.spatial_parameters = {
            'min_distance': 0.5,             # 最小间距
            'max_cluster_size': 10,          # 最大集群大小
            'cluster_radius': 5.0,           # 集群半径
            'edge_blending': 0.1             # 边缘混合
        }
        
        # 生成统计
        self.spawn_stats = {
            'total_spawned': 0,
            'spawned_by_type': {},
            'failed_spawns': 0,
            'last_spawn_time': 0.0
        }
        
        # 生成历史
        self.spawn_history = []
        self.max_history_size = 100
        
        print("✓ 植被生成器已创建")
        
    def initialize(self) -> bool:
        """
        初始化植被生成器
        
        Returns:
            是否初始化成功
        """
        try:
            # 初始化统计数据
            if self.plugin.vegetation_manager:
                veg_types = self.plugin.vegetation_manager.get_vegetation_types()
                self.spawn_stats['spawned_by_type'] = {vt: 0 for vt in veg_types}
            
            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.spawn_history.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
                
            # 可以在这里添加动态生成逻辑
            pass
            
        except Exception as e:
            print(f"✗ 植被生成器更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def spawn_vegetation(self, area: Tuple[Tuple[float, float], Tuple[float, float]] = None, 
                        density: float = None, algorithm: str = None) -> int:
        """
        生成植被
        
        Args:
            area: 生成区域 ((min_x, min_y), (max_x, max_y))
            density: 植被密度
            algorithm: 生成算法
            
        Returns:
            生成的植被实例数量
        """
        try:
            if not self.plugin.vegetation_manager:
                print("✗ 植被管理器不可用")
                return 0
                
            # 使用默认值或传入值
            spawn_area = area if area else self.spawn_config['spawn_area']
            spawn_density = density if density else self.spawn_config['density']
            spawn_algorithm = algorithm if algorithm else self.spawn_config['algorithm']
            
            # 检查算法有效性
            if spawn_algorithm not in self.distribution_algorithms:
                print(f"✗ 无效的生成算法: {spawn_algorithm}")
                return 0
                
            # 根据算法生成植被
            spawned_count = 0
            if spawn_algorithm == 'random':
                spawned_count = self._spawn_random(spawn_area, spawn_density)
            elif spawn_algorithm == 'clustered':
                spawned_count = self._spawn_clustered(spawn_area, spawn_density)
            elif spawn_algorithm == 'gradient':
                spawned_count = self._spawn_gradient(spawn_area, spawn_density)
            elif spawn_algorithm == 'competitive':
                spawned_count = self._spawn_competitive(spawn_area, spawn_density)
            elif spawn_algorithm == 'environmental':
                spawned_count = self._spawn_environmental(spawn_area, spawn_density)
                
            # 更新统计信息
            self.spawn_stats['total_spawned'] += spawned_count
            self.spawn_stats['last_spawn_time'] = time.time()
            
            # 记录生成历史
            self._record_spawn_event(spawn_algorithm, spawned_count, spawn_area)
            
            print(f"✓ 植被生成完成: {spawned_count} 个实例，使用算法: {self.distribution_algorithms[spawn_algorithm]['name']}")
            return spawned_count
            
        except Exception as e:
            print(f"✗ 植被生成失败: {e}")
            import traceback
            traceback.print_exc()
            self.spawn_stats['failed_spawns'] += 1
            return 0
            
    def _spawn_random(self, area: Tuple[Tuple[float, float], Tuple[float, float]], density: float) -> int:
        """
        随机生成植被
        
        Args:
            area: 生成区域
            density: 植被密度
            
        Returns:
            生成的植被实例数量
        """
        try:
            (min_x, min_y), (max_x, max_y) = area
            area_size = (max_x - min_x) * (max_y - min_y)
            target_count = int(area_size * density * 0.1)  # 调整密度系数
            
            spawned_count = 0
            veg_types = self.plugin.vegetation_manager.get_vegetation_types()
            
            for _ in range(target_count):
                if self._check_max_instances():
                    break
                    
                # 随机选择植被类型
                veg_type = random.choice(veg_types)
                
                # 随机生成位置
                x = random.uniform(min_x, max_x)
                y = 0.0  # 假设地面高度为0
                z = random.uniform(min_y, max_y)
                
                # 创建植被实例
                instance_id = self.plugin.vegetation_manager.create_vegetation_instance(
                    veg_type, (x, y, z)
                )
                
                if instance_id >= 0:
                    self.spawn_stats['spawned_by_type'][veg_type] += 1
                    spawned_count += 1
                    
            return spawned_count
            
        except Exception as e:
            print(f"✗ 随机植被生成失败: {e}")
            return 0
            
    def _spawn_clustered(self, area: Tuple[Tuple[float, float], Tuple[float, float]], density: float) -> int:
        """
        聚集生成植被
        
        Args:
            area: 生成区域
            density: 植被密度
            
        Returns:
            生成的植被实例数量
        """
        try:
            (min_x, min_y), (max_x, max_y) = area
            area_size = (max_x - min_x) * (max_y - min_y)
            target_count = int(area_size * density * 0.1)
            
            spawned_count = 0
            veg_types = self.plugin.vegetation_manager.get_vegetation_types()
            
            # 生成集群
            clusters = max(1, int(target_count * (1 - self.spawn_config['clumping_factor'])))
            
            for _ in range(clusters):
                if self._check_max_instances():
                    break
                    
                # 随机选择集群中心
                center_x = random.uniform(min_x, max_x)
                center_z = random.uniform(min_y, max_y)
                
                # 随机选择集群大小
                cluster_size = random.randint(1, self.spatial_parameters['max_cluster_size'])
                
                # 随机选择植被类型
                veg_type = random.choice(veg_types)
                
                # 在集群中心周围生成植被
                for _ in range(cluster_size):
                    if self._check_max_instances():
                        break
                        
                    # 在集群半径内随机生成位置
                    angle = random.uniform(0, 2 * math.pi)
                    radius = random.uniform(0, self.spatial_parameters['cluster_radius'])
                    x = center_x + radius * math.cos(angle)
                    z = center_z + radius * math.sin(angle)
                    
                    # 检查是否在生成区域内
                    if min_x <= x <= max_x and min_y <= z <= max_y:
                        instance_id = self.plugin.vegetation_manager.create_vegetation_instance(
                            veg_type, (x, 0.0, z)
                        )
                        
                        if instance_id >= 0:
                            self.spawn_stats['spawned_by_type'][veg_type] += 1
                            spawned_count += 1
                            
            return spawned_count
            
        except Exception as e:
            print(f"✗ 聚集植被生成失败: {e}")
            return 0
            
    def _spawn_gradient(self, area: Tuple[Tuple[float, float], Tuple[float, float]], density: float) -> int:
        """
        梯度生成植被
        
        Args:
            area: 生成区域
            density: 植被密度
            
        Returns:
            生成的植被实例数量
        """
        try:
            # 简化实现，实际中会根据环境梯度生成
            return self._spawn_random(area, density)
            
        except Exception as e:
            print(f"✗ 梯度植被生成失败: {e}")
            return 0
            
    def _spawn_competitive(self, area: Tuple[Tuple[float, float], Tuple[float, float]], density: float) -> int:
        """
        竞争生成植被
        
        Args:
            area: 生成区域
            density: 植被密度
            
        Returns:
            生成的植被实例数量
        """
        try:
            # 简化实现，实际中会考虑植物间竞争关系
            return self._spawn_clustered(area, density)
            
        except Exception as e:
            print(f"✗ 竞争植被生成失败: {e}")
            return 0
            
    def _spawn_environmental(self, area: Tuple[Tuple[float, float], Tuple[float, float]], density: float) -> int:
        """
        环境适应生成植被
        
        Args:
            area: 生成区域
            density: 植被密度
            
        Returns:
            生成的植被实例数量
        """
        try:
            (min_x, min_y), (max_x, max_y) = area
            area_size = (max_x - min_x) * (max_y - min_y)
            target_count = int(area_size * density * 0.1)
            
            spawned_count = 0
            if not self.plugin.vegetation_manager:
                return 0
                
            # 获取环境因子
            environment_factors = self.plugin.vegetation_manager.get_environment_factors()
            
            for _ in range(target_count):
                if self._check_max_instances():
                    break
                    
                # 根据环境因子选择最适宜的植被类型
                veg_type = self._select_suitable_vegetation(environment_factors)
                
                # 随机生成位置
                x = random.uniform(min_x, max_x)
                z = random.uniform(min_y, max_y)
                
                # 创建植被实例
                instance_id = self.plugin.vegetation_manager.create_vegetation_instance(
                    veg_type, (x, 0.0, z)
                )
                
                if instance_id >= 0:
                    self.spawn_stats['spawned_by_type'][veg_type] += 1
                    spawned_count += 1
                    
            return spawned_count
            
        except Exception as e:
            print(f"✗ 环境适应植被生成失败: {e}")
            return 0
            
    def _select_suitable_vegetation(self, environment_factors: Dict[str, float]) -> str:
        """
        根据环境因子选择最适宜的植被类型
        
        Args:
            environment_factors: 环境因子字典
            
        Returns:
            最适宜的植被类型
        """
        try:
            if not self.plugin.vegetation_manager:
                veg_types = list(self.ecological_preferences.keys())
                return random.choice(veg_types)
                
            veg_types = self.plugin.vegetation_manager.get_vegetation_types()
            if not veg_types:
                return 'grass'
                
            # 计算每种植被类型的适宜性评分
            suitability_scores = {}
            
            for veg_type in veg_types:
                if veg_type in self.ecological_preferences:
                    preferences = self.ecological_preferences[veg_type]
                    score = self._calculate_suitability_score(environment_factors, preferences)
                    suitability_scores[veg_type] = score
                    
            # 选择适宜性评分最高的植被类型
            if suitability_scores:
                return max(suitability_scores, key=suitability_scores.get)
            else:
                return random.choice(veg_types)
                
        except Exception as e:
            print(f"✗ 适宜植被选择失败: {e}")
            veg_types = self.plugin.vegetation_manager.get_vegetation_types() if self.plugin.vegetation_manager else ['grass']
            return random.choice(veg_types)
            
    def _calculate_suitability_score(self, environment_factors: Dict[str, float], 
                                   preferences: Dict[str, Tuple[float, float]]) -> float:
        """
        计算植被类型的环境适宜性评分
        
        Args:
            environment_factors: 环境因子
            preferences: 植被偏好
            
        Returns:
            适宜性评分 (0.0-1.0)
        """
        try:
            total_score = 0.0
            weight_sum = 0.0
            
            for factor, weight in self.environment_weights.items():
                if factor in environment_factors and f"{factor}_preference" in preferences:
                    current_value = environment_factors[factor]
                    preferred_range = preferences[f"{factor}_preference"]
                    
                    # 计算因子适宜性
                    factor_suitability = self._calculate_factor_suitability(
                        current_value, preferred_range
                    )
                    
                    total_score += factor_suitability * weight
                    weight_sum += weight
                    
            if weight_sum > 0:
                return total_score / weight_sum
            return 0.5
            
        except Exception as e:
            print(f"✗ 适宜性评分计算失败: {e}")
            return 0.5
            
    def _calculate_factor_suitability(self, current_value: float, preferred_range: Tuple[float, float]) -> float:
        """
        计算单个环境因子的适宜性
        
        Args:
            current_value: 当前值
            preferred_range: 偏好范围
            
        Returns:
            适宜性评分 (0.0-1.0)
        """
        try:
            min_val, max_val = preferred_range
            
            if min_val <= current_value <= max_val:
                return 1.0
            elif current_value < min_val:
                if min_val > 0:
                    return max(0.0, 1.0 - (min_val - current_value) / min_val)
                return 0.0
            else:  # current_value > max_val
                if max_val > 0:
                    return max(0.0, 1.0 - (current_value - max_val) / max_val)
                return 0.0
                
        except Exception as e:
            print(f"✗ 因子适宜性计算失败: {e}")
            return 0.5
            
    def _check_max_instances(self) -> bool:
        """
        检查是否达到最大实例数限制
        
        Returns:
            是否达到限制
        """
        try:
            if self.plugin.vegetation_manager:
                current_count = self.plugin.vegetation_manager.get_stats()['total_vegetation']
                return current_count >= self.spawn_config['max_instances']
            return False
            
        except Exception as e:
            print(f"✗ 实例数检查失败: {e}")
            return False
            
    def _record_spawn_event(self, algorithm: str, count: int, area: Tuple[Tuple[float, float], Tuple[float, float]]):
        """
        记录生成事件
        
        Args:
            algorithm: 算法名称
            count: 生成数量
            area: 生成区域
        """
        try:
            event_record = {
                'timestamp': time.time(),
                'algorithm': algorithm,
                'count': count,
                'area': area
            }
            
            self.spawn_history.append(event_record)
            
            # 限制历史记录大小
            if len(self.spawn_history) > self.max_history_size:
                self.spawn_history.pop(0)
                
        except Exception as e:
            print(f"✗ 生成事件记录失败: {e}")
            
    def get_distribution_algorithms(self) -> Dict[str, Dict[str, str]]:
        """
        获取可用的分布算法
        
        Returns:
            分布算法字典
        """
        return self.distribution_algorithms.copy()
        
    def set_spawn_config(self, config: Dict[str, Any]):
        """
        设置生成配置
        
        Args:
            config: 配置字典
        """
        try:
            self.spawn_config.update(config)
            print(f"✓ 生成配置已更新: {self.spawn_config}")
        except Exception as e:
            print(f"✗ 生成配置更新失败: {e}")
            
    def get_spawn_config(self) -> Dict[str, Any]:
        """
        获取生成配置
        
        Returns:
            生成配置字典
        """
        return self.spawn_config.copy()
        
    def set_environment_weights(self, weights: Dict[str, float]):
        """
        设置环境因子权重
        
        Args:
            weights: 权重字典
        """
        try:
            self.environment_weights.update(weights)
            print(f"✓ 环境因子权重已更新: {self.environment_weights}")
        except Exception as e:
            print(f"✗ 环境因子权重更新失败: {e}")
            
    def get_environment_weights(self) -> Dict[str, float]:
        """
        获取环境因子权重
        
        Returns:
            环境因子权重字典
        """
        return self.environment_weights.copy()
        
    def set_spatial_parameters(self, parameters: Dict[str, float]):
        """
        设置空间分布参数
        
        Args:
            parameters: 参数字典
        """
        try:
            self.spatial_parameters.update(parameters)
            print(f"✓ 空间分布参数已更新: {self.spatial_parameters}")
        except Exception as e:
            print(f"✗ 空间分布参数更新失败: {e}")
            
    def get_spatial_parameters(self) -> Dict[str, float]:
        """
        获取空间分布参数
        
        Returns:
            空间分布参数字典
        """
        return self.spatial_parameters.copy()
        
    def get_spawn_stats(self) -> Dict[str, Any]:
        """
        获取生成统计信息
        
        Returns:
            生成统计信息字典
        """
        return self.spawn_stats.copy()
        
    def reset_spawn_stats(self):
        """重置生成统计信息"""
        try:
            self.spawn_stats = {
                'total_spawned': 0,
                'spawned_by_type': {},
                'failed_spawns': 0,
                'last_spawn_time': 0.0
            }
            
            if self.plugin.vegetation_manager:
                veg_types = self.plugin.vegetation_manager.get_vegetation_types()
                self.spawn_stats['spawned_by_type'] = {vt: 0 for vt in veg_types}
                
            print("✓ 植被生成统计信息已重置")
        except Exception as e:
            print(f"✗ 植被生成统计信息重置失败: {e}")
            
    def get_spawn_history(self) -> List[Dict[str, Any]]:
        """
        获取生成历史
        
        Returns:
            生成历史列表
        """
        return self.spawn_history.copy()
        
    def clear_spawn_history(self):
        """清空生成历史"""
        try:
            self.spawn_history.clear()
            print("✓ 生成历史已清空")
        except Exception as e:
            print(f"✗ 生成历史清空失败: {e}")
            
    def regenerate_vegetation(self, clear_existing: bool = True) -> int:
        """
        重新生成植被
        
        Args:
            clear_existing: 是否清除现有植被
            
        Returns:
            生成的植被实例数量
        """
        try:
            if clear_existing and self.plugin.vegetation_manager:
                # 清除现有植被实例
                instances = self.plugin.vegetation_manager.get_all_vegetation_instances()
                for instance_id in list(instances.keys()):
                    self.plugin.vegetation_manager.remove_vegetation_instance(instance_id)
                    
                # 重置统计信息
                self.reset_spawn_stats()
                
            # 使用当前配置重新生成植被
            spawned_count = self.spawn_vegetation()
            print(f"✓ 植被重新生成完成: {spawned_count} 个实例")
            return spawned_count
            
        except Exception as e:
            print(f"✗ 植被重新生成失败: {e}")
            return 0