"""
音频组件基类
提供音频组件的基础功能和接口
"""

from abc import ABC, abstractmethod
from typing import Dict, Any, Optional
import uuid

class AudioComponent(ABC):
    """
    音频组件基类
    提供音频组件的基础功能和接口
    """
    
    def __init__(self, plugin, name: str = ""):
        """
        初始化音频组件
        
        Args:
            plugin: 3D音频插件实例
            name: 组件名称
        """
        self.plugin = plugin
        self.name = name if name else f"AudioComponent_{uuid.uuid4()}"
        self.enabled = True
        self.properties: Dict[str, Any] = {}
        
    @abstractmethod
    def initialize(self) -> bool:
        """
        初始化组件
        
        Returns:
            是否初始化成功
        """
        pass
        
    @abstractmethod
    def cleanup(self):
        """清理组件资源"""
        pass
        
    @abstractmethod
    def update(self, dt: float):
        """
        更新组件状态
        
        Args:
            dt: 时间增量
        """
        pass
        
    def enable(self):
        """启用组件"""
        self.enabled = True
        
    def disable(self):
        """禁用组件"""
        self.enabled = False
        
    def is_enabled(self) -> bool:
        """
        检查组件是否启用
        
        Returns:
            是否启用
        """
        return self.enabled
        
    def set_property(self, name: str, value: Any) -> bool:
        """
        设置属性
        
        Args:
            name: 属性名
            value: 属性值
            
        Returns:
            是否设置成功
        """
        try:
            self.properties[name] = value
            return True
        except Exception:
            return False
            
    def get_property(self, name: str, default: Any = None) -> Any:
        """
        获取属性
        
        Args:
            name: 属性名
            default: 默认值
            
        Returns:
            属性值
        """
        return self.properties.get(name, default)
        
    def remove_property(self, name: str) -> bool:
        """
        移除属性
        
        Args:
            name: 属性名
            
        Returns:
            是否移除成功
        """
        if name in self.properties:
            del self.properties[name]
            return True
        return False
        
    def get_all_properties(self) -> Dict[str, Any]:
        """
        获取所有属性
        
        Returns:
            属性字典
        """
        return self.properties.copy()


