from __future__ import annotations

import unittest
from copy import deepcopy
from datetime import UTC, datetime
from types import SimpleNamespace
from unittest.mock import patch

from app.rda.application.builders import (
    RDA_MAPPER_VERSION,
    RDA_SCHEMA_VERSION,
    build_rda_emergency_summary,
    build_rda_patient_summary,
    build_source_context_fingerprint,
)
from app.rda.application.models import GenerateRdaCommand, RdaGenerationResult, RdaStatusResult
from app.rda.domain.fhir_validation import RdaValidationResult
from app.rda.application.use_cases import GenerateCaseRdaUseCase
from app.rda.domain.models import RdaArtifactType, RdaFieldStatus, RdaJobState, RdaSectionTrace
from app.rda.infrastructure.repositories import MongoRdaArtifactRepository, MongoRdaJobStatusRepository
from app.services.rda_service import RdaService
from test.fixtures.rips_cases import base_rips_context


def _base_context() -> dict:
    context = base_rips_context()
    context.update(
        {
            "case_key": "CASE-001",
            "case_number": "CASE-001",
            "nombre_paciente": "Paciente Demo",
            "metadatos_hc": {
                **context.get("metadatos_hc", {}),
                "prestador_servicio": "Clinica Central",
                "motivo_consulta": "Dolor abdominal agudo",
                "triage": "II",
                "profesional_tratante": "Dra. Ana Torres",
            },
            "medicamentos_hc_display": ["CEFALEXINA 500 MG"],
            "procedimientos_factura": [{"codigo_cups": "895100", "descripcion": "Sutura simple"}],
            "ayudas_diagnosticas": [{"nombre": "RX tórax", "tipo": "imagen"}],
        }
    )
    context["factura"]["factura_json"]["proveedor"]["nombre"] = "Clinica Central"
    return context


def _trace_map(section_trace: list[RdaSectionTrace]) -> dict[str, RdaSectionTrace]:
    return {item.field_path: item for item in section_trace}


class FakeContextProvider:
    def __init__(self, context: dict):
        self.context = context
        self.calls = 0

    def get_case_context(self, username: str, case_key: str, *, regen: bool = False) -> dict:
        self.calls += 1
        return deepcopy(self.context)


class FakeRdaArtifactRepository:
    def __init__(self) -> None:
        self.items: dict[tuple[str, str, str], list[dict]] = {}
        self.stored_at = datetime(2026, 5, 9, 10, 30, tzinfo=UTC)

    def ensure_indexes(self) -> None:
        return None

    def get_latest(self, username: str, case_key: str, artifact_type: RdaArtifactType) -> dict | None:
        versions = self.items.get((username, case_key, artifact_type.value), [])
        return deepcopy(versions[-1]) if versions else None

    def save_version(
        self,
        *,
        username: str,
        case_key: str,
        artifact_type: RdaArtifactType,
        payload: dict,
        completeness_status: str,
        missing_fields: list[str],
        section_trace: list[dict],
        source_context: dict,
        source_context_fingerprint: str,
        schema_version: int,
        mapper_version: str,
        regen_requested: bool,
    ) -> dict:
        key = (username, case_key, artifact_type.value)
        versions = self.items.setdefault(key, [])
        document = {
            "case_key": case_key,
            "artifact_type": artifact_type.value,
            "version": len(versions) + 1,
            "schema_version": schema_version,
            "mapper_version": mapper_version,
            "fecha_analisis": self.stored_at,
            "payload": deepcopy(payload),
            "completeness_status": completeness_status,
            "missing_fields": list(missing_fields),
            "section_trace": deepcopy(section_trace),
            "source_context_fingerprint": source_context_fingerprint,
            "regen_requested": regen_requested,
        }
        versions.append(document)
        return deepcopy(document)


class FakeRdaJobStatusRepository:
    def __init__(self) -> None:
        self.statuses: dict[tuple[str, str, str], dict] = {}

    def ensure_indexes(self) -> None:
        return None

    def get_status(self, username: str, case_key: str, artifact_type: RdaArtifactType) -> dict | None:
        document = self.statuses.get((username, case_key, artifact_type.value))
        return deepcopy(document) if document else None

    def upsert_status(
        self,
        *,
        username: str,
        case_key: str,
        artifact_type: RdaArtifactType,
        status: str,
        job_id: str,
        error: str | None = None,
        source_context_fingerprint: str | None = None,
        resolved_version: int | None = None,
        reused: bool = False,
    ) -> dict:
        document = {
            "case_key": case_key,
            "artifact_type": artifact_type.value,
            "status": status,
            "job_id": job_id,
            "error": error or "",
            "source_context_fingerprint": source_context_fingerprint or "",
            "resolved_version": resolved_version,
            "reused": reused,
        }
        self.statuses[(username, case_key, artifact_type.value)] = document
        return deepcopy(document)


