"""Tests for OpenAPI documentation completeness (Task 5.14)."""

from __future__ import annotations

import os
import sys

import pytest

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


def test_openapi_tags_configured():
    """FastAPI app should have openapi_tags configured with descriptions."""
    from app.main import app

    assert app.openapi_tags is not None
    assert len(app.openapi_tags) > 0
    tag_names = {t["name"] for t in app.openapi_tags}
    # Core tags should be present
    assert "health" in tag_names
    assert "auth" in tag_names
    assert "users" in tag_names
    assert "contacts" in tag_names
    assert "system-settings" in tag_names


def test_openapi_tags_have_descriptions():
    """Each openapi_tag should have a description."""
    from app.main import app

    for tag in app.openapi_tags:
        assert "description" in tag
        assert len(tag["description"]) > 0


def test_app_has_description():
    """FastAPI app should have a description for OpenAPI docs."""
    from app.main import app

    assert app.description is not None
    assert len(app.description) > 0
    assert "LeoCRM" in app.description or "CRM" in app.description


def test_all_api_routes_have_tags():
    """All API routes should have at least one tag for OpenAPI grouping."""
    from app.main import app

    untagged = []
    for route in app.routes:
        if not hasattr(route, "methods") or not hasattr(route, "path"):
            continue
        if not route.path.startswith("/api/"):
            continue
        methods = route.methods - {"HEAD", "OPTIONS"} if route.methods else set()
        if not methods:
            continue
        tags = getattr(route, "tags", []) or []
        if not tags:
            untagged.append(f"{route.path} [{','.join(sorted(methods))}]")
    assert len(untagged) == 0, f"Routes without tags: {untagged}"


def test_key_routes_have_response_model():
    """Key routes should have response_model set for OpenAPI schema generation."""
    from app.main import app

    # Check that at least some routes have response_model
    routes_with_response_model = 0
    for route in app.routes:
        if not hasattr(route, "methods") or not hasattr(route, "path"):
            continue
        if not route.path.startswith("/api/"):
            continue
        response_model = getattr(route, "response_model", None)
        if response_model is not None:
            routes_with_response_model += 1
    assert routes_with_response_model >= 5, (
        f"Expected at least 5 routes with response_model, got {routes_with_response_model}"
    )


def test_auth_login_has_auth_response_model():
    """POST /api/v1/auth/login should have AuthResponse as response_model."""
    from app.main import app
    from app.schemas.auth import AuthResponse

    for route in app.routes:
        if (
            hasattr(route, "path")
            and route.path == "/api/v1/auth/login"
            and hasattr(route, "response_model")
        ):
            assert route.response_model == AuthResponse
            return
    pytest.fail("Route /api/v1/auth/login not found")


def test_health_has_health_response_model():
    """GET /api/v1/health should have HealthResponse as response_model."""
    from app.main import app
    from app.schemas.common import HealthResponse

    for route in app.routes:
        if (
            hasattr(route, "path")
            and route.path == "/api/v1/health"
            and hasattr(route, "response_model")
        ):
            assert route.response_model == HealthResponse
            return
    pytest.fail("Route /api/v1/health not found")


def test_api_documentation_md_exists():
    """docs/api-documentation.md should exist and have content."""
    doc_path = os.path.join(
        os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
        "docs",
        "api-documentation.md",
    )
    assert os.path.isfile(doc_path), "docs/api-documentation.md not found"
    with open(doc_path) as f:
        content = f.read()
    assert "LeoCRM API Documentation" in content
    assert "auth" in content.lower()
    assert "contacts" in content.lower()
    assert "plugins" in content.lower()