class AudioSourceComponent(AudioComponent):
    """
    音频源组件
    用于为游戏对象添加音频播放功能
    """
    
    def __init__(self, plugin, name: str = ""):
        super().__init__(plugin, name)
        self.sound_id: Optional[str] = None
        self.spatial = False
        self.loop = False
        self.volume = 1.0
        self.attached_object = None
        
    def initialize(self) -> bool:
        """初始化音频源组件"""
        # 音频源组件在需要时才创建音效
        return True
        
    def cleanup(self):
        """清理音频源组件"""
        if self.sound_id:
            self.plugin.audio_source_manager.delete_sound(self.sound_id)
            self.sound_id = None
            
    def update(self, dt: float):
        """更新音频源组件"""
        if not self.enabled:
            return
            
        # 如果附加到对象，同步位置
        if self.attached_object and self.sound_id and self.spatial:
            pos = self.attached_object.getPos()
            self.plugin.audio_source_manager.set_sound_position(
                self.sound_id, (pos.x, pos.y, pos.z))
                
    def load_sound(self, filepath: str, spatial: bool = False, 
                   loop: bool = False, volume: float = 1.0) -> bool:
        """
        加载音频文件
        
        Args:
            filepath: 音频文件路径
            spatial: 是否为3D音效
            loop: 是否循环播放
            volume: 音量
            
        Returns:
            是否加载成功
        """
        try:
            # 删除现有音效
            if self.sound_id:
                self.plugin.audio_source_manager.delete_sound(self.sound_id)
                
            # 创建新音效
            if spatial:
                pos = (0, 0, 0)
                if self.attached_object:
                    obj_pos = self.attached_object.getPos()
                    pos = (obj_pos.x, obj_pos.y, obj_pos.z)
                self.sound_id = self.plugin.audio_source_manager.create_3d_sound(
                    filepath, pos, loop, volume)
            else:
                self.sound_id = self.plugin.audio_source_manager.create_2d_sound(
                    filepath, loop, volume)
                
            if self.sound_id:
                self.spatial = spatial
                self.loop = loop
                self.volume = volume
                return True
            else:
                return False
                
        except Exception as e:
            print(f"✗ 加载音频文件失败: {e}")
            return False
            
    def play(self) -> bool:
        """
        播放音效
        
        Returns:
            是否播放成功
        """
        if self.sound_id:
            return self.plugin.audio_source_manager.play_sound(self.sound_id)
        return False
        
    def stop(self) -> bool:
        """
        停止音效
        
        Returns:
            是否停止成功
        """
        if self.sound_id:
            return self.plugin.audio_source_manager.stop_sound(self.sound_id)
        return False
        
    def pause(self) -> bool:
        """
        暂停音效
        
        Returns:
            是否暂停成功
        """
        if self.sound_id:
            return self.plugin.audio_source_manager.pause_sound(self.sound_id)
        return False
        
    def resume(self) -> bool:
        """
        恢复音效
        
        Returns:
            是否恢复成功
        """
        if self.sound_id:
            return self.plugin.audio_source_manager.resume_sound(self.sound_id)
        return False
        
    def is_playing(self) -> bool:
        """
        检查音效是否正在播放
        
        Returns:
            是否正在播放
        """
        if self.sound_id:
            return self.plugin.audio_source_manager.is_sound_playing(self.sound_id)
        return False
        
    def set_volume(self, volume: float) -> bool:
        """
        设置音量
        
        Args:
            volume: 音量 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        if self.sound_id:
            success = self.plugin.audio_source_manager.set_sound_volume(self.sound_id, volume)
            if success:
                self.volume = volume
            return success
        return False
        
    def set_loop(self, loop: bool) -> bool:
        """
        设置循环模式
        
        Args:
            loop: 是否循环
            
        Returns:
            是否设置成功
        """
        if self.sound_id:
            success = self.plugin.audio_source_manager.set_sound_loop(self.sound_id, loop)
            if success:
                self.loop = loop
            return success
        return False
        
    def attach_to_object(self, obj):
        """
        附加到游戏对象
        
        Args:
            obj: 游戏对象
        """
        self.attached_object = obj
        
    def detach_from_object(self):
        """从游戏对象分离"""
        self.attached_object = None


class AudioListenerComponent(AudioComponent):
    """
    音频听者组件
    用于设置音频听者位置和方向
    """
    
    def __init__(self, plugin, name: str = ""):
        super().__init__(plugin, name)
        self.attached_object = None
        
    def initialize(self) -> bool:
        """初始化音频听者组件"""
        return True
        
    def cleanup(self):
        """清理音频听者组件"""
        pass
        
    def update(self, dt: float):
        """更新音频听者组件"""
        if not self.enabled:
            return
            
        # 如果附加到对象，同步位置和方向
        if self.attached_object:
            pos = self.attached_object.getPos()
            hpr = self.attached_object.getHpr()
            self.plugin.set_listener_position((pos.x, pos.y, pos.z))
            self.plugin.set_listener_orientation((hpr.x, hpr.y, hpr.z))
            
    def attach_to_object(self, obj):
        """
        附加到游戏对象
        
        Args:
            obj: 游戏对象
        """
        self.attached_object = obj
        
    def detach_from_object(self):
        """从游戏对象分离"""
        self.attached_object = None


class AudioEffectComponent(AudioComponent):
    """
    音频效果组件
    用于为音频源应用效果
    """
    
    def __init__(self, plugin, name: str = ""):
        super().__init__(plugin, name)
        self.effect_id: Optional[str] = None
        self.effect_type = ""
        self.target_sound_id: Optional[str] = None
        
    def initialize(self) -> bool:
        """初始化音频效果组件"""
        return True
        
    def cleanup(self):
        """清理音频效果组件"""
        if self.effect_id:
            self.plugin.audio_effect_processor.delete_effect(self.effect_id)
            self.effect_id = None
            
    def update(self, dt: float):
        """更新音频效果组件"""
        if not self.enabled:
            return
            
    def create_effect(self, effect_type: str, parameters: Dict[str, Any]) -> bool:
        """
        创建音频效果
        
        Args:
            effect_type: 效果类型
            parameters: 效果参数
            
        Returns:
            是否创建成功
        """
        try:
            # 删除现有效果
            if self.effect_id:
                self.plugin.audio_effect_processor.delete_effect(self.effect_id)
                
            # 创建新效果
            self.effect_id = self.plugin.audio_effect_processor.create_effect(
                effect_type, parameters)
                
            if self.effect_id:
                self.effect_type = effect_type
                return True
            else:
                return False
                
        except Exception as e:
            print(f"✗ 创建音频效果失败: {e}")
            return False
            
    def apply_to_sound(self, sound_id: str) -> bool:
        """
        应用效果到音效
        
        Args:
            sound_id: 音源ID
            
        Returns:
            是否应用成功
        """
        if self.effect_id:
            success = self.plugin.audio_effect_processor.apply_effect_to_sound(
                sound_id, self.effect_id)
            if success:
                self.target_sound_id = sound_id
            return success
        return False
        
    def remove_from_sound(self, sound_id: str) -> bool:
        """
        从音效移除效果
        
        Args:
            sound_id: 音源ID
            
        Returns:
            是否移除成功
        """
        if self.effect_id:
            success = self.plugin.audio_effect_processor.remove_effect_from_sound(
                sound_id, self.effect_id)
            if success and self.target_sound_id == sound_id:
                self.target_sound_id = None
            return success
        return False
        
    def set_parameter(self, parameter: str, value: Any) -> bool:
        """
        设置效果参数
        
        Args:
            parameter: 参数名
            value: 参数值
            
        Returns:
            是否设置成功
        """
        if self.effect_id:
            return self.plugin.audio_effect_processor.set_effect_parameter(
                self.effect_id, parameter, value)
        return False