"""
生命周期管理器 - 负责服务状态管理

职责:
1. 监听 ServiceCached 事件，初始化生命周期状态
2. 监听 ServiceConnected/ServiceConnectionFailed 事件，转换状态
3. 发布 ServiceStateChanged 事件
4. 管理状态元数据
"""

import logging
from datetime import datetime

from mcpstore.core.events.event_bus import EventBus
from mcpstore.core.events.service_events import (
    ServiceCached, ServiceInitialized, ServiceConnected,
    ServiceConnectionFailed, ServiceStateChanged
)
from mcpstore.core.models.service import ServiceConnectionState, ServiceStateMetadata

logger = logging.getLogger(__name__)


class LifecycleManager:
    """
    生命周期管理器
    
    职责:
    1. 监听 ServiceCached 事件，初始化生命周期状态
    2. 监听 ServiceConnected/ServiceConnectionFailed 事件，转换状态
    3. 发布 ServiceStateChanged 事件
    4. 管理状态元数据
    """
    
    def __init__(self, event_bus: EventBus, registry: 'CoreRegistry'):
        self._event_bus = event_bus
        self._registry = registry
        
        # 订阅事件
        self._event_bus.subscribe(ServiceCached, self._on_service_cached, priority=90)
        self._event_bus.subscribe(ServiceConnected, self._on_service_connected, priority=40)
        self._event_bus.subscribe(ServiceConnectionFailed, self._on_service_connection_failed, priority=40)

        # 🆕 订阅健康检查和超时事件
        from mcpstore.core.events.service_events import HealthCheckCompleted, ServiceTimeout, ReconnectionRequested
        self._event_bus.subscribe(HealthCheckCompleted, self._on_health_check_completed, priority=50)
        self._event_bus.subscribe(ServiceTimeout, self._on_service_timeout, priority=50)
        self._event_bus.subscribe(ReconnectionRequested, self._on_reconnection_requested, priority=30)

        logger.info("LifecycleManager initialized and subscribed to events")
    
    async def _on_service_cached(self, event: ServiceCached):
        """
        处理服务已缓存事件 - 初始化生命周期状态
        """
        logger.info(f"[LIFECYCLE] Initializing lifecycle for: {event.service_name}")
        
        try:
            # 🔧 修复：检查是否已有 metadata（CacheManager 可能已创建）
            existing_metadata = self._registry.get_service_metadata(event.agent_id, event.service_name)
            
            if existing_metadata and existing_metadata.service_config:
                # 如果已有 metadata 且包含配置，保留原有配置
                service_config = existing_metadata.service_config
                logger.debug(f"[LIFECYCLE] Preserving existing service_config for: {event.service_name}")
            else:
                # 否则，尝试从客户端配置中读取
                client_config = self._registry.get_client_config_from_cache(event.client_id)
                service_config = client_config.get("mcpServers", {}).get(event.service_name, {}) if client_config else {}
                logger.debug(f"[LIFECYCLE] Loading service_config from client config for: {event.service_name}")
            
            # 创建或更新元数据（保留配置信息）
            metadata = ServiceStateMetadata(
                service_name=event.service_name,
                agent_id=event.agent_id,
                state_entered_time=datetime.now(),
                consecutive_failures=0,
                reconnect_attempts=0,
                next_retry_time=None,
                error_message=None,
                service_config=service_config  # 🔧 修复：使用正确的配置
            )
            
            self._registry.set_service_metadata(event.agent_id, event.service_name, metadata)
            
            logger.info(f"[LIFECYCLE] Lifecycle initialized: {event.service_name} -> INITIALIZING")
            
            # 发布初始化完成事件
            initialized_event = ServiceInitialized(
                agent_id=event.agent_id,
                service_name=event.service_name,
                initial_state="initializing"
            )
            await self._event_bus.publish(initialized_event)
            
        except Exception as e:
            logger.error(f"[LIFECYCLE] Failed to initialize lifecycle for {event.service_name}: {e}", exc_info=True)
    
    async def _on_service_connected(self, event: ServiceConnected):
        """
        处理服务连接成功 - 转换状态为 HEALTHY
        """
        logger.info(f"[LIFECYCLE] Service connected: {event.service_name}")
        
        try:
            await self._transition_state(
                agent_id=event.agent_id,
                service_name=event.service_name,
                new_state=ServiceConnectionState.HEALTHY,
                reason="connection_success",
                source="ConnectionManager"
            )
            
            # 重置失败计数
            metadata = self._registry.get_service_metadata(event.agent_id, event.service_name)
            if metadata:
                metadata.consecutive_failures = 0
                metadata.reconnect_attempts = 0
                metadata.error_message = None
                metadata.last_health_check = datetime.now()
                metadata.last_response_time = event.connection_time
                self._registry.set_service_metadata(event.agent_id, event.service_name, metadata)
            
        except Exception as e:
            logger.error(f"[LIFECYCLE] Failed to transition state for {event.service_name}: {e}", exc_info=True)
    
    async def _on_service_connection_failed(self, event: ServiceConnectionFailed):
        """
        处理服务连接失败 - 转换状态为 RECONNECTING
        """
        logger.warning(f"[LIFECYCLE] Service connection failed: {event.service_name} ({event.error_message})")
        
        try:
            # 更新元数据
            metadata = self._registry.get_service_metadata(event.agent_id, event.service_name)
            if metadata:
                metadata.consecutive_failures += 1
                metadata.error_message = event.error_message
                metadata.last_failure_time = datetime.now()
                self._registry.set_service_metadata(event.agent_id, event.service_name, metadata)
            
            # 根据当前状态决定目标状态
            current_state = self._registry.get_service_state(event.agent_id, event.service_name)
            
            if current_state == ServiceConnectionState.INITIALIZING:
                # 初次连接失败 -> RECONNECTING
                new_state = ServiceConnectionState.RECONNECTING
                reason = "initial_connection_failed"
            else:
                # 其他情况也转到 RECONNECTING
                new_state = ServiceConnectionState.RECONNECTING
                reason = "connection_failed"
            
            await self._transition_state(
                agent_id=event.agent_id,
                service_name=event.service_name,
                new_state=new_state,
                reason=reason,
                source="ConnectionManager"
            )
            
        except Exception as e:
            logger.error(f"[LIFECYCLE] Failed to handle connection failure for {event.service_name}: {e}", exc_info=True)

    async def _on_health_check_completed(self, event: 'HealthCheckCompleted'):
        """
        处理健康检查完成 - 根据健康状态转换服务状态
        """
        logger.debug(f"[LIFECYCLE] Health check completed: {event.service_name} (success={event.success})")

        try:
            # 更新元数据
            metadata = self._registry.get_service_metadata(event.agent_id, event.service_name)
            if metadata:
                metadata.last_health_check = datetime.now()
                metadata.last_response_time = event.response_time

                if event.success:
                    metadata.consecutive_failures = 0
                    metadata.error_message = None
                else:
                    metadata.consecutive_failures += 1
                    metadata.error_message = event.error_message

                self._registry.set_service_metadata(event.agent_id, event.service_name, metadata)

            # 根据建议的状态转换
            if event.suggested_state:
                current_state = self._registry.get_service_state(event.agent_id, event.service_name)
                suggested_state_enum = ServiceConnectionState[event.suggested_state]

                # 只有状态真正变化时才转换
                if current_state != suggested_state_enum:
                    await self._transition_state(
                        agent_id=event.agent_id,
                        service_name=event.service_name,
                        new_state=suggested_state_enum,
                        reason=f"health_check_{event.success}",
                        source="HealthMonitor"
                    )

        except Exception as e:
            logger.error(f"[LIFECYCLE] Failed to handle health check result for {event.service_name}: {e}", exc_info=True)

    async def _on_service_timeout(self, event: 'ServiceTimeout'):
        """
        处理服务超时 - 转换状态为 UNREACHABLE
        """
        logger.warning(
            f"[LIFECYCLE] Service timeout: {event.service_name} "
            f"(type={event.timeout_type}, elapsed={event.elapsed_time:.1f}s)"
        )

        try:
            # 更新元数据
            metadata = self._registry.get_service_metadata(event.agent_id, event.service_name)
            if metadata:
                metadata.error_message = f"Timeout: {event.timeout_type} ({event.elapsed_time:.1f}s)"
                self._registry.set_service_metadata(event.agent_id, event.service_name, metadata)

            # 转换到 UNREACHABLE 状态
            await self._transition_state(
                agent_id=event.agent_id,
                service_name=event.service_name,
                new_state=ServiceConnectionState.UNREACHABLE,
                reason=f"timeout_{event.timeout_type}",
                source="HealthMonitor"
            )

        except Exception as e:
            logger.error(f"[LIFECYCLE] Failed to handle timeout for {event.service_name}: {e}", exc_info=True)

    async def _on_reconnection_requested(self, event: 'ReconnectionRequested'):
        """
        处理重连请求 - 记录日志（实际重连由 ConnectionManager 处理）
        """
        logger.info(
            f"[LIFECYCLE] Reconnection requested: {event.service_name} "
            f"(retry={event.retry_count}, reason={event.reason})"
        )

        # 更新元数据中的重连尝试次数
        try:
            metadata = self._registry.get_service_metadata(event.agent_id, event.service_name)
            if metadata:
                metadata.reconnect_attempts = event.retry_count
                self._registry.set_service_metadata(event.agent_id, event.service_name, metadata)
        except Exception as e:
            logger.error(f"[LIFECYCLE] Failed to update reconnection metadata: {e}")
    
    async def _transition_state(
        self,
        agent_id: str,
        service_name: str,
        new_state: ServiceConnectionState,
        reason: str,
        source: str
    ):
        """
        执行状态转换（唯一入口）
        """
        old_state = self._registry.get_service_state(agent_id, service_name)
        
        if old_state == new_state:
            logger.debug(f"[LIFECYCLE] State unchanged: {service_name} already in {new_state.value}")
            return
        
        logger.info(
            f"[LIFECYCLE] State transition: {service_name} "
            f"{old_state.value if old_state else 'None'} -> {new_state.value} "
            f"(reason={reason}, source={source})"
        )
        
        # 更新状态
        self._registry.set_service_state(agent_id, service_name, new_state)
        
        # 更新元数据
        metadata = self._registry.get_service_metadata(agent_id, service_name)
        if metadata:
            metadata.state_entered_time = datetime.now()
            self._registry.set_service_metadata(agent_id, service_name, metadata)
        
        # 发布状态变化事件
        state_changed_event = ServiceStateChanged(
            agent_id=agent_id,
            service_name=service_name,
            old_state=old_state.value if old_state else "none",
            new_state=new_state.value,
            reason=reason,
            source=source
        )
        await self._event_bus.publish(state_changed_event)

