from __future__ import annotations

import unittest
from copy import deepcopy
from typing import Any

from app.services.demo_identity_service import DemoIdentityService


class FakeDemoIdentityCollection:
    def __init__(self) -> None:
        self.documents: list[dict[str, Any]] = []

    def create_index(self, *args, **kwargs) -> None:
        return None

    def find_one(self, query: dict[str, Any]) -> dict[str, Any] | None:
        for document in self.documents:
            if all(document.get(key) == value for key, value in query.items()):
                return deepcopy(document)
        return None

    def find_one_and_update(self, query: dict[str, Any], update: dict[str, Any], upsert: bool, return_document):
        for index, document in enumerate(self.documents):
            if all(document.get(key) == value for key, value in query.items()):
                if "$inc" in update:
                    for key, value in update["$inc"].items():
                        document[key] = int(document.get(key) or 0) + int(value)
                self.documents[index] = document
                return deepcopy(document)

        if not upsert:
            return None

        document = dict(query)
        for key, value in update.get("$setOnInsert", {}).items():
            document.setdefault(key, value)
        for key, value in update.get("$inc", {}).items():
            document[key] = int(document.get(key) or 0) + int(value)
        self.documents.append(document)
        return deepcopy(document)


class DemoIdentityServiceTest(unittest.TestCase):
    def setUp(self) -> None:
        self.collection = FakeDemoIdentityCollection()
        self.service = DemoIdentityService(self.collection, enabled=True)

    def test_projects_stable_aliases_for_same_case(self) -> None:
        first = self.service.project_case_identity(
            username="auditor",
            case_key="93387170-178474-julio-cesar-acosta-guevara",
            case_number="178474",
            patient_id="93387170",
            patient_name="JULIO CESAR ACOSTA GUEVARA",
        )
        second = self.service.project_case_identity(
            username="auditor",
            case_key="93387170-178474-julio-cesar-acosta-guevara",
            case_number="178474",
            patient_id="93387170",
            patient_name="JULIO CESAR ACOSTA GUEVARA",
        )

        self.assertEqual(first["case_key"], second["case_key"])
        self.assertEqual(first["patient_id"], "00001")
        self.assertEqual(first["patient_name"], "paciente-01")
        self.assertEqual(
            self.service.resolve_case_key(username="auditor", visible_case_key=first["case_key"]),
            "93387170-178474-julio-cesar-acosta-guevara",
        )

    def test_project_document_sanitizes_nested_visible_content(self) -> None:
        payload = {
            "_id": "doc-1",
            "case_key": "93387170-178474-julio-cesar-acosta-guevara",
            "case_number": "178474",
            "patient_id": "93387170",
            "nombre_paciente": "JULIO CESAR ACOSTA GUEVARA",
            "analisis_html": "<p>Paciente JULIO CESAR ACOSTA GUEVARA identificado con 93387170.</p>",
            "diagnosticos_extraidos": ["Paciente JULIO CESAR ACOSTA GUEVARA", "CC 93387170"],
        }

        projected = self.service.project_document(username="auditor", document=payload)

        self.assertIsNotNone(projected)
        projected = projected or {}
        self.assertEqual(projected["patient_id"], "00001")
        self.assertEqual(projected["nombre_paciente"], "paciente-01")
        self.assertNotIn("93387170", projected["analisis_html"])
        self.assertNotIn("JULIO CESAR ACOSTA GUEVARA", projected["analisis_html"])
        self.assertIn("paciente-01", projected["analisis_html"])
