from __future__ import annotations

import unittest
from tempfile import TemporaryDirectory
from unittest.mock import patch

from fastapi import FastAPI
from fastapi.testclient import TestClient
from sqlalchemy import BigInteger, create_engine
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.orm import Session, sessionmaker
from sqlalchemy.pool import StaticPool

import app.models.document_archive  # noqa: E402,F401
import app.models.master_data  # noqa: E402,F401
import app.models.miniapp  # noqa: E402,F401
import app.models.operations  # noqa: E402,F401
import app.models.org  # noqa: E402,F401
import app.models.planning  # noqa: E402,F401
import app.models.sales  # noqa: E402,F401
from app.api.routes.document_archives import normalize_document_type_key, router  # noqa: E402
from app.db.session import get_db  # noqa: E402
from app.models.base import Base  # noqa: E402
from app.services.auth import require_authenticated_user  # noqa: E402


@compiles(BigInteger, "sqlite")
def _compile_big_integer_for_sqlite(type_, compiler, **kw) -> str:
    _ = type_, compiler, kw
    return "INTEGER"


class DocumentArchiveRouteTest(unittest.TestCase):
    def setUp(self) -> None:
        engine = create_engine(
            "sqlite+pysqlite:///:memory:",
            connect_args={"check_same_thread": False},
            poolclass=StaticPool,
            future=True,
        )
        Base.metadata.create_all(engine)
        self.SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False, future=True)

        app = FastAPI()
        app.include_router(router, prefix="/document-archives")

        def override_get_db() -> Session:
            db = self.SessionLocal()
            try:
                yield db
            finally:
                db.close()

        def override_require_authenticated_user() -> dict[str, int]:
            return {"user_id": 123}

        app.dependency_overrides[get_db] = override_get_db
        app.dependency_overrides[require_authenticated_user] = override_require_authenticated_user
        self.client = TestClient(app)

    def test_normalize_document_type_key_supports_route_keys(self) -> None:
        self.assertEqual(normalize_document_type_key("sales-order"), "销售订单")
        self.assertEqual(normalize_document_type_key("purchase-order"), "采购订单")
        self.assertEqual(normalize_document_type_key("quality-inspection"), "质量校验单")
        self.assertEqual(normalize_document_type_key("production-material-out"), "生产领料出库单")
        self.assertEqual(normalize_document_type_key("production-inbound-settlement"), "生产入库结算单")
        self.assertEqual(normalize_document_type_key("warehouse-operation"), "仓库出入库单")
        self.assertEqual(normalize_document_type_key("仓库出入库单"), "仓库出入库单")

    def test_preview_missing_archive_returns_chinese_404(self) -> None:
        response = self.client.get("/document-archives/sales-order/999/latest/preview")

        self.assertEqual(response.status_code, 404)
        self.assertIn("归档文件不存在", response.json()["detail"])

    def test_batch_download_missing_archives_returns_chinese_404(self) -> None:
        with TemporaryDirectory() as tmp_dir, patch("app.api.routes.document_archives.default_archive_root", return_value=tmp_dir):
            response = self.client.post(
                "/document-archives/batch-download",
                json={"document_type": "sales-order", "business_ids": [999]},
            )

        self.assertEqual(response.status_code, 404)
        self.assertIn("没有可下载的归档文件", response.json()["detail"])


if __name__ == "__main__":
    unittest.main()
