from __future__ import annotations

import unittest

from app.services.historia_medicamentos import (
    extract_valle_salud_medications,
    medication_from_legacy,
    reconcile_case_medications,
)


VALLE_SALUD_MEDICATION_TEXT = """
Inversiones Médicas Valle Salud S.A.S
Ordenes Generadas en Historias Clinicas
Codigo   Descripcion                                                   Observacion   Cant
HOSPITALIZACION 07/05/2024 15:52
 5656     DIPIRONA 1.0 G/2ML SOLUCION INYECTABLE 2 gr INTRAVENOSA                 6
          Cada 8 Horas por 1 Dia(s)
 6491     TRAMADOL CLORHIDRATO AMPOLLAS 50 MG / 1 ML SOLUCION                     2
          INYECTABLE 50 mg INTRAVENOSA Cada 12 Horas por 1 Dia(s)
 6129     OMEPRAZOL 40 MG AMPOLLAS SOLUCION INYECTABLE 40 mg                      1
          INTRAVENOSA Cada 24 Horas por 1 Dia(s)
CIRUGIA 09/05/2024 09:45
 5138     (C)_FENTANILO CITRATO 0.5 MG/10ML SOLUCION INYECTABLE 0.05 mg            1
          INTRAVENOSA AHORA
 5926     JERINGA 10ML                                                            3
Hoja de Drogas
Medicamento Frecuencia Vía Aplicación Dosis Ap FechaHora Prof. Administra
 DIPIRONA 1.0 G/2ML SOLUCION 2 gr INTRAVENOSA Cada INTRAVENOSA 2 gr 08/05/2024
 INYECTABLE Horas por 1 Dia(s) 08:00
 TRAMADOL CLORHIDRATO 50 mg INTRAVENOSA Cada INTRAVENOSA 50 mg 08/05/2024
 AMPOLLAS 50 MG / 1 ML 12 Horas por 1 Dia(s) 10:00
"""


class ValleSaludMedicationExtractionTest(unittest.TestCase):
    def test_extracts_regimens_without_interleaving_status_as_name(self) -> None:
        medications = extract_valle_salud_medications(VALLE_SALUD_MEDICATION_TEXT)

        names = [item["nombre"] for item in medications]
        self.assertIn("Dipirona", names)
        self.assertIn("Tramadol Clorhidrato", names)
        self.assertIn("Fentanilo Citrato", names)
        self.assertNotIn("Administrado", names)
        self.assertNotIn("Formulado", names)
        self.assertFalse(any("Jeringa" in name for name in names))

        dipyrone = next(item for item in medications if item["nombre"] == "Dipirona")
        fentanyl = next(item for item in medications if item["nombre"] == "Fentanilo Citrato")
        self.assertEqual(dipyrone["posologia"], "INTRAVENOSA Cada 8 Horas por 1 Dia(s)")
        self.assertEqual(dipyrone["dosis"], "2 gr")
        self.assertEqual(dipyrone["cantidad"], 6)
        self.assertEqual(dipyrone["estados"], ["administrado", "ordenado"])
        self.assertEqual(fentanyl["estados"], ["ordenado"])

    def test_reconciles_invoice_quantities_and_keeps_cum_out_of_dose(self) -> None:
        clinical = extract_valle_salud_medications(VALLE_SALUD_MEDICATION_TEXT)
        invoice = [
            {
                "codigo_facturacion": "5656",
                "codigo_referencia": "19993038-8",
                "medicamento": "DIPIRONA 1.0 G/2ML SOLUCION INYECTABLE",
                "cantidad": amount,
            }
            for amount in ("6.00", "6.00", "4.00")
        ]
        reconciled = reconcile_case_medications(clinical, invoice)
        dipyrone = next(item for item in reconciled if item["nombre"] == "Dipirona")

        self.assertEqual(dipyrone["cantidad"], 16)
        self.assertEqual(dipyrone["dosis"], "2 gr")
        self.assertEqual(dipyrone["codigo_referencia"], "19993038-8")
        self.assertEqual(dipyrone["codigo_facturacion"], "5656")
        self.assertIn("facturado", dipyrone["estados"])

    def test_parses_new_manual_format_and_preserves_legacy_format(self) -> None:
        manual = medication_from_legacy(
            "Dipirona | intravenosa cada 8 horas | 1 g | 2 | administrado",
            fuente="manual",
        )
        legacy = medication_from_legacy("5656 - 2 ampollas - Dipirona - 1 g IV", fuente="manual")

        assert manual is not None
        assert legacy is not None
        self.assertEqual(manual["nombre"], "Dipirona")
        self.assertEqual(manual["cantidad"], 2)
        self.assertEqual(manual["estados"], ["administrado"])
        self.assertEqual(legacy["nombre"], "Dipirona")
        self.assertEqual(legacy["cantidad"], 2)
