"""
天气和季节系统工具类
提供各种实用工具函数和辅助方法
"""

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

class WeatherUtils:
    """
    天气和季节系统工具类
    提供各种实用工具函数和辅助方法
    """
    
    def __init__(self, plugin):
        """
        初始化工具类
        
        Args:
            plugin: 天气和季节系统插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 配置文件路径
        self.config_directory = "config/weather"
        self.preset_directory = "presets/weather"
        
        # 数据缓存
        self.data_cache = {}
        self.cache_expiry = 300  # 缓存过期时间(秒)
        
        # 日志配置
        self.log_enabled = True
        self.log_level = "INFO"
        self.log_file = "weather_system.log"
        
        # 性能监控
        self.performance_stats = {
            'function_calls': {},
            'execution_times': {},
            'memory_usage': 0.0
        }
        
        print("✓ 天气和季节系统工具类已创建")
        
    def initialize(self) -> bool:
        """
        初始化工具类
        
        Returns:
            是否初始化成功
        """
        try:
            # 创建必要的目录
            directories = [self.config_directory, self.preset_directory]
            for directory in directories:
                if not os.path.exists(directory):
                    os.makedirs(directory)
                    
            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._save_cache()
            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._cleanup_expired_cache()
            
        except Exception as e:
            print(f"✗ 天气和季节系统工具类更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _cleanup_expired_cache(self):
        """清理过期缓存"""
        try:
            current_time = time.time()
            expired_keys = []
            
            for key, (timestamp, _) in self.data_cache.items():
                if current_time - timestamp > self.cache_expiry:
                    expired_keys.append(key)
                    
            for key in expired_keys:
                del self.data_cache[key]
                
        except Exception as e:
            if self.log_enabled and self.log_level == "DEBUG":
                print(f"✗ 缓存清理失败: {e}")
                
    def _save_cache(self):
        """保存缓存到文件"""
        try:
            cache_file = os.path.join(self.config_directory, "cache.json")
            cache_data = {}
            
            # 只保存可序列化的数据
            for key, (timestamp, value) in self.data_cache.items():
                try:
                    json.dumps(value)  # 测试是否可序列化
                    cache_data[key] = (timestamp, value)
                except (TypeError, ValueError):
                    continue  # 跳过不可序列化的数据
                    
            with open(cache_file, 'w', encoding='utf-8') as f:
                json.dump(cache_data, f, ensure_ascii=False, indent=2)
                
        except Exception as e:
            if self.log_enabled and self.log_level == "DEBUG":
                print(f"✗ 缓存保存失败: {e}")
                
    def load_cache(self):
        """从文件加载缓存"""
        try:
            cache_file = os.path.join(self.config_directory, "cache.json")
            if os.path.exists(cache_file):
                with open(cache_file, 'r', encoding='utf-8') as f:
                    cache_data = json.load(f)
                    self.data_cache.update(cache_data)
                    
        except Exception as e:
            if self.log_enabled and self.log_level == "DEBUG":
                print(f"✗ 缓存加载失败: {e}")
                
    def log_message(self, level: str, message: str):
        """
        记录日志消息
        
        Args:
            level: 日志级别
            message: 日志消息
        """
        try:
            if not self.log_enabled:
                return
                
            levels = ["DEBUG", "INFO", "WARNING", "ERROR"]
            if levels.index(level) < levels.index(self.log_level):
                return
                
            timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
            log_entry = f"[{timestamp}] {level}: {message}\n"
            
            print(log_entry.strip())
            
            # 写入日志文件
            try:
                with open(self.log_file, 'a', encoding='utf-8') as f:
                    f.write(log_entry)
            except Exception:
                pass  # 忽略文件写入错误
                
        except Exception as e:
            pass  # 忽略日志记录错误
            
    def performance_monitor(self, func_name: str):
        """
        性能监控装饰器
        
        Args:
            func_name: 函数名称
        """
        def decorator(func):
            def wrapper(*args, **kwargs):
                start_time = time.time()
                
                try:
                    result = func(*args, **kwargs)
                    end_time = time.time()
                    
                    # 记录执行时间
                    execution_time = end_time - start_time
                    if func_name not in self.performance_stats['function_calls']:
                        self.performance_stats['function_calls'][func_name] = 0
                        self.performance_stats['execution_times'][func_name] = 0.0
                        
                    self.performance_stats['function_calls'][func_name] += 1
                    self.performance_stats['execution_times'][func_name] += execution_time
                    
                    return result
                    
                except Exception as e:
                    end_time = time.time()
                    execution_time = end_time - start_time
                    
                    self.log_message("ERROR", f"函数 {func_name} 执行失败: {e}")
                    raise
                    
            return wrapper
        return decorator
        
    def get_weather_icon(self, weather_type: str) -> str:
        """
        获取天气图标
        
        Args:
            weather_type: 天气类型
            
        Returns:
            天气图标字符
        """
        icons = {
            'clear': '☀️',
            'cloudy': '☁️',
            'rain': '🌧️',
            'storm': '⛈️',
            'snow': '❄️',
            'fog': '🌫️',
            'windy': '💨',
            'hail': '🌨️'
        }
        
        return icons.get(weather_type, '🌈')
        
    def get_season_icon(self, season: str) -> str:
        """
        获取季节图标
        
        Args:
            season: 季节名称
            
        Returns:
            季节图标字符
        """
        icons = {
            'spring': '🌸',
            'summer': '☀️',
            'autumn': '🍂',
            'winter': '❄️'
        }
        
        return icons.get(season, '🌍')
        
    def temperature_to_string(self, temperature: float) -> str:
        """
        将温度转换为字符串
        
        Args:
            temperature: 温度值(摄氏度)
            
        Returns:
            温度字符串
        """
        return f"{temperature:.1f}°C"
        
    def wind_speed_to_string(self, wind_speed: float) -> str:
        """
        将风速转换为字符串
        
        Args:
            wind_speed: 风速(m/s)
            
        Returns:
            风速字符串
        """
        return f"{wind_speed:.1f} m/s"
        
    def precipitation_to_string(self, precipitation: float) -> str:
        """
        将降水强度转换为字符串
        
        Args:
            precipitation: 降水强度(0-1)
            
        Returns:
            降水强度字符串
        """
        if precipitation <= 0:
            return "无降水"
        elif precipitation < 0.3:
            return "小雨"
        elif precipitation < 0.6:
            return "中雨"
        elif precipitation < 0.9:
            return "大雨"
        else:
            return "暴雨"
            
    def visibility_to_string(self, visibility: float) -> str:
        """
        将能见度转换为字符串
        
        Args:
            visibility: 能见度(米)
            
        Returns:
            能见度字符串
        """
        if visibility >= 5000:
            return "良好"
        elif visibility >= 1000:
            return "一般"
        elif visibility >= 500:
            return "较差"
        else:
            return "极差"
            
    def humidity_to_string(self, humidity: float) -> str:
        """
        将湿度转换为字符串
        
        Args:
            humidity: 湿度(%)
            
        Returns:
            湿度字符串
        """
        return f"{humidity:.0f}%"
        
    def pressure_to_string(self, pressure: float) -> str:
        """
        将气压转换为字符串
        
        Args:
            pressure: 气压(hPa)
            
        Returns:
            气压字符串
        """
        return f"{pressure:.1f} hPa"
        
    def uv_index_to_string(self, uv_index: float) -> str:
        """
        将UV指数转换为字符串
        
        Args:
            uv_index: UV指数
            
        Returns:
            UV指数字符串
        """
        if uv_index <= 2:
            return "低"
        elif uv_index <= 5:
            return "中等"
        elif uv_index <= 7:
            return "高"
        elif uv_index <= 10:
            return "很高"
        else:
            return "极高"
            
    def get_weather_description(self, weather_type: str) -> str:
        """
        获取天气描述
        
        Args:
            weather_type: 天气类型
            
        Returns:
            天气描述
        """
        descriptions = {
            'clear': '晴朗无云',
            'cloudy': '多云天气',
            'rain': '正在下雨',
            'storm': '雷暴天气',
            'snow': '正在下雪',
            'fog': '大雾天气',
            'windy': '风力强劲',
            'hail': '正在下冰雹'
        }
        
        return descriptions.get(weather_type, '未知天气')
        
    def get_season_description(self, season: str) -> str:
        """
        获取季节描述
        
        Args:
            season: 季节名称
            
        Returns:
            季节描述
        """
        descriptions = {
            'spring': '万物复苏的春季',
            'summer': '炎热的夏季',
            'autumn': '收获的秋季',
            'winter': '寒冷的冬季'
        }
        
        return descriptions.get(season, '未知季节')
        
    def calculate_weather_severity(self, conditions: Dict[str, Any]) -> float:
        """
        计算天气严重程度
        
        Args:
            conditions: 天气条件字典
            
        Returns:
            严重程度(0-1)
        """
        try:
            severity = 0.0
            
            # 降水影响
            precipitation = conditions.get('precipitation', 0.0)
            severity += precipitation * 0.3
            
            # 风速影响
            wind_speed = conditions.get('wind_speed', 0.0)
            severity += min(1.0, wind_speed / 20.0) * 0.2
            
            # 温度影响（极端温度）
            temperature = conditions.get('temperature', 20.0)
            if temperature > 35 or temperature < 0:
                severity += 0.2
                
            # 能见度影响
            visibility = conditions.get('visibility', 10000.0)
            severity += (1.0 - min(1.0, visibility / 10000.0)) * 0.3
            
            return min(1.0, severity)
            
        except Exception as e:
            self.log_message("ERROR", f"天气严重程度计算失败: {e}")
            return 0.0
            
    def interpolate_values(self, start_value: float, end_value: float, progress: float) -> float:
        """
        插值计算
        
        Args:
            start_value: 起始值
            end_value: 结束值
            progress: 进度(0-1)
            
        Returns:
            插值结果
        """
        return start_value + (end_value - start_value) * progress
        
    def clamp_value(self, value: float, min_value: float, max_value: float) -> float:
        """
        限制值范围
        
        Args:
            value: 值
            min_value: 最小值
            max_value: 最大值
            
        Returns:
            限制后的值
        """
        return max(min_value, min(max_value, value))
        
    def random_range(self, min_value: float, max_value: float) -> float:
        """
        生成随机范围值
        
        Args:
            min_value: 最小值
            max_value: 最大值
            
        Returns:
            随机值
        """
        return random.uniform(min_value, max_value)
        
    def normalize_vector(self, vector: List[float]) -> List[float]:
        """
        归一化向量
        
        Args:
            vector: 向量
            
        Returns:
            归一化后的向量
        """
        try:
            magnitude = math.sqrt(sum(x * x for x in vector))
            if magnitude > 0:
                return [x / magnitude for x in vector]
            return [0.0] * len(vector)
        except Exception as e:
            self.log_message("ERROR", f"向量归一化失败: {e}")
            return vector
            
    def distance_3d(self, pos1: Tuple[float, float, float], pos2: Tuple[float, float, float]) -> float:
        """
        计算3D空间距离
        
        Args:
            pos1: 位置1
            pos2: 位置2
            
        Returns:
            距离
        """
        try:
            dx = pos1[0] - pos2[0]
            dy = pos1[1] - pos2[1]
            dz = pos1[2] - pos2[2]
            return math.sqrt(dx * dx + dy * dy + dz * dz)
        except Exception as e:
            self.log_message("ERROR", f"距离计算失败: {e}")
            return 0.0
            
    def angle_between_vectors(self, v1: List[float], v2: List[float]) -> float:
        """
        计算两个向量之间的夹角
        
        Args:
            v1: 向量1
            v2: 向量2
            
        Returns:
            夹角(弧度)
        """
        try:
            dot_product = sum(a * b for a, b in zip(v1, v2))
            magnitude1 = math.sqrt(sum(a * a for a in v1))
            magnitude2 = math.sqrt(sum(b * b for b in v2))
            
            if magnitude1 > 0 and magnitude2 > 0:
                cos_angle = dot_product / (magnitude1 * magnitude2)
                cos_angle = max(-1.0, min(1.0, cos_angle))  # 限制在[-1, 1]范围内
                return math.acos(cos_angle)
            return 0.0
        except Exception as e:
            self.log_message("ERROR", f"向量夹角计算失败: {e}")
            return 0.0
            
    def save_to_json(self, data: Dict[str, Any], filename: str) -> bool:
        """
        保存数据到JSON文件
        
        Args:
            data: 数据字典
            filename: 文件名
            
        Returns:
            是否保存成功
        """
        try:
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
            return True
        except Exception as e:
            self.log_message("ERROR", f"数据保存失败: {e}")
            return False
            
    def load_from_json(self, filename: str) -> Optional[Dict[str, Any]]:
        """
        从JSON文件加载数据
        
        Args:
            filename: 文件名
            
        Returns:
            数据字典或None
        """
        try:
            if os.path.exists(filename):
                with open(filename, 'r', encoding='utf-8') as f:
                    return json.load(f)
            return None
        except Exception as e:
            self.log_message("ERROR", f"数据加载失败: {e}")
            return None
            
    def get_cache(self, key: str) -> Any:
        """
        获取缓存数据
        
        Args:
            key: 缓存键
            
        Returns:
            缓存数据或None
        """
        try:
            if key in self.data_cache:
                timestamp, value = self.data_cache[key]
                if time.time() - timestamp <= self.cache_expiry:
                    return value
                else:
                    del self.data_cache[key]
            return None
        except Exception as e:
            self.log_message("ERROR", f"缓存获取失败: {e}")
            return None
            
    def set_cache(self, key: str, value: Any):
        """
        设置缓存数据
        
        Args:
            key: 缓存键
            value: 缓存值
        """
        try:
            self.data_cache[key] = (time.time(), value)
        except Exception as e:
            self.log_message("ERROR", f"缓存设置失败: {e}")
            
    def clear_cache(self):
        """清空缓存"""
        try:
            self.data_cache.clear()
        except Exception as e:
            self.log_message("ERROR", f"缓存清空失败: {e}")
            
    def get_performance_stats(self) -> Dict[str, Any]:
        """
        获取性能统计信息
        
        Returns:
            性能统计信息字典
        """
        try:
            stats = self.performance_stats.copy()
            
            # 计算平均执行时间
            average_times = {}
            for func_name, total_time in stats['execution_times'].items():
                calls = stats['function_calls'][func_name]
                if calls > 0:
                    average_times[func_name] = total_time / calls
                    
            stats['average_times'] = average_times
            return stats
        except Exception as e:
            self.log_message("ERROR", f"性能统计获取失败: {e}")
            return {}
            
    def reset_performance_stats(self):
        """重置性能统计信息"""
        try:
            self.performance_stats = {
                'function_calls': {},
                'execution_times': {},
                'memory_usage': 0.0
            }
        except Exception as e:
            self.log_message("ERROR", f"性能统计重置失败: {e}")
            
    def format_time(self, seconds: float) -> str:
        """
        格式化时间
        
        Args:
            seconds: 秒数
            
        Returns:
            格式化的时间字符串
        """
        try:
            if seconds < 60:
                return f"{seconds:.1f}秒"
            elif seconds < 3600:
                minutes = seconds / 60
                return f"{minutes:.1f}分钟"
            else:
                hours = seconds / 3600
                return f"{hours:.1f}小时"
        except Exception as e:
            self.log_message("ERROR", f"时间格式化失败: {e}")
            return f"{seconds:.1f}秒"
            
    def generate_unique_id(self) -> str:
        """
        生成唯一ID
        
        Returns:
            唯一ID字符串
        """
        try:
            timestamp = int(time.time() * 1000000)  # 微秒时间戳
            random_part = random.randint(1000, 9999)
            return f"{timestamp}_{random_part}"
        except Exception as e:
            self.log_message("ERROR", f"唯一ID生成失败: {e}")
            return str(random.randint(10000000, 99999999))