#!/usr/bin/env python3
"""
组件基类 - 所有模块组件的基类

提供统一的初始化、启动、停止接口。
"""

import asyncio
import logging
from typing import Optional, Dict, Any
from abc import ABC, abstractmethod
from dataclasses import dataclass
from enum import Enum

from event_bus import EventBus, EventBusEvent

logger = logging.getLogger(__name__)


class ComponentState(str, Enum):
    """组件状态"""
    INITIALIZED = "initialized"
    RUNNING = "running"
    STOPPED = "stopped"
    ERROR = "error"


@dataclass
class ComponentConfig:
    """组件配置"""
    name: str
    enabled: bool = True
    priority: int = 0  # 启动优先级
    dependencies: list = None  # 依赖的组件名称列表
    
    def __post_init__(self):
        if self.dependencies is None:
            self.dependencies = []


class BaseComponent(ABC):
    """
    组件基类
    
    所有模块组件都应继承此类，实现统一的 lifecycle 接口。
    """
    
    def __init__(self, config: ComponentConfig, event_bus: EventBus):
        self.config = config
        self.event_bus = event_bus
        self.state = ComponentState.INITIALIZED
        self._task: Optional[asyncio.Task] = None
        self._handlers = {}
        
        # 注册默认处理器
        self._register_default_handlers()
    
    def _register_default_handlers(self):
        """注册默认事件处理器"""
        pass
    
    async def initialize(self) -> bool:
        """
        初始化组件
        
        Returns:
            bool: 初始化是否成功
        """
        try:
            logger.info(f"🔄 初始化组件: {self.config.name}")
            await self._do_initialize()
            self.state = ComponentState.INITIALIZED
            logger.info(f"✅ 组件初始化完成: {self.config.name}")
            return True
        except Exception as e:
            logger.error(f"❌ 组件初始化失败: {self.config.name} - {e}")
            self.state = ComponentState.ERROR
            self.event_bus.publish("system_error", {
                "component": self.config.name,
                "error": str(e)
            }, source=self.config.name)
            return False
    
    async def start(self) -> bool:
        """
        启动组件
        
        Returns:
            bool: 启动是否成功
        """
        if self.state != ComponentState.INITIALIZED:
            logger.warning(f"⚠️ 组件 {self.config.name} 未初始化，跳过启动")
            return False
        
        try:
            logger.info(f"▶️ 启动组件: {self.config.name}")
            self._task = asyncio.create_task(self._run_loop())
            self.state = ComponentState.RUNNING
            self.event_bus.publish("component_ready", {
                "component": self.config.name
            }, source=self.config.name)
            return True
        except Exception as e:
            logger.error(f"❌ 组件启动失败: {self.config.name} - {e}")
            self.state = ComponentState.ERROR
            return False
    
    async def stop(self) -> bool:
        """
        停止组件
        
        Returns:
            bool: 停止是否成功
        """
        if self.state != ComponentState.RUNNING:
            return True
        
        try:
            logger.info(f"⏹️ 停止组件: {self.config.name}")
            self.state = ComponentState.STOPPED
            if self._task:
                self._task.cancel()
                try:
                    await self._task
                except asyncio.CancelledError:
                    pass
            return True
        except Exception as e:
            logger.error(f"❌ 组件停止失败: {self.config.name} - {e}")
            return False
    
    @abstractmethod
    async def _do_initialize(self):
        """组件初始化实现（子类覆盖）"""
        pass
    
    @abstractmethod
    async def _run_loop(self):
        """组件主循环实现（子类覆盖）"""
        pass
    
    def publish(self, event_type: str, data: Dict[str, Any], priority: int = 0):
        """发布事件"""
        self.event_bus.publish(event_type, data, source=self.config.name, priority=priority)
    
    def subscribe(self, event_type: str, handler, async_handler: bool = True):
        """订阅事件"""
        self.event_bus.subscribe(event_type, handler, is_async=async_handler)
        self._handlers[event_type] = handler
        logger.debug(f"📡 {self.config.name} 订阅: {event_type}")
    
    def unsubscribe(self, event_type: str):
        """取消订阅"""
        if event_type in self._handlers:
            self.event_bus.unsubscribe(event_type, self._handlers[event_type])
            del self._handlers[event_type]


class STTComponent(BaseComponent):
    """STT 组件基类"""
    
    async def _do_initialize(self):
        pass
    
    async def _run_loop(self):
        pass
    
    async def transcribe(self, audio_data: bytes) -> str:
        """转录音频（子类实现）"""
        raise NotImplementedError


class LLMComponent(BaseComponent):
    """LLM 组件基类"""
    
    async def _do_initialize(self):
        pass
    
    async def _run_loop(self):
        pass
    
    async def generate(self, prompt: str, context: Dict = None) -> str:
        """生成回复（子类实现）"""
        raise NotImplementedError


class TTSComponent(BaseComponent):
    """TTS 组件基类"""
    
    async def _do_initialize(self):
        pass
    
    async def _run_loop(self):
        pass
    
    async def speak(self, text: str) -> bytes:
        """合成语音（子类实现）"""
        raise NotImplementedError


class MemoryComponent(BaseComponent):
    """记忆组件基类"""
    
    async def _do_initialize(self):
        pass
    
    async def _run_loop(self):
        pass
    
    async def extract_facts(self, text: str, speaker: str) -> list:
        """提取事实（子类实现）"""
        raise NotImplementedError
    
    async def get_context(self, identity: str, hours: int = 24) -> Dict:
        """获取上下文（子类实现）"""
        raise NotImplementedError


class VisionComponent(BaseComponent):
    """视觉组件基类"""
    
    async def _do_initialize(self):
        pass
    
    async def _run_loop(self):
        pass
    
    async def process_frame(self, image_bytes: bytes) -> Dict:
        """处理帧（子类实现）"""
        raise NotImplementedError


# ========== 组件工厂 ==========

class ComponentFactory:
    """组件工厂 - 根据配置创建组件实例"""
    
    _components = {
        "stt": STTComponent,
        "llm": LLMComponent,
        "tts": TTSComponent,
        "memory": MemoryComponent,
        "vision": VisionComponent,
    }
    
    @classmethod
    def create(cls, component_type: str, config: Dict, event_bus: EventBus) -> BaseComponent:
        """
        创建组件实例
        
        Args:
            component_type: 组件类型 (stt/llm/tts/memory/vision)
            config: 组件配置
            event_bus: 事件总线
        
        Returns:
            BaseComponent: 组件实例
        """
        if component_type not in cls._components:
            raise ValueError(f"未知组件类型: {component_type}")
        
        component_class = cls._components[component_type]
        comp_config = ComponentConfig(
            name=f"{component_type}_component",
            enabled=config.get("enabled", True),
            priority=config.get("priority", 0),
            dependencies=config.get("dependencies", [])
        )
        
        return component_class(comp_config, event_bus)