class FakeMongoCollection:
    def __init__(self) -> None:
        self.documents: list[dict] = []
        self.indexes: list[list[tuple[str, int]]] = []

    def create_index(self, keys: list[tuple[str, int]]) -> None:
        self.indexes.append(keys)

    def find_one(self, query: dict, sort: list[tuple[str, int]] | None = None) -> dict | None:
        matches = [
            item for item in self.documents if all(item.get(key) == value for key, value in query.items())
        ]
        if not matches:
            return None
        if sort:
            for key, direction in reversed(sort):
                matches.sort(key=lambda item, sort_key=key: item.get(sort_key), reverse=direction < 0)
        return deepcopy(matches[0])

    def insert_one(self, document: dict) -> None:
        self.documents.append(deepcopy(document))

    def update_one(self, query: dict, update: dict, upsert: bool = False) -> None:
        payload = deepcopy(update.get("$set", {}))
        for index, document in enumerate(self.documents):
            if all(document.get(key) == value for key, value in query.items()):
                self.documents[index] = {**document, **payload}
                return
        if upsert:
            self.documents.append({**deepcopy(query), **payload})


class FakeAuditLogger:
    def __init__(self) -> None:
        self.events: list[dict[str, object]] = []

    def business_event(self, **kwargs) -> None:
        self.events.append(kwargs)


