"""
健康检查和监控端点

提供系统健康状态、性能指标和诊断信息
""" 
import logging
import time
from datetime import datetime
from typing import Dict, Any
from fastapi import APIRouter, Response
from prometheus_client import generate_latest, CONTENT_TYPE_LATEST

from src.models.schemas import ResponseModel
from src.services.task_manager import task_manager
from src.services.provider.registry import ModelRegistry
from src.services.provider.health import health_monitor
from src.config.database import engine, get_pool_status
from sqlmodel import Session, text
from src.utils.errors import ErrorCode, AppException

router = APIRouter(tags=["health"])
logger = logging.getLogger(__name__)

# 应用启动时间
_start_time = time.time()


@router.get("/health", response_model=ResponseModel)
async def health_check():
    """基础健康检查

    Returns:
        基本的健康状态信息
    """
    return ResponseModel(data={
        "status": "healthy",
        "service": "Pixel Backend",
        "timestamp": datetime.now().isoformat(),
        "uptime_seconds": int(time.time() - _start_time)
    })


@router.get("/health/detailed", response_model=ResponseModel)
async def detailed_health_check():
    """详细健康检查
    
    检查所有关键组件的健康状态
    
    Returns:
        详细的健康状态信息，包括各组件状态
    """
    health_status = {
        "status": "healthy",
        "timestamp": datetime.now().isoformat(),
        "uptime_seconds": int(time.time() - _start_time),
        "components": {}
    }
    
    # 检查数据库连接
    try:
        start = time.time()
        with Session(engine) as session:
            session.exec(text("SELECT 1"))
        latency_ms = (time.time() - start) * 1000
        
        # Get connection pool status
        pool_status = get_pool_status()
        
        health_status["components"]["database"] = {
            "status": "healthy",
            "message": "Database connection successful",
            "latency_ms": round(latency_ms, 2),
            "pool": pool_status
        }
    except Exception as e:
        health_status["status"] = "unhealthy"
        health_status["components"]["database"] = {
            "status": "unhealthy",
            "message": f"Database connection failed: {str(e)}"
        }
    
    # 检查Redis连接
    from src.config.settings import REDIS_ENABLED
    if REDIS_ENABLED:
        try:
            from src.services.cache_service import get_cache_service
            cache = get_cache_service()
            
            if cache._connected:
                start = time.time()
                await cache._redis.ping()
                latency_ms = (time.time() - start) * 1000
                
                # Get Redis info
                info = await cache._redis.info()
                health_status["components"]["redis"] = {
                    "status": "healthy",
                    "message": "Redis connection successful",
                    "latency_ms": round(latency_ms, 2),
                    "version": info.get("redis_version"),
                    "connected_clients": info.get("connected_clients"),
                    "used_memory_human": info.get("used_memory_human")
                }
            else:
                health_status["status"] = "degraded"
                health_status["components"]["redis"] = {
                    "status": "unhealthy",
                    "message": "Redis not connected"
                }
        except Exception as e:
            health_status["status"] = "degraded"
            health_status["components"]["redis"] = {
                "status": "unhealthy",
                "message": f"Redis connection failed: {str(e)}"
            }
    else:
        health_status["components"]["redis"] = {
            "status": "disabled",
            "message": "Redis is disabled in configuration"
        }
    
    # 检查任务管理器
    try:
        stats = task_manager.get_stats()
        health_status["components"]["task_manager"] = {
            "status": "healthy",
            "stats": stats
        }
    except Exception as e:
        health_status["status"] = "degraded"
        health_status["components"]["task_manager"] = {
            "status": "unhealthy",
            "message": f"Task manager error: {str(e)}"
        }
    
    # 检查模型注册表
    try:
        models = ModelRegistry.list_models()
        health_status["components"]["model_registry"] = {
            "status": "healthy",
            "total_models": len(models)
        }
    except Exception as e:
        health_status["status"] = "degraded"
        health_status["components"]["model_registry"] = {
            "status": "unhealthy",
            "message": f"Model registry error: {str(e)}"
        }
    
    # 检查 AI 服务健康状态
    try:
        service_health = health_monitor.get_health_summary()
        health_status["components"]["ai_services"] = {
            "status": "healthy" if service_health["healthy"] == service_health["total"] else "degraded",
            "summary": service_health
        }
    except Exception as e:
        health_status["status"] = "degraded"
        health_status["components"]["ai_services"] = {
            "status": "unknown",
            "message": f"Health monitor error: {str(e)}"
        }
    
    return ResponseModel(data=health_status)


