"""
环境音频管理器
管理环境音效和区域音频效果
"""

import math
from typing import Dict, List, Any, Tuple, Optional
from panda3d.core import Vec3

class EnvironmentAudioManager:
    """
    环境音频管理器
    管理环境音效和区域音频效果
    """
    
    def __init__(self, plugin):
        """
        初始化环境音频管理器
        
        Args:
            plugin: 3D音频插件实例
        """
        self.plugin = plugin
        self.zones: Dict[str, Dict[str, Any]] = {}
        self.ambient_sounds: Dict[str, str] = {}  # 环境音效
        self.enabled = True
        self.listener_position = (0, 0, 0)
        self.stats = {
            'zones_created': 0,
            'active_zones': 0,
            'ambient_sounds': 0
        }
        
    def create_zone(self, zone_id: str, position: Tuple[float, float, float], 
                   radius: float, properties: Dict[str, Any]) -> bool:
        """
        创建环境区域
        
        Args:
            zone_id: 区域ID
            position: 位置 (x, y, z)
            radius: 半径
            properties: 区域属性
            
        Returns:
            是否创建成功
        """
        try:
            # 检查区域ID是否已存在
            if zone_id in self.zones:
                print(f"✗ 区域ID已存在: {zone_id}")
                return False
                
            # 创建区域
            zone = {
                'id': zone_id,
                'position': position,
                'radius': radius,
                'properties': properties,
                'active': True,
                'ambient_sound': None
            }
            
            # 存储区域
            self.zones[zone_id] = zone
            
            # 更新统计信息
            self.stats['zones_created'] += 1
            self.stats['active_zones'] += 1
            
            print(f"✓ 环境区域创建成功: {zone_id}")
            return True
            
        except Exception as e:
            print(f"✗ 创建环境区域失败: {e}")
            return False
            
    def delete_zone(self, zone_id: str) -> bool:
        """
        删除环境区域
        
        Args:
            zone_id: 区域ID
            
        Returns:
            是否删除成功
        """
        if zone_id not in self.zones:
            print(f"✗ 区域不存在: {zone_id}")
            return False
            
        try:
            # 停止区域内的环境音效
            zone = self.zones[zone_id]
            if zone['ambient_sound']:
                ambient_sound_id = zone['ambient_sound']
                self.plugin.audio_source_manager.stop_sound(ambient_sound_id)
                self.plugin.audio_source_manager.delete_sound(ambient_sound_id)
                
            # 删除区域
            del self.zones[zone_id]
            
            # 更新统计信息
            self.stats['active_zones'] -= 1
            
            print(f"✓ 环境区域已删除: {zone_id}")
            return True
            
        except Exception as e:
            print(f"✗ 删除环境区域失败: {e}")
            return False
            
    def set_zone_property(self, zone_id: str, property_name: str, value: Any) -> bool:
        """
        设置区域属性
        
        Args:
            zone_id: 区域ID
            property_name: 属性名
            value: 属性值
            
        Returns:
            是否设置成功
        """
        if zone_id not in self.zones:
            print(f"✗ 区域不存在: {zone_id}")
            return False
            
        try:
            self.zones[zone_id]['properties'][property_name] = value
            print(f"✓ 区域属性已设置: {zone_id}.{property_name} = {value}")
            return True
            
        except Exception as e:
            print(f"✗ 设置区域属性失败: {e}")
            return False
            
    def get_zone_property(self, zone_id: str, property_name: str) -> Any:
        """
        获取区域属性
        
        Args:
            zone_id: 区域ID
            property_name: 属性名
            
        Returns:
            属性值
        """
        if zone_id not in self.zones:
            return None
            
        return self.zones[zone_id]['properties'].get(property_name, None)
        
    def set_zone_position(self, zone_id: str, position: Tuple[float, float, float]) -> bool:
        """
        设置区域位置
        
        Args:
            zone_id: 区域ID
            position: 位置 (x, y, z)
            
        Returns:
            是否设置成功
        """
        if zone_id not in self.zones:
            print(f"✗ 区域不存在: {zone_id}")
            return False
            
        try:
            self.zones[zone_id]['position'] = position
            print(f"✓ 区域位置已设置: {zone_id} -> {position}")
            return True
            
        except Exception as e:
            print(f"✗ 设置区域位置失败: {e}")
            return False
            
    def set_zone_radius(self, zone_id: str, radius: float) -> bool:
        """
        设置区域半径
        
        Args:
            zone_id: 区域ID
            radius: 半径
            
        Returns:
            是否设置成功
        """
        if zone_id not in self.zones:
            print(f"✗ 区域不存在: {zone_id}")
            return False
            
        try:
            self.zones[zone_id]['radius'] = max(0.1, radius)  # 最小半径0.1
            print(f"✓ 区域半径已设置: {zone_id} -> {radius}")
            return True
            
        except Exception as e:
            print(f"✗ 设置区域半径失败: {e}")
            return False
            
    def enable_zone(self, zone_id: str) -> bool:
        """
        启用区域
        
        Args:
            zone_id: 区域ID
            
        Returns:
            是否启用成功
        """
        if zone_id not in self.zones:
            print(f"✗ 区域不存在: {zone_id}")
            return False
            
        try:
            self.zones[zone_id]['active'] = True
            self.stats['active_zones'] += 1
            print(f"✓ 区域已启用: {zone_id}")
            return True
            
        except Exception as e:
            print(f"✗ 启用区域失败: {e}")
            return False
            
    def disable_zone(self, zone_id: str) -> bool:
        """
        禁用区域
        
        Args:
            zone_id: 区域ID
            
        Returns:
            是否禁用成功
        """
        if zone_id not in self.zones:
            print(f"✗ 区域不存在: {zone_id}")
            return False
            
        try:
            self.zones[zone_id]['active'] = False
            self.stats['active_zones'] -= 1
            print(f"✓ 区域已禁用: {zone_id}")
            return True
            
        except Exception as e:
            print(f"✗ 禁用区域失败: {e}")
            return False
            
    def add_ambient_sound_to_zone(self, zone_id: str, filepath: str, 
                                 volume: float = 1.0, loop: bool = True) -> bool:
        """
        为区域添加环境音效
        
        Args:
            zone_id: 区域ID
            filepath: 音频文件路径
            volume: 音量
            loop: 是否循环
            
        Returns:
            是否添加成功
        """
        if zone_id not in self.zones:
            print(f"✗ 区域不存在: {zone_id}")
            return False
            
        try:
            # 创建3D音效
            zone = self.zones[zone_id]
            position = zone['position']
            sound_id = self.plugin.audio_source_manager.create_3d_sound(
                filepath, position, loop, volume)
                
            if not sound_id:
                print(f"✗ 无法创建环境音效: {filepath}")
                return False
                
            # 播放音效
            self.plugin.audio_source_manager.play_sound(sound_id)
            
            # 关联音效到区域
            zone['ambient_sound'] = sound_id
            
            # 更新统计信息
            self.stats['ambient_sounds'] += 1
            
            print(f"✓ 环境音效已添加到区域: {zone_id} -> {filepath}")
            return True
            
        except Exception as e:
            print(f"✗ 添加环境音效到区域失败: {e}")
            return False
            
    def remove_ambient_sound_from_zone(self, zone_id: str) -> bool:
        """
        从区域移除环境音效
        
        Args:
            zone_id: 区域ID
            
        Returns:
            是否移除成功
        """
        if zone_id not in self.zones:
            print(f"✗ 区域不存在: {zone_id}")
            return False
            
        try:
            zone = self.zones[zone_id]
            if zone['ambient_sound']:
                # 停止并删除音效
                sound_id = zone['ambient_sound']
                self.plugin.audio_source_manager.stop_sound(sound_id)
                self.plugin.audio_source_manager.delete_sound(sound_id)
                
                # 清除关联
                zone['ambient_sound'] = None
                
                # 更新统计信息
                self.stats['ambient_sounds'] -= 1
                
                print(f"✓ 环境音效已从区域移除: {zone_id}")
                return True
            else:
                print(f"⚠ 区域没有环境音效: {zone_id}")
                return True
                
        except Exception as e:
            print(f"✗ 从区域移除环境音效失败: {e}")
            return False
            
    def set_ambient_sound_volume(self, zone_id: str, volume: float) -> bool:
        """
        设置区域环境音效音量
        
        Args:
            zone_id: 区域ID
            volume: 音量 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        if zone_id not in self.zones:
            print(f"✗ 区域不存在: {zone_id}")
            return False
            
        try:
            zone = self.zones[zone_id]
            if zone['ambient_sound']:
                sound_id = zone['ambient_sound']
                return self.plugin.audio_source_manager.set_sound_volume(sound_id, volume)
            else:
                print(f"⚠ 区域没有环境音效: {zone_id}")
                return False
                
        except Exception as e:
            print(f"✗ 设置环境音效音量失败: {e}")
            return False
            
    def _calculate_distance(self, pos1: Tuple[float, float, float], 
                          pos2: Tuple[float, float, float]) -> float:
        """
        计算两点间距离
        
        Args:
            pos1: 第一个点
            pos2: 第二个点
            
        Returns:
            距离
        """
        dx = pos1[0] - pos2[0]
        dy = pos1[1] - pos2[1]
        dz = pos1[2] - pos2[2]
        return math.sqrt(dx*dx + dy*dy + dz*dz)
        
    def _is_point_in_zone(self, point: Tuple[float, float, float], 
                         zone_id: str) -> bool:
        """
        检查点是否在区域内
        
        Args:
            point: 检查点
            zone_id: 区域ID
            
        Returns:
            是否在区域内
        """
        if zone_id not in self.zones:
            return False
            
        zone = self.zones[zone_id]
        zone_position = zone['position']
        zone_radius = zone['radius']
        
        distance = self._calculate_distance(point, zone_position)
        return distance <= zone_radius
        
    def update(self, dt: float):
        """
        更新环境音频状态
        
        Args:
            dt: 时间增量
        """
        if not self.enabled:
            return
            
        # 更新听者位置
        if self.plugin.listener:
            listener_pos = self.plugin.listener.getPos()
            self.listener_position = (listener_pos.x, listener_pos.y, listener_pos.z)
            
        # 更新各区域的环境音效
        for zone_id, zone in self.zones.items():
            if not zone['active']:
                continue
                
            # 检查听者是否在区域内
            is_in_zone = self._is_point_in_zone(self.listener_position, zone_id)
            
            # 更新环境音效状态
            if zone['ambient_sound']:
                sound_id = zone['ambient_sound']
                if is_in_zone:
                    # 在区域内，确保音效播放
                    if not self.plugin.audio_source_manager.is_sound_playing(sound_id):
                        self.plugin.audio_source_manager.play_sound(sound_id)
                else:
                    # 不在区域内，停止音效
                    if self.plugin.audio_source_manager.is_sound_playing(sound_id):
                        self.plugin.audio_source_manager.stop_sound(sound_id)
                        
    def toggle_enabled(self):
        """切换启用状态"""
        self.enabled = not self.enabled
        print(f"✓ 环境音频管理器已{'启用' if self.enabled else '禁用'}")
        
    def get_zone_info(self, zone_id: str) -> Dict[str, Any]:
        """
        获取区域信息
        
        Args:
            zone_id: 区域ID
            
        Returns:
            区域信息字典
        """
        if zone_id not in self.zones:
            return {}
            
        zone = self.zones[zone_id]
        return {
            'id': zone['id'],
            'position': zone['position'],
            'radius': zone['radius'],
            'active': zone['active'],
            'has_ambient_sound': zone['ambient_sound'] is not None
        }
        
    def get_all_zones_info(self) -> List[Dict[str, Any]]:
        """
        获取所有区域信息
        
        Returns:
            区域信息列表
        """
        zones_info = []
        for zone_id in self.zones:
            zones_info.append(self.get_zone_info(zone_id))
        return zones_info
        
    def cleanup(self):
        """清理所有资源"""
        # 删除所有区域
        zone_ids = list(self.zones.keys())
        for zone_id in zone_ids:
            self.delete_zone(zone_id)
            
        self.zones.clear()
        self.ambient_sounds.clear()
        self.stats = {
            'zones_created': 0,
            'active_zones': 0,
            'ambient_sounds': 0
        }
        print("✓ 环境音频管理器资源已清理")
        
    def get_stats(self) -> Dict[str, int]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        return self.stats.copy()