class RdaBuildersTest(unittest.TestCase):
    def test_patient_summary_covers_demographics_and_traceability(self) -> None:
        context = _base_context()

        payload, section_trace, missing_fields = build_rda_patient_summary(context)
        traces = _trace_map(section_trace)

        self.assertEqual(payload["patient"]["name"], "Paciente Demo")
        self.assertEqual(payload["patient"]["document"], {"type": "CC", "number": "123456789"})
        self.assertEqual(payload["patient"]["birth_date"], "1990-01-15")
        self.assertEqual(payload["patient"]["sex"], "M")
        self.assertEqual(payload["organization"]["provider"], {"name": "Clinica Central", "nit": "900123456"})
        self.assertEqual(payload["organization"]["payer"], {"name": "EPS Demo", "nit": "800999111"})
        self.assertEqual(payload["diagnoses"], [{"code": "A080", "description": "Enteritis debida a virus"}])
        self.assertEqual(missing_fields, ["patient.clinical_background"])
        self.assertEqual(traces["patient.name"].status, RdaFieldStatus.DOCUMENTAL)
        self.assertEqual(traces["patient.document.number"].status, RdaFieldStatus.INFERIDO)
        self.assertEqual(traces["patient.birth_date"].primary_source, "metadatos_hc.fecha_nacimiento")
        self.assertEqual(traces["patient.sex"].primary_source, "metadatos_hc.sexo")
        self.assertEqual(traces["patient.clinical_background"].status, RdaFieldStatus.FALTANTE)
        self.assertEqual(traces["patient.clinical_background"].primary_source, "missing")
        self.assertEqual(
            sorted(missing_fields),
            sorted(
                trace.field_path for trace in section_trace if trace.status == RdaFieldStatus.FALTANTE
            ),
        )

    def test_patient_summary_prioritizes_clinical_source_and_marks_conflict(self) -> None:
        context = _base_context()
        context["metadatos_hc"]["datos_identificacion_paciente"] = "CC 123456789"
        context["factura"]["factura_json"]["informacion_paciente"]["numero_identificacion"] = "CC 987654321"

        payload, section_trace, missing_fields = build_rda_patient_summary(context)

        self.assertEqual(payload["patient"]["document"]["number"], "123456789")
        self.assertEqual(missing_fields, ["patient.clinical_background"])
        document_trace = next(item for item in section_trace if item.field_path == "patient.document.number")
        self.assertIn("Se priorizó", document_trace.conflict_note or "")
        self.assertEqual(document_trace.status, "inferido")

    def test_emergency_summary_covers_full_mapping_and_case_key_trace(self) -> None:
        context = _base_context()

        payload, section_trace, missing_fields = build_rda_emergency_summary(context)
        traces = _trace_map(section_trace)

        self.assertEqual(payload["patient"], {"name": "Paciente Demo", "document": {"type": "CC", "number": "123456789"}})
        self.assertEqual(
            payload["encounter"],
            {
                "case_key": "CASE-001",
                "case_number": "CASE-001",
                "admission_at": "2026-04-20 07:45",
                "reason": "Dolor abdominal agudo",
                "triage": "II",
                "responsible_professional": "Dra. Ana Torres",
                "provider": {"name": "Clinica Central", "nit": "900123456"},
                "payer": {"name": "EPS Demo", "nit": "800999111"},
            },
        )
        self.assertEqual(
            payload["clinical"]["diagnoses"],
            [{"code": "A080", "description": "Enteritis debida a virus"}],
        )
        self.assertEqual(
            payload["clinical"]["procedures"],
            [{"code": "895100", "description": "Sutura simple"}],
        )
        self.assertEqual(payload["clinical"]["medications"], ["CEFALEXINA 500 MG"])
        self.assertEqual(payload["clinical"]["diagnostic_support"], ["RX tórax"])
        self.assertEqual(missing_fields, [])
        self.assertEqual(traces["encounter.case_key"].primary_source, "context.case_key")
        self.assertEqual(traces["encounter.case_key"].status, RdaFieldStatus.DOCUMENTAL)
        self.assertEqual(traces["encounter.case_number"].status, RdaFieldStatus.DOCUMENTAL)
        self.assertEqual(traces["encounter.triage"].status, RdaFieldStatus.DOCUMENTAL)
        self.assertEqual(traces["encounter.responsible_professional"].status, RdaFieldStatus.DOCUMENTAL)
        self.assertEqual(traces["clinical.diagnoses"].status, RdaFieldStatus.INFERIDO)
        self.assertEqual(traces["clinical.procedures"].status, RdaFieldStatus.INFERIDO)
        self.assertEqual(traces["clinical.medications"].status, RdaFieldStatus.INFERIDO)
        self.assertEqual(traces["clinical.diagnostic_support"].status, RdaFieldStatus.INFERIDO)

    def test_emergency_summary_marks_missing_fields_for_absent_optional_sections(self) -> None:
        context = _base_context()
        context["metadatos_hc"].pop("triage", None)
        context["metadatos_hc"].pop("profesional_tratante", None)
        context["metadatos_hc"].pop("medico_responsable", None)
        context["medicamentos_hc_display"] = []
        context["procedimientos_factura"] = []
        context["ayudas_diagnosticas"] = []
        context["factura"]["factura_json"]["servicios_procedimientos"]["medicamentos"] = []
        context["factura"]["factura_json"]["servicios_procedimientos"]["procedimientos_quirurgicos"] = []

        payload, section_trace, missing_fields = build_rda_emergency_summary(context)
        traces = _trace_map(section_trace)

        self.assertEqual(payload["encounter"]["triage"], None)
        self.assertEqual(payload["encounter"]["responsible_professional"], None)
        self.assertEqual(payload["clinical"]["procedures"], [])
        self.assertEqual(payload["clinical"]["medications"], [])
        self.assertEqual(payload["clinical"]["diagnostic_support"], [])
        self.assertEqual(
            sorted(missing_fields),
            sorted(
                [
                    "encounter.triage",
                    "encounter.responsible_professional",
                    "clinical.procedures",
                    "clinical.medications",
                    "clinical.diagnostic_support",
                ]
            ),
        )
        for field_path in missing_fields:
            self.assertEqual(traces[field_path].status, RdaFieldStatus.FALTANTE)
        self.assertEqual(
            sorted(missing_fields),
            sorted(
                trace.field_path for trace in section_trace if trace.status == RdaFieldStatus.FALTANTE
            ),
        )

    def test_fingerprint_changes_when_schema_or_mapper_changes(self) -> None:
        context = _base_context()

        current = build_source_context_fingerprint(
            context,
            artifact_type=RdaArtifactType.PATIENT,
            schema_version=RDA_SCHEMA_VERSION,
            mapper_version=RDA_MAPPER_VERSION,
        )
        next_schema = build_source_context_fingerprint(
            context,
            artifact_type=RdaArtifactType.PATIENT,
            schema_version=RDA_SCHEMA_VERSION + 1,
            mapper_version=RDA_MAPPER_VERSION,
        )
        next_mapper = build_source_context_fingerprint(
            context,
            artifact_type=RdaArtifactType.PATIENT,
            schema_version=RDA_SCHEMA_VERSION,
            mapper_version="mapper-v2",
        )

        self.assertNotEqual(current, next_schema)
        self.assertNotEqual(current, next_mapper)


