"""
天气管理器
负责管理天气系统和天气变化
"""

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

class WeatherManager:
    """
    天气管理器
    负责管理天气系统、天气变化和天气过渡效果
    """
    
    def __init__(self, plugin):
        """
        初始化天气管理器
        
        Args:
            plugin: 天气和季节系统插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 天气类型定义
        self.weather_types = {
            'clear': {
                'name': '晴朗',
                'description': '晴朗无云的天气',
                'temperature_modifier': 0.0,
                'humidity_modifier': -10.0,
                'wind_speed': 2.0,
                'visibility': 1.0,
                'precipitation': 0.0,
                'cloud_cover': 0.1,
                'light_intensity': 1.0,
                'particle_effect': None,
                'audio_effect': None,
                'transition_time': 300.0,  # 过渡时间(秒)
                'probability_weight': 30.0  # 概率权重
            },
            'cloudy': {
                'name': '多云',
                'description': '多云天气，阳光时隐时现',
                'temperature_modifier': -2.0,
                'humidity_modifier': 5.0,
                'wind_speed': 4.0,
                'visibility': 0.9,
                'precipitation': 0.0,
                'cloud_cover': 0.7,
                'light_intensity': 0.7,
                'particle_effect': 'light_fog',
                'audio_effect': 'wind',
                'transition_time': 600.0,
                'probability_weight': 20.0
            },
            'rain': {
                'name': '下雨',
                'description': '降雨天气',
                'temperature_modifier': -3.0,
                'humidity_modifier': 20.0,
                'wind_speed': 6.0,
                'visibility': 0.7,
                'precipitation': 1.0,
                'cloud_cover': 0.9,
                'light_intensity': 0.5,
                'particle_effect': 'rain',
                'audio_effect': 'rain',
                'transition_time': 120.0,
                'probability_weight': 15.0
            },
            'storm': {
                'name': '暴风雨',
                'description': '强烈的雷暴天气',
                'temperature_modifier': -5.0,
                'humidity_modifier': 30.0,
                'wind_speed': 15.0,
                'visibility': 0.4,
                'precipitation': 1.0,
                'cloud_cover': 1.0,
                'light_intensity': 0.3,
                'particle_effect': 'storm',
                'audio_effect': 'thunderstorm',
                'transition_time': 90.0,
                'probability_weight': 5.0
            },
            'snow': {
                'name': '下雪',
                'description': '降雪天气',
                'temperature_modifier': -10.0,
                'humidity_modifier': 15.0,
                'wind_speed': 5.0,
                'visibility': 0.6,
                'precipitation': 0.8,
                'cloud_cover': 0.8,
                'light_intensity': 0.6,
                'particle_effect': 'snow',
                'audio_effect': 'wind',
                'transition_time': 180.0,
                'probability_weight': 8.0
            },
            'fog': {
                'name': '雾天',
                'description': '大雾天气，能见度低',
                'temperature_modifier': -1.0,
                'humidity_modifier': 25.0,
                'wind_speed': 1.0,
                'visibility': 0.3,
                'precipitation': 0.0,
                'cloud_cover': 0.5,
                'light_intensity': 0.4,
                'particle_effect': 'heavy_fog',
                'audio_effect': 'wind',
                'transition_time': 300.0,
                'probability_weight': 7.0
            },
            'windy': {
                'name': '大风',
                'description': '强风天气',
                'temperature_modifier': -2.0,
                'humidity_modifier': 0.0,
                'wind_speed': 12.0,
                'visibility': 0.8,
                'precipitation': 0.0,
                'cloud_cover': 0.4,
                'light_intensity': 0.9,
                'particle_effect': 'wind_debris',
                'audio_effect': 'strong_wind',
                'transition_time': 150.0,
                'probability_weight': 10.0
            },
            'hail': {
                'name': '冰雹',
                'description': '降冰雹天气',
                'temperature_modifier': -4.0,
                'humidity_modifier': 20.0,
                'wind_speed': 8.0,
                'visibility': 0.5,
                'precipitation': 1.0,
                'cloud_cover': 0.9,
                'light_intensity': 0.4,
                'particle_effect': 'hail',
                'audio_effect': 'hail',
                'transition_time': 120.0,
                'probability_weight': 3.0
            }
        }
        
        # 当前天气状态
        self.current_weather = 'clear'
        self.target_weather = 'clear'
        self.weather_transition_progress = 0.0
        self.weather_transition_active = False
        
        # 天气时间配置
        self.weather_duration_min = 300.0  # 最短天气持续时间(秒)
        self.weather_duration_max = 3600.0  # 最长天气持续时间(秒)
        self.current_weather_time = 0.0  # 当前天气持续时间(秒)
        self.target_weather_duration = 0.0  # 目标天气持续时间(秒)
        
        # 天气变化配置
        self.weather_change_enabled = True
        self.weather_change_probability = 0.01  # 每秒天气变化概率
        self.season_influence_enabled = True  # 季节对天气的影响
        
        # 天气物理参数
        self.base_temperature = 20.0  # 基础温度(摄氏度)
        self.base_humidity = 50.0     # 基础湿度(%)
        self.base_wind_speed = 3.0    # 基础风速(m/s)
        self.base_visibility = 1.0    # 基础能见度(0-1)
        
        # 统计信息
        self.stats = {
            'weather_changes': 0,
            'transitions_completed': 0,
            'total_weather_time': 0.0
        }
        
        # 编辑器相关
        self.is_being_edited = False
        self.edit_timestamp = 0
        self.edit_history = []
        self.max_history_size = 100
        
        print("✓ 天气管理器已创建")
        
    def initialize(self) -> bool:
        """
        初始化天气管理器
        
        Returns:
            是否初始化成功
        """
        try:
            # 设置初始天气持续时间
            self.target_weather_duration = random.uniform(
                self.weather_duration_min, 
                self.weather_duration_max
            )
            
            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: 时间增量
        """
        try:
            if not self.enabled:
                return
                
            # 更新天气时间
            self._update_weather_time(dt)
            
            # 更新天气过渡
            if self.weather_transition_active:
                self._update_weather_transition(dt)
            else:
                # 检查是否需要自动变化天气
                self._check_auto_weather_change(dt)
                
        except Exception as e:
            print(f"✗ 天气管理器更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _update_weather_time(self, dt: float):
        """
        更新天气时间
        
        Args:
            dt: 时间增量
        """
        try:
            self.current_weather_time += dt
            self.stats['total_weather_time'] += dt
            
            # 检查是否达到目标持续时间
            if self.current_weather_time >= self.target_weather_duration and not self.weather_transition_active:
                self._change_weather_randomly()
                
        except Exception as e:
            print(f"✗ 天气时间更新失败: {e}")
            
    def _change_weather_randomly(self):
        """随机改变天气"""
        try:
            # 获取可能的天气类型
            possible_weathers = self._get_possible_weathers()
            
            if not possible_weathers:
                return
                
            # 根据权重选择天气
            weights = [self.weather_types[w]['probability_weight'] for w in possible_weathers]
            target_weather = random.choices(possible_weathers, weights=weights)[0]
            
            # 设置为目标天气
            self.set_target_weather(target_weather)
            
        except Exception as e:
            print(f"✗ 随机天气变化失败: {e}")
            
    def _get_possible_weathers(self) -> List[str]:
        """
        获取可能的天气类型（根据季节影响）
        
        Returns:
            可能的天气类型列表
        """
        try:
            # 基本所有天气都可能
            possible_weathers = list(self.weather_types.keys())
            
            # 如果启用了季节影响，则根据当前季节调整权重
            if self.season_influence_enabled and self.plugin.season_manager:
                current_season = self.plugin.season_manager.get_current_season()
                
                # 根据季节过滤不太可能的天气
                if current_season == 'summer':
                    # 夏季不太可能下雪
                    if 'snow' in possible_weathers:
                        possible_weathers.remove('snow')
                elif current_season == 'winter':
                    # 冬季可能下雪
                    pass
                elif current_season == 'spring':
                    # 春季可能下雨
                    pass
                elif current_season == 'autumn':
                    # 秋季可能下雨和起雾
                    pass
                    
            return possible_weathers
            
        except Exception as e:
            print(f"✗ 可能天气获取失败: {e}")
            return list(self.weather_types.keys())
            
    def _check_auto_weather_change(self, dt: float):
        """
        检查自动天气变化
        
        Args:
            dt: 时间增量
        """
        try:
            if not self.weather_change_enabled:
                return
                
            # 计算变化概率（考虑时间增量）
            change_probability = 1 - math.pow(1 - self.weather_change_probability, dt)
            
            # 检查是否发生天气变化
            if random.random() < change_probability:
                self._change_weather_randomly()
                
        except Exception as e:
            print(f"✗ 自动天气变化检查失败: {e}")
            
    def set_target_weather(self, weather: str):
        """
        设置目标天气
        
        Args:
            weather: 天气类型
        """
        try:
            if weather not in self.weather_types:
                print(f"✗ 无效的天气类型: {weather}")
                return
                
            if weather == self.current_weather:
                return  # 天气未变化
                
            self.target_weather = weather
            self.start_weather_transition()
            
        except Exception as e:
            print(f"✗ 目标天气设置失败: {e}")
            
    def start_weather_transition(self):
        """开始天气过渡"""
        try:
            if self.current_weather == self.target_weather:
                return
                
            self.weather_transition_active = True
            self.weather_transition_progress = 0.0
            
            # 设置新的目标持续时间
            self.target_weather_duration = random.uniform(
                self.weather_duration_min, 
                self.weather_duration_max
            )
            self.current_weather_time = 0.0
            
            print(f"✓ 开始天气过渡: {self.weather_types[self.current_weather]['name']} -> {self.weather_types[self.target_weather]['name']}")
            
        except Exception as e:
            print(f"✗ 天气过渡启动失败: {e}")
            
    def _update_weather_transition(self, dt: float):
        """
        更新天气过渡
        
        Args:
            dt: 时间增量
        """
        try:
            if not self.weather_transition_active:
                return
                
            # 获取过渡时间
            transition_time = self.weather_types[self.target_weather]['transition_time']
            
            # 计算进度增量
            if transition_time > 0:
                progress_delta = dt / transition_time
                self.weather_transition_progress += progress_delta
                
                # 检查过渡是否完成
                if self.weather_transition_progress >= 1.0:
                    self._complete_weather_transition()
                    
        except Exception as e:
            print(f"✗ 天气过渡更新失败: {e}")
            
    def _complete_weather_transition(self):
        """完成天气过渡"""
        try:
            # 更新当前天气
            self.current_weather = self.target_weather
            
            # 重置过渡状态
            self.weather_transition_active = False
            self.weather_transition_progress = 0.0
            
            # 更新统计信息
            self.stats['weather_changes'] += 1
            self.stats['transitions_completed'] += 1
            
            print(f"✓ 天气过渡完成: 现在是{self.weather_types[self.current_weather]['name']}")
            
            # 触发天气变化事件
            self._trigger_weather_change_event()
            
        except Exception as e:
            print(f"✗ 天气过渡完成失败: {e}")
            
    def _trigger_weather_change_event(self):
        """触发天气变化事件"""
        try:
            # 在实际实现中，这里会触发一个事件通知其他系统天气已变化
            pass
        except Exception as e:
            print(f"✗ 天气变化事件触发失败: {e}")
            
    def set_current_weather(self, weather: str):
        """
        立即设置当前天气（无过渡）
        
        Args:
            weather: 天气类型
        """
        try:
            if weather not in self.weather_types:
                print(f"✗ 无效的天气类型: {weather}")
                return
                
            self.current_weather = weather
            self.target_weather = weather
            self.weather_transition_active = False
            self.weather_transition_progress = 0.0
            
            # 设置新的目标持续时间
            self.target_weather_duration = random.uniform(
                self.weather_duration_min, 
                self.weather_duration_max
            )
            self.current_weather_time = 0.0
            
            print(f"✓ 当前天气设置为: {self.weather_types[weather]['name']}")
            
        except Exception as e:
            print(f"✗ 当前天气设置失败: {e}")
            
    def get_current_weather(self) -> str:
        """
        获取当前天气
        
        Returns:
            当前天气类型
        """
        return self.current_weather
        
    def get_weather_info(self, weather: str = None) -> Optional[Dict[str, Any]]:
        """
        获取天气信息
        
        Args:
            weather: 天气类型（如果为None，则返回当前天气信息）
            
        Returns:
            天气信息字典或None
        """
        try:
            if weather is None:
                weather = self.current_weather
                
            if weather not in self.weather_types:
                return None
                
            return self.weather_types[weather].copy()
            
        except Exception as e:
            print(f"✗ 天气信息获取失败: {e}")
            return None
            
    def get_interpolated_weather_params(self) -> Dict[str, Any]:
        """
        获取插值后的天气参数（考虑天气过渡）
        
        Returns:
            插值后的天气参数字典
        """
        try:
            if not self.weather_transition_active or self.weather_transition_progress <= 0.0:
                # 没有过渡，返回当前天气参数
                return self.weather_types[self.current_weather].copy()
                
            if self.weather_transition_progress >= 1.0:
                # 过渡完成，返回目标天气参数
                return self.weather_types[self.target_weather].copy()
                
            # 进行插值计算
            current_params = self.weather_types[self.current_weather]
            target_params = self.weather_types[self.target_weather]
            
            interpolated_params = {}
            
            # 对数值参数进行线性插值
            numeric_params = [
                'temperature_modifier', 'humidity_modifier', 'wind_speed', 
                'visibility', 'precipitation', 'cloud_cover', 'light_intensity'
            ]
            
            for param in numeric_params:
                current_value = current_params[param]
                target_value = target_params[param]
                interpolated_value = current_value + (target_value - current_value) * self.weather_transition_progress
                interpolated_params[param] = interpolated_value
                
            # 复制非数值参数（使用目标天气的参数）
            interpolated_params['name'] = f"{current_params['name']} → {target_params['name']}"
            interpolated_params['description'] = f"过渡天气 ({self.weather_transition_progress*100:.1f}%)"
            interpolated_params['particle_effect'] = target_params['particle_effect']
            interpolated_params['audio_effect'] = target_params['audio_effect']
            interpolated_params['transition_time'] = target_params['transition_time']
            interpolated_params['probability_weight'] = target_params['probability_weight']
            
            return interpolated_params
            
        except Exception as e:
            print(f"✗ 插值天气参数获取失败: {e}")
            return self.weather_types[self.current_weather].copy()
            
    def get_weather_transition_progress(self) -> float:
        """
        获取天气过渡进度
        
        Returns:
            过渡进度 (0-1)
        """
        return self.weather_transition_progress
        
    def is_transition_active(self) -> bool:
        """
        检查是否正在进行天气过渡
        
        Returns:
            是否正在进行天气过渡
        """
        return self.weather_transition_active
        
    def get_base_environment_params(self) -> Dict[str, float]:
        """
        获取基础环境参数
        
        Returns:
            基础环境参数字典
        """
        return {
            'temperature': self.base_temperature,
            'humidity': self.base_humidity,
            'wind_speed': self.base_wind_speed,
            'visibility': self.base_visibility
        }
        
    def set_base_temperature(self, temperature: float):
        """
        设置基础温度
        
        Args:
            temperature: 温度值(摄氏度)
        """
        self.base_temperature = temperature
        self.is_being_edited = True
        self.edit_timestamp = time.time()
        print(f"✓ 基础温度设置为: {temperature}°C")
        
    def set_base_humidity(self, humidity: float):
        """
        设置基础湿度
        
        Args:
            humidity: 湿度值(%)
        """
        self.base_humidity = max(0.0, min(100.0, humidity))
        self.is_being_edited = True
        self.edit_timestamp = time.time()
        print(f"✓ 基础湿度设置为: {humidity}%")
        
    def set_base_wind_speed(self, wind_speed: float):
        """
        设置基础风速
        
        Args:
            wind_speed: 风速(m/s)
        """
        self.base_wind_speed = max(0.0, wind_speed)
        self.is_being_edited = True
        self.edit_timestamp = time.time()
        print(f"✓ 基础风速设置为: {wind_speed} m/s")
        
    def set_base_visibility(self, visibility: float):
        """
        设置基础能见度
        
        Args:
            visibility: 能见度(0-1)
        """
        self.base_visibility = max(0.0, min(1.0, visibility))
        self.is_being_edited = True
        self.edit_timestamp = time.time()
        print(f"✓ 基础能见度设置为: {visibility}")
        
    def _save_edit_history(self):
        """保存编辑历史"""
        try:
            # 创建当前状态快照
            snapshot = {
                'timestamp': time.time(),
                'base_temperature': self.base_temperature,
                'base_humidity': self.base_humidity,
                'base_wind_speed': self.base_wind_speed,
                'base_visibility': self.base_visibility,
                'current_weather': self.current_weather,
                'target_weather': self.target_weather
            }
            
            # 添加到历史记录
            self.edit_history.append(snapshot)
            
            # 限制历史记录大小
            if len(self.edit_history) > self.max_history_size:
                self.edit_history.pop(0)
                
        except Exception as e:
            print(f"✗ 编辑历史保存失败: {e}")
            
    def undo_edit(self) -> bool:
        """
        撤销编辑
        
        Returns:
            是否撤销成功
        """
        try:
            if not self.edit_history:
                print("✗ 没有可撤销的编辑")
                return False
                
            # 恢复到上一个状态
            last_state = self.edit_history.pop()
            
            # 恢复参数
            self.base_temperature = last_state['base_temperature']
            self.base_humidity = last_state['base_humidity']
            self.base_wind_speed = last_state['base_wind_speed']
            self.base_visibility = last_state['base_visibility']
            self.current_weather = last_state['current_weather']
            self.target_weather = last_state['target_weather']
            
            print("✓ 编辑已撤销")
            return True
            
        except Exception as e:
            print(f"✗ 编辑撤销失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def get_edit_history_size(self) -> int:
        """
        获取编辑历史大小
        
        Returns:
            编辑历史记录数量
        """
        return len(self.edit_history)
        
    def clear_edit_history(self):
        """清空编辑历史"""
        try:
            self.edit_history.clear()
            print("✓ 编辑历史已清空")
        except Exception as e:
            print(f"✗ 编辑历史清空失败: {e}")
            
    def get_current_state_info(self) -> Dict[str, Any]:
        """
        获取当前状态信息
        
        Returns:
            当前状态信息字典
        """
        try:
            return {
                'current_weather': self.current_weather,
                'target_weather': self.target_weather,
                'base_temperature': self.base_temperature,
                'base_humidity': self.base_humidity,
                'base_wind_speed': self.base_wind_speed,
                'base_visibility': self.base_visibility,
                'is_being_edited': self.is_being_edited,
                'edit_timestamp': self.edit_timestamp,
                'edit_history_size': len(self.edit_history)
            }
        except Exception as e:
            print(f"✗ 当前状态信息获取失败: {e}")
            return {}
            
    def get_current_environment_params(self) -> Dict[str, float]:
        """
        获取当前环境参数（结合季节和天气影响）
        
        Returns:
            当前环境参数字典
        """
        try:
            # 获取基础参数
            params = self.get_base_environment_params()
            
            # 应用季节影响
            if self.plugin.season_manager:
                season_params = self.plugin.season_manager.get_interpolated_season_params()
                params['temperature'] += season_params.get('temperature', 0.0)
                params['humidity'] += season_params.get('humidity', 0.0)
                
            # 应用天气影响
            weather_params = self.get_interpolated_weather_params()
            params['temperature'] += weather_params.get('temperature_modifier', 0.0)
            params['humidity'] += weather_params.get('humidity_modifier', 0.0)
            params['wind_speed'] = weather_params.get('wind_speed', params['wind_speed'])
            params['visibility'] = weather_params.get('visibility', params['visibility'])
            
            return params
            
        except Exception as e:
            print(f"✗ 当前环境参数获取失败: {e}")
            return self.get_base_environment_params()
            
    def get_weather_list(self) -> List[str]:
        """
        获取所有天气类型列表
        
        Returns:
            天气类型列表
        """
        return list(self.weather_types.keys())
        
    def get_weather_name(self, weather: str) -> str:
        """
        获取天气显示名称
        
        Args:
            weather: 天气类型
            
        Returns:
            天气显示名称
        """
        if weather in self.weather_types:
            return self.weather_types[weather]['name']
        return weather
        
    def enable_weather_change(self, enabled: bool):
        """
        启用/禁用天气变化
        
        Args:
            enabled: 是否启用天气变化
        """
        self.weather_change_enabled = enabled
        print(f"✓ 天气变化{'已启用' if enabled else '已禁用'}")
        
    def set_weather_change_probability(self, probability: float):
        """
        设置天气变化概率
        
        Args:
            probability: 每秒天气变化概率
        """
        self.weather_change_probability = max(0.0, min(1.0, probability))
        print(f"✓ 天气变化概率设置为: {probability}")
        
    def get_stats(self) -> Dict[str, Any]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        return self.stats.copy()
        
    def reset_stats(self):
        """重置统计信息"""
        self.stats = {
            'weather_changes': 0,
            'transitions_completed': 0,
            'total_weather_time': 0.0
        }
        print("✓ 天气管理器统计信息已重置")