"""Health check endpoint."""

import asyncio

import structlog
from fastapi import APIRouter
from fastapi.responses import JSONResponse

from src.api.dependencies import (
    AsyncSessionDep,
    RedisDep,
)
from src.api.schemas.health import DependencyHealth, HealthResponse
from src.services.health import (
    aggregate_health_status,
    check_milvus,
    check_postgres,
    check_redis,
)

logger = structlog.get_logger(__name__)

router = APIRouter(prefix="/health", tags=["Health"])

# Application version - should match pyproject.toml
APP_VERSION = "1.0.0"


@router.get(
    "",
    response_model=HealthResponse,
    responses={
        200: {"description": "Service is healthy or degraded"},
        503: {"description": "Service is unhealthy - critical dependency down"},
    },
)
async def health_check(
    session: AsyncSessionDep,
    redis_client: RedisDep,
) -> JSONResponse:
    """Check service health and dependency status.

    Performs concurrent health checks on all dependencies:
    - PostgreSQL (critical): SELECT 1 query
    - Redis: PING command
    - Milvus: list_collections API

    Returns:
        HealthResponse with overall status and individual dependency health.

    Status codes:
        200: All dependencies healthy or non-critical dependencies degraded
        503: Critical dependency (database) is unhealthy
    """
    logger.info("health_check_started")

    # Run all dependency checks concurrently for efficiency
    postgres_check, redis_check, milvus_check = await asyncio.gather(
        check_postgres(session),
        check_redis(redis_client),
        check_milvus(),
        return_exceptions=False,
    )

    # Build dependencies dict
    dependencies: dict[str, DependencyHealth] = {
        "database": postgres_check,
        "redis": redis_check,
        "milvus": milvus_check,
    }

    # Aggregate overall status
    overall_status = aggregate_health_status(dependencies)

    # Create response
    response = HealthResponse(
        status=overall_status,
        version=APP_VERSION,
        dependencies=dependencies,
    )

    logger.info(
        "health_check_completed",
        status=overall_status,
        database_healthy=postgres_check.status == "healthy",
        redis_healthy=redis_check.status == "healthy",
        milvus_healthy=milvus_check.status == "healthy",
    )

    # Return 503 if critical dependency (database) is unhealthy
    if overall_status == "unhealthy":
        return JSONResponse(
            status_code=503,
            content=response.model_dump(),
        )

    return JSONResponse(
        status_code=200,
        content=response.model_dump(),
    )