class GenerateCaseRdaUseCaseTest(unittest.TestCase):
    def test_execute_reuses_existing_artifact_when_fingerprint_matches(self) -> None:
        context = _base_context()
        provider = FakeContextProvider(context)
        artifacts = FakeRdaArtifactRepository()
        statuses = FakeRdaJobStatusRepository()
        use_case = GenerateCaseRdaUseCase(provider, artifacts, statuses)
        command = GenerateRdaCommand(
            username="tester",
            case_key="CASE-001",
            artifact_type=RdaArtifactType.PATIENT,
            force=False,
            persist=True,
        )

        first = use_case.execute(command)
        second = use_case.execute(command)

        self.assertEqual(first.source, "generated")
        self.assertEqual(second.source, "cache")
        self.assertEqual(first.version, 1)
        self.assertEqual(second.version, 1)
        self.assertEqual(provider.calls, 2)
        self.assertIsInstance(first, RdaGenerationResult)
        self.assertIsInstance(first.artifact_type, RdaArtifactType)
        self.assertTrue(all(isinstance(item, RdaSectionTrace) for item in first.section_trace))

    def test_execute_creates_new_version_when_source_context_changes(self) -> None:
        context = _base_context()
        provider = FakeContextProvider(context)
        artifacts = FakeRdaArtifactRepository()
        statuses = FakeRdaJobStatusRepository()
        use_case = GenerateCaseRdaUseCase(provider, artifacts, statuses)
        command = GenerateRdaCommand(
            username="tester",
            case_key="CASE-001",
            artifact_type=RdaArtifactType.PATIENT,
            force=False,
            persist=True,
        )

        initial = use_case.execute(command)
        provider.context["metadatos_hc"]["motivo_consulta"] = "Dolor torácico"
        provider.context["nombre_paciente"] = "Paciente Demo Actualizado"
        regenerated = use_case.execute(command)

        self.assertEqual(initial.version, 1)
        self.assertEqual(regenerated.version, 2)
        self.assertEqual(regenerated.source, "generated")
        self.assertNotEqual(initial.source_context_fingerprint, regenerated.source_context_fingerprint)

    def test_execute_creates_new_version_when_force_is_true(self) -> None:
        context = _base_context()
        provider = FakeContextProvider(context)
        artifacts = FakeRdaArtifactRepository()
        statuses = FakeRdaJobStatusRepository()
        use_case = GenerateCaseRdaUseCase(provider, artifacts, statuses)

        initial = use_case.execute(
            GenerateRdaCommand(
                username="tester",
                case_key="CASE-001",
                artifact_type=RdaArtifactType.EMERGENCY,
                force=False,
                persist=True,
            )
        )
        forced = use_case.execute(
            GenerateRdaCommand(
                username="tester",
                case_key="CASE-001",
                artifact_type=RdaArtifactType.EMERGENCY,
                force=True,
                persist=True,
            )
        )

        self.assertEqual(initial.version, 1)
        self.assertEqual(forced.version, 2)
        self.assertEqual(forced.source, "generated")

    def test_execute_creates_new_version_when_mapper_version_changes(self) -> None:
        context = _base_context()
        provider = FakeContextProvider(context)
        artifacts = FakeRdaArtifactRepository()
        statuses = FakeRdaJobStatusRepository()
        use_case = GenerateCaseRdaUseCase(provider, artifacts, statuses)
        command = GenerateRdaCommand(
            username="tester",
            case_key="CASE-001",
            artifact_type=RdaArtifactType.EMERGENCY,
            force=False,
            persist=True,
        )

        initial = use_case.execute(command)
        with patch("app.rda.application.use_cases.RDA_MAPPER_VERSION", "2026-05-rda-v2"):
            regenerated = use_case.execute(command)

        self.assertEqual(initial.version, 1)
        self.assertEqual(regenerated.version, 2)
        self.assertEqual(regenerated.source, "generated")
        self.assertNotEqual(initial.source_context_fingerprint, regenerated.source_context_fingerprint)
        self.assertEqual(regenerated.mapper_version, "2026-05-rda-v2")

    def test_execute_creates_new_version_when_schema_version_changes(self) -> None:
        context = _base_context()
        provider = FakeContextProvider(context)
        artifacts = FakeRdaArtifactRepository()
        statuses = FakeRdaJobStatusRepository()
        use_case = GenerateCaseRdaUseCase(provider, artifacts, statuses)
        command = GenerateRdaCommand(
            username="tester",
            case_key="CASE-001",
            artifact_type=RdaArtifactType.PATIENT,
            force=False,
            persist=True,
        )

        initial = use_case.execute(command)
        with patch("app.rda.application.use_cases.RDA_SCHEMA_VERSION", RDA_SCHEMA_VERSION + 1):
            regenerated = use_case.execute(command)

        self.assertEqual(initial.version, 1)
        self.assertEqual(regenerated.version, 2)
        self.assertEqual(regenerated.source, "generated")
        self.assertNotEqual(initial.source_context_fingerprint, regenerated.source_context_fingerprint)
        self.assertEqual(regenerated.schema_version, RDA_SCHEMA_VERSION + 1)

    def test_get_status_falls_back_to_completed_artifact(self) -> None:
        context = _base_context()
        provider = FakeContextProvider(context)
        artifacts = FakeRdaArtifactRepository()
        statuses = FakeRdaJobStatusRepository()
        use_case = GenerateCaseRdaUseCase(provider, artifacts, statuses)

        use_case.execute(
            GenerateRdaCommand(
                username="tester",
                case_key="CASE-001",
                artifact_type=RdaArtifactType.PATIENT,
            )
        )

        status = use_case.get_status("tester", "CASE-001", RdaArtifactType.PATIENT)

        self.assertIsNotNone(status)
        self.assertEqual(status.status, RdaJobState.COMPLETED)
        self.assertEqual(status.source, "artifact")
        self.assertEqual(status.updated_at, artifacts.stored_at)

    def test_generate_command_preserves_enum_types(self) -> None:
        command = GenerateRdaCommand(
            username="tester",
            case_key="CASE-001",
            artifact_type=RdaArtifactType.PATIENT,
        )

        self.assertIsInstance(command.artifact_type, RdaArtifactType)


