from __future__ import annotations

from collections.abc import Generator

from auth_helpers import install_legacy_header_auth_override
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import Session, sessionmaker
from sqlalchemy.pool import StaticPool

from app.api.deps import get_db
from app.db.base import Base
from app.main import create_app
from app.schemas.ocr import OcrRecognizeDocumentRead
from app.services.ocr import OcrService


def build_client() -> TestClient:
    engine = create_engine(
        "sqlite+pysqlite:///:memory:",
        connect_args={"check_same_thread": False},
        poolclass=StaticPool,
    )
    Base.metadata.create_all(bind=engine)
    session_factory = sessionmaker(bind=engine, autoflush=False, autocommit=False)
    app = create_app()
    install_legacy_header_auth_override(app)

    def override_db() -> Generator[Session, None, None]:
        db = session_factory()
        try:
            yield db
        finally:
            db.close()

    app.dependency_overrides[get_db] = override_db
    return TestClient(app)


def _seed_ocr_cache() -> None:
    OcrService._write_cached_document(
        "pytest-cache-key",
        OcrRecognizeDocumentRead(
            filename="receipt.pdf",
            media_type="application/pdf",
            text="旧 OCR 缓存",
            summary="旧 OCR 缓存",
        ),
    )


def test_clear_settings_cache_endpoint_clears_ocr_result_cache() -> None:
    OcrService.clear_result_cache()
    _seed_ocr_cache()
    assert len(OcrService._result_cache) == 1

    client = build_client()
    response = client.post(
        "/api/v1/settings/cache/clear",
        headers={
            "x-auth-username": "admin",
            "x-auth-name": "Admin",
            "x-auth-is-admin": "true",
        },
    )

    assert response.status_code == 200
    payload = response.json()
    assert payload["totalCleared"] >= 1
    assert {
        "cacheKey": "ocr_result_cache",
        "label": "OCR 识别结果缓存",
        "clearedCount": 1,
    } in payload["items"]
    assert len(OcrService._result_cache) == 0


def test_clear_settings_cache_endpoint_requires_admin() -> None:
    OcrService.clear_result_cache()
    _seed_ocr_cache()

    client = build_client()
    response = client.post(
        "/api/v1/settings/cache/clear",
        headers={
            "x-auth-username": "ordinary-user",
            "x-auth-name": "Ordinary User",
        },
    )

    assert response.status_code == 403
    assert len(OcrService._result_cache) == 1
    OcrService.clear_result_cache()
