import unittest
from typing import Any

from app.modules.dossier.application.dossier_report_service import DossierReportService


class StubQdrantStore:
    def __init__(self, results=None, error: Exception | None = None):
        self._results = list(results or [])
        self._error = error

    def scroll(self, *, limit: int = 100, filters: dict[str, Any] | None = None):
        if self._error is not None:
            raise self._error
        return list(self._results)


class DossierReportServiceBehaviorAuditTests(unittest.TestCase):
    def test_build_project_report_deduplicates_document_types_from_scroll_results(
        self,
    ) -> None:
        service = DossierReportService(
            StubQdrantStore(
                results=[
                    {
                        "id": "1",
                        "metadata": {
                            "project_code": "PRJ-001",
                            "document_type": "hop_dong",
                            "doc_stage": "contracting",
                            "source_filename": "hop_dong_01.docx",
                            "doc_family": "contract",
                            "task_type": "contract_management",
                            "readiness_weight": 1.0,
                        },
                    },
                    {
                        "id": "2",
                        "metadata": {
                            "project_code": "PRJ-001",
                            "document_type": "hop_dong",
                            "doc_stage": "contracting",
                            "source_filename": "hop_dong_02.docx",
                        },
                    },
                ]
            )
        )

        report = service.build_project_report("PRJ-001")

        self.assertEqual(report["project_code"], "PRJ-001")
        self.assertIn("contracting", report["documents_present"])
        self.assertEqual(report["documents_present"]["contracting"], ["hop_dong"])
        self.assertIn("hop_dong", report["document_index"])

    def test_build_project_report_returns_safe_empty_report_when_qdrant_scroll_fails(
        self,
    ) -> None:
        service = DossierReportService(
            StubQdrantStore(error=RuntimeError("qdrant unavailable"))
        )

        report = service.build_project_report("PRJ-ERR")

        self.assertEqual(report["project_code"], "PRJ-ERR")
        self.assertEqual(report["source"], "fallback")
        self.assertTrue(report["used_fallback"])
        self.assertIn("Qdrant", report["message"])
        self.assertEqual(report["documents_present"], {})
        self.assertEqual(report["document_index"], {})
        self.assertIn("readiness", report)
        self.assertIn("summary", report)

    def test_build_project_report_handles_missing_metadata_shape_safely(self) -> None:
        service = DossierReportService(
            StubQdrantStore(
                results=[
                    {"id": "1"},
                    {"id": "2", "metadata": None},
                    {"id": "3", "metadata": {"project_code": "PRJ-002"}},
                    {
                        "id": "4",
                        "metadata": {
                            "project_code": "PRJ-002",
                            "document_type": "bien_ban_nghiem_thu_noi_bo",
                            "doc_stage": "finalization",
                            "source_filename": "bbntnb.docx",
                        },
                    },
                ]
            )
        )

        report = service.build_project_report("PRJ-002")

        self.assertEqual(report["project_code"], "PRJ-002")
        self.assertIn("finalization", report["documents_present"])
        self.assertIn(
            "bien_ban_nghiem_thu_noi_bo",
            report["documents_present"]["finalization"],
        )
        self.assertIn("readiness", report)
        self.assertIn("summary", report)


if __name__ == "__main__":
    unittest.main()