class RdaServiceAuditTest(unittest.TestCase):
    def _build_service(self, *, use_case: object | None = None) -> tuple[RdaService, FakeAuditLogger]:
        service = RdaService.__new__(RdaService)
        audit_logger = FakeAuditLogger()
        service.audit_logger = audit_logger
        service.generate_case_rda_use_case = use_case or SimpleNamespace()
        service.validate_rda_fhir_projection_use_case = SimpleNamespace(
            execute=lambda artifact: RdaValidationResult.from_findings(
                artifact_type=artifact.artifact_type,
                findings=[],
            )
        )
        return service, audit_logger

    def test_get_latest_logs_read_miss_when_artifact_is_missing(self) -> None:
        use_case = SimpleNamespace(get_latest=lambda *args: None)
        service, audit_logger = self._build_service(use_case=use_case)

        result = service.get_latest_case_rda("tester", "CASE-001", RdaArtifactType.PATIENT)

        self.assertIsNone(result)
        self.assertEqual(audit_logger.events[-1]["event_type"], "rda.read_missing")
        self.assertEqual(audit_logger.events[-1]["outcome"], "not_found")
        self.assertEqual(audit_logger.events[-1]["resource"]["case_key"], "CASE-001")

    def test_get_case_rda_status_logs_successful_status_lookup(self) -> None:
        status_result = SimpleNamespace(
            status=RdaJobState.COMPLETED,
            job_id="job-123",
            resolved_version=2,
            source="status",
        )
        use_case = SimpleNamespace(get_status=lambda *args: status_result)
        service, audit_logger = self._build_service(use_case=use_case)

        result = service.get_case_rda_status("tester", "CASE-001", RdaArtifactType.PATIENT)

        self.assertIs(result, status_result)
        self.assertEqual(audit_logger.events[-1]["event_type"], "rda.status")
        self.assertEqual(audit_logger.events[-1]["resource"]["status"], "completed")
        self.assertEqual(audit_logger.events[-1]["resource"]["job_id"], "job-123")
        self.assertEqual(audit_logger.events[-1]["resource"]["resolved_version"], 2)

    def test_queue_case_rda_logs_reused_running_job(self) -> None:
        service, audit_logger = self._build_service()
        service.get_case_rda_status = lambda *args: SimpleNamespace(
            status=RdaJobState.PROCESSING,
            job_id="job-123",
        )

        result = service.queue_case_rda("tester", "CASE-001", RdaArtifactType.PATIENT, force=True)

        self.assertEqual(result.status, RdaJobState.PROCESSING)
        self.assertTrue(result.reused)
        self.assertEqual(audit_logger.events[-1]["event_type"], "rda.queue_reused")
        self.assertEqual(audit_logger.events[-1]["resource"]["status"], "processing")
        self.assertEqual(audit_logger.events[-1]["resource"]["reused"], True)

    def test_get_case_rda_validation_returns_status_without_artifact(self) -> None:
        status_result = RdaStatusResult(
            case_key="CASE-001",
            artifact_type=RdaArtifactType.PATIENT,
            status=RdaJobState.QUEUED,
            job_id="job-123",
            source="status",
        )
        use_case = SimpleNamespace(
            get_latest=lambda *args: None,
            get_status=lambda *args: status_result,
        )
        service, audit_logger = self._build_service(use_case=use_case)

        result = service.get_case_rda_validation("tester", "CASE-001", RdaArtifactType.PATIENT)

        self.assertIsNotNone(result)
        assert result is not None
        self.assertIsNone(result.artifact)
        self.assertIs(result.status, status_result)
        self.assertIsNone(result.validation)
        self.assertEqual(audit_logger.events[-1]["event_type"], "rda.validation_read")
        self.assertFalse(audit_logger.events[-1]["resource"]["has_artifact"])
        self.assertTrue(audit_logger.events[-1]["resource"]["has_status"])

    def test_get_case_rda_validation_logs_missing_when_no_artifact_or_status_exist(self) -> None:
        use_case = SimpleNamespace(
            get_latest=lambda *args: None,
            get_status=lambda *args: None,
        )
        service, audit_logger = self._build_service(use_case=use_case)

        result = service.get_case_rda_validation("tester", "CASE-001", RdaArtifactType.PATIENT)

        self.assertIsNone(result)
        self.assertEqual(audit_logger.events[-1]["event_type"], "rda.validation_missing")


