"""Health check and monitoring endpoints."""

import logging

from fastapi import APIRouter

from src.models.schemas import ResponseModel
from src.services.provider.registry import ModelRegistry
from src.utils.errors import AppException, ErrorCode
from src.services.provider.health import health_monitor

logger = logging.getLogger(__name__)
router = APIRouter()


@router.get("/config/health", response_model=ResponseModel)
async def get_health_status():
    """Get health status of all registered services."""
    try:
        summary = health_monitor.get_health_summary()
        all_health = health_monitor.get_all_health()

        services = {}
        for service_id, health in all_health.items():
            services[service_id] = {
                "status": health.status.value,
                "last_check": health.last_check.isoformat() if health.last_check else None,
                "last_success": health.last_success.isoformat() if health.last_success else None,
                "last_failure": health.last_failure.isoformat() if health.last_failure else None,
                "consecutive_failures": health.consecutive_failures,
                "consecutive_successes": health.consecutive_successes,
                "total_checks": health.total_checks,
                "total_failures": health.total_failures,
                "success_rate": health.get_success_rate(),
                "avg_latency_ms": health.avg_latency_ms,
                "should_circuit_break": health.should_circuit_break()
            }

        return ResponseModel(data={
            "summary": summary,
            "services": services,
            "unhealthy": health_monitor.get_unhealthy_services(),
            "degraded": health_monitor.get_degraded_services()
        })
    except Exception as e:
        logger.error(f"Failed to get health status: {e}")
        raise AppException(
            message=str(e),
            code=ErrorCode.INTERNAL_ERROR,
            status_code=500
        )


@router.get("/config/health/{service_id}", response_model=ResponseModel)
async def get_service_health(service_id: str):
    """Get detailed health status for a specific service."""
    try:
        health = health_monitor.get_health(service_id)

        if not health:
            raise AppException(
                message=f"Service not found: {service_id}",
                code=ErrorCode.NOT_FOUND,
                status_code=404
            )

        history = [
            {
                "status": result.status.value,
                "latency_ms": result.latency_ms,
                "timestamp": result.timestamp.isoformat(),
                "error": result.error,
                "metadata": result.metadata
            }
            for result in health.history
        ]

        return ResponseModel(data={
            "service_id": service_id,
            "status": health.status.value,
            "last_check": health.last_check.isoformat() if health.last_check else None,
            "last_success": health.last_success.isoformat() if health.last_success else None,
            "last_failure": health.last_failure.isoformat() if health.last_failure else None,
            "consecutive_failures": health.consecutive_failures,
            "consecutive_successes": health.consecutive_successes,
            "total_checks": health.total_checks,
            "total_failures": health.total_failures,
            "success_rate": health.get_success_rate(),
            "avg_latency_ms": health.avg_latency_ms,
            "should_circuit_break": health.should_circuit_break(),
            "history": history
        })
    except AppException:
        raise
    except Exception as e:
        logger.error(f"Failed to get service health: {e}")
        raise AppException(
            message=str(e),
            code=ErrorCode.INTERNAL_ERROR,
            status_code=500
        )


@router.post("/config/health/{service_id}/check", response_model=ResponseModel)
async def check_service_health(service_id: str):
    """Manually trigger a health check for a specific service."""
    try:
        service = ModelRegistry.get(service_id)
        if not service:
            raise AppException(
                message=f"Service not found: {service_id}",
                code=ErrorCode.NOT_FOUND,
                status_code=404
            )

        health_monitor.register_service(service_id)

        result = await health_monitor.check_service_health(service_id, service)

        health_monitor.update_health(service_id, result)

        return ResponseModel(data={
            "service_id": service_id,
            "status": result.status.value,
            "latency_ms": result.latency_ms,
            "timestamp": result.timestamp.isoformat(),
            "error": result.error
        })
    except AppException:
        raise
    except Exception as e:
        logger.error(f"Failed to check service health: {e}")
        raise AppException(
            message=str(e),
            code=ErrorCode.INTERNAL_ERROR,
            status_code=500
        )
