"""
Integration tests for API routes and OpenAPI schema.

Verifies that all API v1 endpoints are mounted, properly documented,
and render expected OpenAPI schema and stubs.
"""

import pytest
from httpx import ASGITransport, AsyncClient

from app.main import app


@pytest.mark.asyncio
class TestRouteRegistration:
    """Test suite for OpenAPI schema generation and router mounting."""

    async def test_openapi_schema_generated(self) -> None:
        async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
            response = await client.get("/openapi.json")
            assert response.status_code == 200
            schema = response.json()
            assert "paths" in schema
            assert schema["info"]["title"] == "Munal LMS API"

            paths = schema["paths"]
            # Auth
            assert "/api/v1/auth/login" in paths
            assert "/api/v1/auth/refresh" in paths
            assert "/api/v1/auth/logout" in paths
            assert "/api/v1/auth/me" in paths

            # Labs
            assert "/api/v1/labs" in paths
            assert "/api/v1/labs/{lab_id}" in paths

            # Users
            assert "/api/v1/users" in paths
            assert "/api/v1/users/{user_id}" in paths
            assert "/api/v1/users/{user_id}/deactivate" in paths
            assert "/api/v1/users/{user_id}/activate" in paths
            assert "/api/v1/users/me/change-password" in paths

            # Patients
            assert "/api/v1/patients" in paths
            assert "/api/v1/patients/{patient_id}" in paths

            # Tests, Parameters, Ranges
            assert "/api/v1/test-categories" in paths
            assert "/api/v1/test-categories/{category_id}" in paths
            assert "/api/v1/tests" in paths
            assert "/api/v1/tests/{test_id}" in paths
            assert "/api/v1/tests/{test_id}/parameters" in paths
            assert "/api/v1/tests/{test_id}/parameters/{param_id}" in paths
            assert "/api/v1/tests/{test_id}/parameters/{param_id}/ranges" in paths
            assert "/api/v1/tests/{test_id}/parameters/{param_id}/ranges/{range_id}" in paths

            # Packages
            assert "/api/v1/packages" in paths
            assert "/api/v1/packages/{package_id}" in paths
            assert "/api/v1/packages/{package_id}/items" in paths
            assert "/api/v1/packages/{package_id}/items/{item_id}" in paths

            # Appointments
            assert "/api/v1/appointment-slots" in paths
            assert "/api/v1/appointment-slots/{slot_id}" in paths
            assert "/api/v1/appointments" in paths
            assert "/api/v1/appointments/{appointment_id}" in paths
            assert "/api/v1/appointments/{appointment_id}/confirm" in paths
            assert "/api/v1/appointments/{appointment_id}/complete" in paths
            assert "/api/v1/appointments/{appointment_id}/cancel" in paths

            # Orders
            assert "/api/v1/orders" in paths
            assert "/api/v1/orders/{order_id}" in paths
            assert "/api/v1/orders/{order_id}/cancel" in paths

    async def test_docs_page_available(self) -> None:
        async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
            response = await client.get("/docs")
            assert response.status_code == 200

    async def test_health_check(self) -> None:
        async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
            response = await client.get("/health")
            assert response.status_code == 200
            data = response.json()
            assert data["status"] == "ok"

    async def test_protected_routes_return_401_without_token(self) -> None:
        async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
            response = await client.get("/api/v1/orders")
            assert response.status_code == 401
            body = response.json()
            assert body["success"] is False
            assert body["error"]["code"] == "UNAUTHORIZED"

            response = await client.get("/api/v1/labs")
            assert response.status_code == 401
            body = response.json()
            assert body["success"] is False
            assert body["error"]["code"] == "UNAUTHORIZED"