class MongoRdaRepositoriesTest(unittest.TestCase):
    def test_artifact_repository_persists_traceability_metadata(self) -> None:
        collection = FakeMongoCollection()
        repository = MongoRdaArtifactRepository(SimpleNamespace(collection=collection), UTC)
        context = _base_context()
        fingerprint = build_source_context_fingerprint(context, artifact_type=RdaArtifactType.PATIENT)

        saved = repository.save_version(
            username="tester",
            case_key="CASE-001",
            artifact_type=RdaArtifactType.PATIENT,
            payload={"summary_type": "patient"},
            completeness_status="partial",
            missing_fields=["patient.clinical_background"],
            section_trace=[
                {
                    "field_path": "patient.name",
                    "status": "documental",
                    "primary_source": "context.nombre_paciente",
                }
            ],
            source_context=context,
            source_context_fingerprint=fingerprint,
            schema_version=1,
            mapper_version="mapper-v1",
            regen_requested=False,
        )

        self.assertEqual(saved["tipo_documento"], "rda_case_artifact")
        self.assertEqual(saved["artifact_type"], "patient")
        self.assertEqual(saved["source_document_count"], 3)
        self.assertEqual(saved["missing_field_count"], 1)
        self.assertEqual(
            saved["source_document_ids"],
            {
                "historia_id": "hist-1",
                "quirurgico_id": "qx-1",
                "factura_id": "fac-1",
            },
        )
        self.assertEqual(saved["source_context_fingerprint"], fingerprint)
        self.assertEqual(saved["schema_version"], 1)
        self.assertEqual(saved["mapper_version"], "mapper-v1")
        self.assertFalse(saved["regen_requested"])
        self.assertEqual(
            saved["persistence_metadata"],
            {
                "schema_version": 1,
                "mapper_version": "mapper-v1",
                "artifact_type": "patient",
            },
        )

    def test_job_status_repository_upserts_mutable_status(self) -> None:
        collection = FakeMongoCollection()
        repository = MongoRdaJobStatusRepository(SimpleNamespace(collection=collection), UTC)

        repository.upsert_status(
            username="tester",
            case_key="CASE-001",
            artifact_type=RdaArtifactType.EMERGENCY,
            status=RdaJobState.QUEUED.value,
            job_id="job-1",
            reused=False,
        )
        updated = repository.upsert_status(
            username="tester",
            case_key="CASE-001",
            artifact_type=RdaArtifactType.EMERGENCY,
            status=RdaJobState.COMPLETED.value,
            job_id="job-1",
            resolved_version=2,
            reused=True,
        )

        self.assertEqual(updated["status"], "completed")
        self.assertEqual(updated["resolved_version"], 2)
        self.assertTrue(updated["reused"])
        self.assertEqual(updated["job_id"], "job-1")
        self.assertIsNotNone(updated["updated_at"])