@router.get("/health/live", response_model=ResponseModel)
async def liveness_probe():
    """ Kubernetes liveness probe

    简单检查应用是否运行

    Returns:
        200 OK if alive
    """
    return ResponseModel(data={"status": "alive"})


@router.get("/health/ready", response_model=ResponseModel)
async def readiness_probe():
    """ Kubernetes readiness probe
    
    检查应用是否准备好接收流量
    
    Returns:
        200 OK if ready, 503 if not ready
    """
    # 检查关键组件
    ready = True
    components = {}
    
    # 检查数据库
    try:
        with Session(engine) as session:
            session.exec(text("SELECT 1"))
        components["database"] = "ready"
    except Exception as e:
        ready = False
        components["database"] = f"not ready: {str(e)}"
    
    # 检查Redis（如果启用）
    from src.config.settings import REDIS_ENABLED
    if REDIS_ENABLED:
        try:
            from src.services.cache_service import get_cache_service
            cache = get_cache_service()
            
            if cache._connected:
                await cache._redis.ping()
                components["redis"] = "ready"
            else:
                ready = False
                components["redis"] = "not ready: not connected"
        except Exception as e:
            ready = False
            components["redis"] = f"not ready: {str(e)}"
    else:
        components["redis"] = "disabled"
    
    # 检查任务管理器
    try:
        task_manager.get_stats()
        components["task_manager"] = "ready"
    except Exception as e:
        ready = False
        components["task_manager"] = f"not ready: {str(e)}"
    
    if ready:
        return ResponseModel(data={"status": "ready", "components": components})
    else:
        raise AppException(
            message="Service not ready",
            code=ErrorCode.SERVICE_UNAVAILABLE,
            status_code=503,
            details={"status": "not ready", "components": components}
        )


@router.get("/metrics")
async def prometheus_metrics():
    """Prometheus metrics endpoint
    
    导出 Prometheus 格式的监控指标
    
    Returns:
        Prometheus 格式的指标数据
    """
    # 更新 system and database metrics before returning
    from src.middlewares.metrics import update_system_metrics, update_database_metrics
    update_system_metrics()
    update_database_metrics()
    
    return Response(
        content=generate_latest(),
        media_type=CONTENT_TYPE_LATEST
    )


@router.get("/metrics/tasks", response_model=ResponseModel)
async def task_metrics():
    """任务管理器指标
    
    Returns:
        任务管理器的详细统计信息
    """
    try:
        stats = task_manager.get_stats()
        return ResponseModel(data=stats)
    except Exception as e:
        logger.error(f"Failed to get task metrics: {e}", exc_info=True)
        return ResponseModel(
            code=500,
            message="Failed to get task metrics",
            data={"error": str(e)}
        )


@router.get("/metrics/models", response_model=ResponseModel)
async def model_metrics():
    """模型服务指标
    
    Returns:
        所有注册模型的健康状态和统计信息
    """
    try:
        # 获取所有模型
        models = ModelRegistry.list_models()
        
        # 获取健康状态
        health_summary = health_monitor.get_health_summary()
        all_health = health_monitor.get_all_health()
        
        # 构建响应
        model_stats = []
        for model_id, config in models.items():
            health = all_health.get(model_id)
            model_stat = {
                "id": model_id,
                "name": config.get("name"),
                "type": config.get("type"),
                "provider": config.get("provider"),
                "enabled": config.get("enabled", True)
            }
            
            if health:
                model_stat["health"] = {
                    "status": health.status.value,
                    "success_rate": health.get_success_rate(),
                    "avg_latency_ms": health.avg_latency_ms,
                    "total_checks": health.total_checks,
                    "total_failures": health.total_failures
                }
            
            model_stats.append(model_stat)
        
        return ResponseModel(data={
            "summary": health_summary,
            "models": model_stats
        })
    except Exception as e:
        logger.error(f"Failed to get model metrics: {e}", exc_info=True)
        return ResponseModel(
            code=500,
            message="Failed to get model metrics",
            data={"error": str(e)}
        )


@router.get("/debug/info", response_model=ResponseModel)
async def debug_info():
    """调试信息
    
    提供系统配置和运行时信息（仅用于开发环境）
    
    Returns:
        系统调试信息
    """ 
    import sys
    import platform
    from src.config.settings import NODE_ENV, STORAGE_TYPE, REDIS_ENABLED
    
    return ResponseModel(data={
        "environment": NODE_ENV,
        "python_version": sys.version,
        "platform": platform.platform(),
        "storage_type": STORAGE_TYPE,
        "redis_enabled": REDIS_ENABLED,
        "uptime_seconds": int(time.time() - _start_time),
        "start_time": datetime.fromtimestamp(_start_time).isoformat()
    })
