using adas_core.Application.Customizations.HPAZ;
using adas_core.Application.Services.Interfaces;
using adas_core.Domain.Enums;
using adas_core.Domain.Models;
using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Models.Pumps;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using Moq;
using Options = Microsoft.Extensions.Options.Options;

namespace adas_core.Test.Customizations.HPAZ;

[TestFixture]
public class CalculatedObservationsTest
{
    /// <summary>
    /// Initializes mocked dependencies and configures the dependency injection container required to instantiate the <see cref="CalculatedObservations"/> service under test.
    /// </summary>
    [SetUp]
        public void Setup()
        {
            _alarmServiceMock = new Mock<IAlarmService>();
            var alarmServiceLazy = new Lazy<IAlarmService>(() => _alarmServiceMock.Object);
    
    
            _patientServiceMock = new Mock<IPatientService>();
    
            _lightBeaconServiceMock = new Mock<ILightBeaconService>();
            var balizaServiceLazy = new Lazy<ILightBeaconService>(() => _lightBeaconServiceMock.Object);
    
            _recordingServiceMock = new Mock<IRecordingService>();
            var recordingServiceLazy = new Lazy<IRecordingService>(() => _recordingServiceMock.Object);
    
            _relayServiceMock = new Mock<IRelayService>();
            var relayServiceLazy = new Lazy<IRelayService>(() => _relayServiceMock.Object);
    
            _treatmentServiceMock = new Mock<ITreatmentService>();
            var treatmentServiceLazy = new Lazy<ITreatmentService>(() => _treatmentServiceMock.Object);
    
            _medicineServiceMock = new Mock<IMedicineService>();
            var medicineServiceLazy = new Lazy<IMedicineService>(() => _medicineServiceMock.Object);
    
            _configObservationServiceMock = new Mock<IConfigObservationService>();
    
    
            _observationServiceMock = new Mock<IObservationService>();
            var observationServiceLazy = new Lazy<IObservationService>(() => _observationServiceMock.Object);
    
            _logger = new Mock<ILogger<CalculatedObservations>>();
    
            _optionsApiSettings = Options.Create(_apiSettings);
    
            _optionsApiSettings.Value.IgnoreCalcObservationsOlderInMinutesThan = 5;
    
            _optionsRecordingSettings = Options.Create(_recordingSettings);
    
            var serviceCollection = new ServiceCollection();
            serviceCollection.AddSingleton(_patientServiceMock.Object);
            serviceCollection.AddSingleton(balizaServiceLazy);
            serviceCollection.AddSingleton(recordingServiceLazy);
            serviceCollection.AddSingleton(relayServiceLazy);
            serviceCollection.AddSingleton(treatmentServiceLazy);
            serviceCollection.AddSingleton(medicineServiceLazy);
            serviceCollection.AddSingleton(_configObservationServiceMock.Object);
            serviceCollection.AddSingleton(observationServiceLazy);
            serviceCollection.AddSingleton(_optionsApiSettings);
            serviceCollection.AddSingleton(_optionsRecordingSettings);
            serviceCollection.AddSingleton(_logger.Object);
            serviceCollection.AddSingleton(alarmServiceLazy);
    
            var serviceProvider = serviceCollection.BuildServiceProvider();
    
            _calculatedObservations = new CalculatedObservations(serviceProvider);
        }

    private CalculatedObservations _calculatedObservations;
    private Mock<IPatientService> _patientServiceMock;
    private Mock<ILightBeaconService> _lightBeaconServiceMock;
    private Mock<IRecordingService> _recordingServiceMock;
    private Mock<IRelayService> _relayServiceMock;
    private Mock<ITreatmentService> _treatmentServiceMock;
    private Mock<IMedicineService> _medicineServiceMock;
    private Mock<IConfigObservationService> _configObservationServiceMock;
    private Mock<IObservationService> _observationServiceMock;
    private Mock<IAlarmService> _alarmServiceMock;
    private Mock<ILogger<CalculatedObservations>> _logger;

    private readonly ApiSettings _apiSettings = new()
    {
        VolumetricAirOcclusionAlarm = ["Occlusion", "Upstream Occlusion"]
    };

    private IOptions<ApiSettings> _optionsApiSettings;
    private readonly RecordingSettings _recordingSettings = new();
    private IOptions<RecordingSettings> _optionsRecordingSettings;

    private readonly List<string> _pressBloodArteryMean = ["TAm"];


    private static readonly DateTime Now = DateTime.Now;
    private static readonly ObjectId PatientId = ObjectId.GenerateNewId();


    /// <summary>
    /// Verifies that a PatientObservation with the ventilation mode "PRVC" is mapped to a calculated observation with the value "VCRP".
    /// </summary>
    [Test]
        public async Task Calculate_Ventilation_Mode_PRVC_Returns_VCRP()
        {
            var patientId = ObjectId.GenerateNewId();
    
            var observation = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Value = "PRVC",
                Name = "Resp_Mode"
            };
    
            var result = await _calculatedObservations.Map(observation, false);
    
            Assert.That(result, Is.Not.Null);
            Assert.That(result!.Value, Is.EqualTo("VCRP"));
        }

    /// <summary>
    /// Verifies that the calculated observations mapping translates the ventilation mode value "FLUJ.ALTO" (High Flow) into the respiratory support code "OAF".
    /// Ensures that a patient observation with the name "Resp_Mode" and value "FLUJ.ALTO" produces a non-null mapped result with the expected output value.
    /// </summary>
    [Test]
        public async Task Calculate_Ventilation_Mode_FLUJ_ALTO_Returns_OAF()
        {
            var patientId = ObjectId.GenerateNewId();
    
            var observation = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Value = "FLUJ.ALTO",
                Name = "Resp_Mode"
            };
    
            var result = await _calculatedObservations.Map(observation, false);
    
            Assert.That(result, Is.Not.Null);
            Assert.That(result!.Value, Is.EqualTo("OAF"));
        }

    /// <summary>
    /// Verifies that when a patient observation's respiratory mode is neither "PRVC" nor "FLUJ_ALTO" (for example, "VNI PC"), the calculated observation is not mapped to "VCRP" or "OAF".
    /// </summary>
    [Test]
        public async Task Calculate_Ventilation_Mode_Not_PRVC_Not_FLUJ_ALTO_Returns_Other()
        {
            var patientId = ObjectId.GenerateNewId();
    
            var observation = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Value = "VNI PC",
                Name = "Resp_Mode"
            };
    
            var result = await _calculatedObservations.Map(observation, false);
    
            Assert.That(result, Is.Not.Null);
            using (Assert.EnterMultipleScope())
            {
                Assert.That(result!.Value, Is.Not.EqualTo("VCRP"));
                Assert.That(result.Value, Is.Not.EqualTo("OAF"));
            }
    
        }


    /// <summary>
    /// Verifies that the calculated observations mapping does not produce a Sattc_FiO2 observation
    /// when the Sattc value is 98, ensuring the calculation is suppressed for this specific input case.
    /// </summary>
    [Test]
        public async Task CalculateSF_Sattc_98_Returns_Not_Sattc_FiO2()
        {
            var patientId = ObjectId.GenerateNewId();
    
            var observation = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "Sattc",
                Value = 98
            };
    
            var obsLast = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "FiO2",
                Value = 34
            };
    
            var value = 96.0 / 34.0;
            value = Math.Round(value, 4);
    
            var obsCalculate = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "Sattc_FiO2",
                CodingSystem = "ADAS",
                Value = value
            };
    
            _observationServiceMock
                .Setup(l => l.FindLastObservations(It.IsAny<ObjectId>(), It.IsAny<int>(), It.IsAny<List<string>>()))
                .ReturnsAsync([obsLast]);
    
            await _calculatedObservations.Map(observation, false);
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.Is<PatientObservation>(arg =>
                arg.Name == obsCalculate.Name &&
                Math.Abs(double.Parse(arg.Value.ToString()!) - double.Parse(obsCalculate.Value.ToString()!)) <= 0 &&
                arg.PatientId == patientId
                && arg.CodingSystem == obsCalculate.CodingSystem
            ), true, true), Times.Never);
        }

    /// <summary>
    /// Verifies that when an FiO2 observation is processed, the Oxygenation Index is calculated and inserted
    /// using the related P_VAM and PaO2_Tidal observations retrieved for the same patient.
    /// </summary>
    [Test]
        public async Task CalculateOxygenationIndex_FiO2_Returns_Oxygenation_Index()
        {
            var patientId = ObjectId.GenerateNewId();
    
            var obsFio2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "FiO2",
                Value = 34
            };
    
            var obsPVam = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "P_VAM",
                Value = 6
            };
    
            var obsPaO2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "PaO2_Tidal",
                Value = 234
            };
    
            const int value = 6 * 34 * 100 / 234;
    
            var obsCalculate = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "Oxygenation_Index",
                CodingSystem = "ADAS",
                Value = value
            };
    
            _observationServiceMock
                .Setup(l => l.FindLastObservations(It.IsAny<ObjectId>(), It.IsAny<int>(), It.IsAny<List<string>>()))
                .ReturnsAsync([obsPVam, obsPaO2]);
    
            await _calculatedObservations.Map(obsFio2, false);
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.Is<PatientObservation>(arg =>
                arg.Name == obsCalculate.Name && arg.Value.ToString() == obsCalculate.Value.ToString() &&
                arg.PatientId == patientId
                && arg.CodingSystem == obsCalculate.CodingSystem
            ), true, true));
        }

    /// <summary>
    /// Verifies that mapping a <c>P_VAM</c> patient observation produces a derived <c>Oxygenation_Index</c> observation
    /// (computed as <c>P_VAM × FiO2 × 100 / PaO2</c>) that is inserted through the observation service for the same patient.
    /// </summary>
    /// <returns>A task that completes when the expected <c>Oxygenation_Index</c> observation has been inserted via the mocked observation service.</returns>
    [Test]
        public async Task CalculateOxygenationIndex_P_VAM_Returns_Oxygenation_Index()
        {
            var patientId = ObjectId.GenerateNewId();
    
            var obsFiO2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "FiO2",
                Value = 34
            };
    
            var obsPVam = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "P_VAM",
                Value = 6
            };
    
            var obsPaO2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "PaO2_Tidal",
                Value = 234
            };
    
            var value = 6 * 34 * 100 / 234;
    
            var obsCalculate = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "Oxygenation_Index",
                CodingSystem = "ADAS",
                Value = value
            };
    
            _observationServiceMock
                .Setup(l => l.FindLastObservations(It.IsAny<ObjectId>(), It.IsAny<int>(), It.IsAny<List<string>>()))
                .ReturnsAsync([obsFiO2, obsPaO2]);
    
            await _calculatedObservations.Map(obsPVam, false);
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.Is<PatientObservation>(arg =>
                arg.Name == obsCalculate.Name && arg.Value.ToString() == obsCalculate.Value.ToString() &&
                arg.PatientId == patientId
                && arg.CodingSystem == obsCalculate.CodingSystem
            ), true, true));
        }

    /// <summary>
    /// Verifies that when a PaO2_Tidal observation is mapped, the calculated Oxygenation_Index is derived using the formula P_VAM * FiO2 * 100 / PaO2_Tidal and persisted as an ADAS-coded observation for the same patient.
    /// </summary>
    [Test]
        public async Task CalculateOxygenationIndex_PaO2_Tidal_Returns_Oxygenation_Index()
        {
            var patientId = ObjectId.GenerateNewId();
    
            var obsFiO2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "FiO2",
                Value = 34
            };
    
            var obsPVam = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "P_VAM",
                Value = 6
            };
    
            var obsPaO2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "PaO2_Tidal",
                Value = 234
            };
    
            var value = 6 * 34 * 100 / 234;
    
            var obsCalculate = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "Oxygenation_Index",
                CodingSystem = "ADAS",
                Value = value
            };
    
            _observationServiceMock
                .Setup(l => l.FindLastObservations(It.IsAny<ObjectId>(), It.IsAny<int>(), It.IsAny<List<string>>()))
                .ReturnsAsync([obsFiO2, obsPVam]);
    
            await _calculatedObservations.Map(obsPaO2, false);
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.Is<PatientObservation>(arg =>
                arg.Name == obsCalculate.Name && arg.Value.ToString() == obsCalculate.Value.ToString() &&
                arg.PatientId == patientId
                && arg.CodingSystem == obsCalculate.CodingSystem
            ), true, true));
        }

    /// <summary>
    /// Verifies that the oxygenation index is not calculated and persisted when the required FiO2 observation
    /// is missing from the patient's most recent observations, even when a PaO2_Tidal observation is provided.
    /// Ensures that the mapping logic does not insert a new Oxygenation_Index observation in this scenario.
    /// </summary>
    [Test]
        public async Task CalculateOxygenationIndex_PaO2_Tidal_Not_Returns_Oxygenation_Index()
        {
            var patientId = ObjectId.GenerateNewId();
    
            var obsFiO2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "FiO2",
                Value = 34
            };
    
            var obsPaO2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "PaO2_Tidal",
                Value = 234
            };
    
            var obsCalculate = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "Oxygenation_Index",
                CodingSystem = "ADAS"
            };
    
            _observationServiceMock
                .Setup(l => l.FindLastObservations(It.IsAny<ObjectId>(), It.IsAny<int>(), It.IsAny<List<string>>()))
                .ReturnsAsync([obsFiO2]);
    
            await _calculatedObservations.Map(obsPaO2, false);
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.Is<PatientObservation>(arg =>
                arg.Name == obsCalculate.Name && arg.PatientId == patientId
                                              && arg.CodingSystem == obsCalculate.CodingSystem
            ), true, true), Times.Never);
        }

    /// <summary>
    /// Verifies that the Oxygenation_Index is not calculated or persisted when the PaO2_Tidal observation value is zero.
    /// Ensures that the mapping logic skips downstream calculation and InsertObservation is never invoked in this edge case.
    /// </summary>
    [Test]
        public async Task CalculateOxygenationIndex_PaO2_Tidal_0_Not_Returns_Oxygenation_Index()
        {
            var patientId = ObjectId.GenerateNewId();
    
            var obsFiO2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "FiO2",
                Value = 34
            };
    
            var obsPVam = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "P_VAM",
                Value = 6
            };
    
            var obsPaO2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "PaO2_Tidal",
                Value = 0
            };
    
            const int value = 6 * 34 * 100 / 234;
    
            var obsCalculate = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "Oxygenation_Index",
                CodingSystem = "ADAS",
                Value = value
            };
    
            _observationServiceMock
                .Setup(l => l.FindLastObservations(It.IsAny<ObjectId>(), It.IsAny<int>(), It.IsAny<List<string>>()))
                .ReturnsAsync([obsFiO2, obsPVam]);
    
            await _calculatedObservations.Map(obsPaO2, false);
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.Is<PatientObservation>(arg =>
                arg.Name == obsCalculate.Name && arg.PatientId == patientId
                                              && arg.CodingSystem == obsCalculate.CodingSystem
            ), true, true), Times.Never);
        }

    /// <summary>
    /// Verifies that the mapping process correctly computes the PaO2/FiO2 ratio when a PaO2 observation is provided,
    /// by dividing the PaO2 value by the most recent FiO2 observation for the patient and inserting the result as a new
    /// PatientObservation with the ADAS coding system.
    /// </summary>
    [Test]
        public async Task CalculatePF_PaO2_Returns_PaO2_FiO2()
        {
            var patientId = ObjectId.GenerateNewId();
    
    
            var observation = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "PaO2_Tidal",
                Value = 234
            };
    
            var obsLast = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "FiO2",
                Value = 34
            };
    
            var value = 234.0 / 34.0;
            value = Math.Round(value, 4);
    
            var obsCalculate = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "PaO2_FiO2",
                CodingSystem = "ADAS",
                Value = value
            };
    
            _observationServiceMock
                .Setup(l => l.FindLastObservations(It.IsAny<ObjectId>(), It.IsAny<int>(), It.IsAny<List<string>>()))
                .ReturnsAsync([obsLast]);
    
            await _calculatedObservations.Map(observation, false);
    
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.Is<PatientObservation>(arg =>
                arg.Name == obsCalculate.Name && Equals(TryparseDouble(arg.Value), TryparseDouble(obsCalculate.Value)) &&
                arg.PatientId == patientId
                && arg.CodingSystem == obsCalculate.CodingSystem
            ), true, true));
        }

    /// <summary>
    /// Verifies that the calculated observation mapping produces a PaO2/FiO2 ratio observation
    /// when an FiO2 observation is processed, by inserting a new patient observation with the
    /// expected ratio value and coding system.
    /// </summary>
    [Test]
        public async Task CalculatePF_FiO2_Returns_PaO2_FiO2()
        {
            var patientId = ObjectId.GenerateNewId();
    
            var observation = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "FiO2",
                Value = 34
            };
    
            var obsLast = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "PaO2_Tidal",
                Value = 234
            };
    
            var value = 234.0 / 34.0;
            value = Math.Round(value, 4);
    
            var obsCalculate = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "PaO2_FiO2",
                CodingSystem = "ADAS",
                Value = value
            };
    
            _observationServiceMock
                .Setup(l => l.FindLastObservations(It.IsAny<ObjectId>(), It.IsAny<int>(), It.IsAny<List<string>>()))
                .ReturnsAsync([obsLast]);
    
            await _calculatedObservations.Map(observation, false);
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.Is<PatientObservation>(arg =>
                arg.Name == obsCalculate.Name && Equals(TryparseDouble(arg.Value), TryparseDouble(obsCalculate.Value)) &&
                arg.PatientId == patientId
                && arg.CodingSystem == obsCalculate.CodingSystem
            ), true, true));
        }

    /// <summary>
    /// Verifies that the PF ratio calculation does not produce a PaO2/FiO2 observation when the FiO2 value is zero.
    /// Ensures that no calculated observation is inserted for the patient under this condition.
    /// </summary>
    [Test]
        public async Task CalculatePF_FiO2_0_Not_Returns_PaO2_FiO2()
        {
            var patientId = ObjectId.GenerateNewId();
    
            var observation = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "PaO2_Tidal",
                Value = 98
            };
    
            var obsLast = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "FiO2",
                Value = 0
            };
    
            var obsCalculate = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "Sattc_FiO2",
                CodingSystem = "ADAS"
            };
    
            _observationServiceMock
                .Setup(l => l.FindLastObservations(It.IsAny<ObjectId>(), It.IsAny<int>(), It.IsAny<List<string>>()))
                .ReturnsAsync([obsLast]);
    
            await _calculatedObservations.Map(observation, false);
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.Is<PatientObservation>(arg =>
                arg.Name == obsCalculate.Name && arg.PatientId == patientId
                                              && arg.CodingSystem == obsCalculate.CodingSystem
            ), true, true), Times.Never);
        }


    /// <summary>
    /// Verifies that when patient observations include a low SpO2 (Sattc) value of 50 and a low FC value of 50, the calculated observations processing triggers a BlueCode alarm by inserting the observation and sending the alarm.
    /// </summary>
    [Test]
        public async Task
            SendAlarm_BlueCode_FC_SpO2_Alarm_True_Returns_SendAlarm_BlueCode()
        {
            var patientId = ObjectId.GenerateNewId();
            var now = DateTime.Now;
    
    
            var obsSattc = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "Sattc",
                Value = 50,
                Time = now
            };
    
    
            var obsFc = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Value = "50",
                Name = "FC",
                Time = now
            };
    
            var listObservation = new List<PatientObservation?>
            {
                obsSattc, obsFc
            };
    
            await _calculatedObservations.CalculateBlueCodeList(listObservation);
    
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.IsAny<PatientObservation>(), true, true),
                Times.Once);
            _alarmServiceMock.Verify(
                a => a.SendAlarm(It.IsAny<PatientObservation>(), "BlueCode", AlarmEnum.Name.Blue, AlarmEnum.Severity.None,
                    AlarmEnum.Type.Auto), Times.Once);
        }

    /// <summary>
    /// Verifies that when a BlueCode alarm condition is triggered by FC and TAm observations, the calculated blue code list is generated, the observation is inserted, and the blue code alarm is sent with the expected severity and type.
    /// </summary>
    /// <returns>A task that completes when the blue code alarm verification has been executed.</returns>
    [Test]
        public async Task
            SendAlarm_BlueCode_FC_TAm_Alarm_True_Returns_SendAlarm_BlueCode()
        {
            var patientId = ObjectId.GenerateNewId();
            var now = DateTime.Now;
    
    
            var obsFc = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Value = "50",
                Name = "FC",
                Time = now
            };
    
            var obsTAm1 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "TAm",
                Value = 100,
                Time = now.AddSeconds(-5)
            };
    
            var obsTAm2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "TAm",
                Value = 50,
                Time = now
            };
    
            var listObservation = new List<PatientObservation?>
            {
                obsFc, obsTAm2
            };
    
            var listTAmObs = new List<PatientObservation>
            {
                obsTAm1
            };
    
            _observationServiceMock.Setup(l => l.FindLastObservations(patientId, 1, _pressBloodArteryMean))
                .ReturnsAsync(listTAmObs);
    
    
            await _calculatedObservations.CalculateBlueCodeList(listObservation);
    
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.IsAny<PatientObservation>(), true, true),
                Times.Once);
            _alarmServiceMock.Verify(
                a => a.SendAlarm(It.IsAny<PatientObservation>(), "BlueCode", AlarmEnum.Name.Blue, AlarmEnum.Severity.None,
                    AlarmEnum.Type.Auto), Times.Once);
        }

    /// <summary>
    /// Verifies that a BlueCode alarm is not triggered when the heart rate (FC) is at 50 and the mean arterial pressure (TAm) values do not meet the BlueCode criteria.
    /// </summary>
    [Test]
        public async Task SendAlarm_BlueCode_FC_TAm_Alarm_False()
        {
            var patientId = ObjectId.GenerateNewId();
            var now = DateTime.Now;
    
    
            var obsFc = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Value = "50",
                Name = "FC",
                Time = now
            };
    
            var obsTAm1 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "TAm",
                Value = 100,
                Time = now.AddSeconds(-5)
            };
    
            var obsTAm2 = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = patientId,
                Name = "TAm",
                Value = 80,
                Time = now
            };
    
            var listObservation = new List<PatientObservation?>
            {
                obsFc, obsTAm2
            };
    
            var listTAmObs = new List<PatientObservation>
            {
                obsTAm1
            };
    
            _observationServiceMock.Setup(l => l.FindLastObservations(patientId, 1, _pressBloodArteryMean))
                .ReturnsAsync(listTAmObs);
    
    
            await _calculatedObservations.CalculateBlueCodeList(listObservation);
    
    
            _observationServiceMock.Verify(o => o.InsertObservation(It.IsAny<PatientObservation>(), true, true),
                Times.Never);
            _alarmServiceMock.Verify(
                a => a.SendAlarm(It.IsAny<PatientObservation>(), "BlueCode", AlarmEnum.Name.Blue, AlarmEnum.Severity.None,
                    AlarmEnum.Type.Auto), Times.Never);
        }

    /// <summary>
    /// Attempts to parse the string representation of the specified object as a <see cref="double"/>.
    /// Returns <see langword="null"/> when the value cannot be parsed as a valid double.
    /// </summary>
    /// <param name="value">The object whose string representation will be converted to a double.</param>
    /// <returns>The parsed <see cref="double"/> value if the conversion succeeds; otherwise, <see langword="null"/>.</returns>
    private static double? TryparseDouble(object value)
        {
            return double.TryParse(value.ToString(), out var valueParsed) ? valueParsed : null;
        }


    [Test]
    public async Task Map_PumpObservation_DrugName_Null_AlarmType_Occlusion_Return_Insert_Pump_Insert_PositionName()
    {
        var pumpObservation = new PumpObservation
        {
            Code = "Tile-6",
            Time = Now,
            Name = "g-1-pump-Tile-6",
            Number = 2,
            Total = 7,
            TotalAux = 0,
            Status = PumpEnum.Status.Alarm,
            PumpMode = PumpEnum.Mode.Unknown,
            InfusingStatus = PumpEnum.InfusingStatus.Unknown,
            Pressure = new CommonPumpTypes.PumpValue(),
            //drugName = "Nutrición Parenteral",
            Concentration = new CommonPumpTypes.PumpValue(),
            DrugAmount = new CommonPumpTypes.PumpValue(),
            DiluentVolume = new CommonPumpTypes.PumpValue(),
            DoseRate = new CommonPumpTypes.PumpValue(),
            Rate = new CommonPumpTypes.PumpValue(),
            VolumeInfused = new CommonPumpTypes.PumpValue
            {
                Value = 0.00001
            },
            VolumeRemaining = new CommonPumpTypes.PumpValue
            {
                Value = 0.00001
            },
            TimeRemaining = new CommonPumpTypes.PumpValue
            {
                Value = 1441,
                Units = "min"
            },
            PatientWeight = new CommonPumpTypes.PumpValue(),
            AlarmType = PumpEnum.AlarmType.Occlusion,
            AlarmMode = PumpEnum.AlarmMode.Hight,
            GatewayNumber = 1,
            IsAux = false,
            IsInfusing = false,
            Expires = 100
        };

        await _calculatedObservations.Map(pumpObservation);


        _observationServiceMock.Verify(d => d.InsertObservation(It.Is<PatientObservation>(arg =>
            arg.Value.ToString() == "Rack 1 Bomba 2"), true, true));
    }

    [Test]
    public async Task
        Map_PumpObservation_DrugName_Null_AlarmType_Occlusion_Return_Insert_Pump_Insert_Aux_PositionName()
    {
        var pumpObservation = new PumpObservation
        {
            Code = "Tile-6",
            Time = Now,
            Name = "g-1-pump-Tile-6",
            Number = 2,
            Total = 7,
            TotalAux = 0,
            Status = PumpEnum.Status.Alarm,
            PumpMode = PumpEnum.Mode.Unknown,
            InfusingStatus = PumpEnum.InfusingStatus.Unknown,
            Pressure = new CommonPumpTypes.PumpValue(),
            //drugName = "Nutrición Parenteral",
            Concentration = new CommonPumpTypes.PumpValue(),
            DrugAmount = new CommonPumpTypes.PumpValue(),
            DiluentVolume = new CommonPumpTypes.PumpValue(),
            DoseRate = new CommonPumpTypes.PumpValue(),
            Rate = new CommonPumpTypes.PumpValue(),
            VolumeInfused = new CommonPumpTypes.PumpValue
            {
                Value = 0.00001
            },
            VolumeRemaining = new CommonPumpTypes.PumpValue
            {
                Value = 0.00001
            },
            TimeRemaining = new CommonPumpTypes.PumpValue
            {
                Value = 1441,
                Units = "min"
            },
            PatientWeight = new CommonPumpTypes.PumpValue(),
            AlarmType = PumpEnum.AlarmType.Occlusion,
            AlarmMode = PumpEnum.AlarmMode.Hight,
            GatewayNumber = 1,
            IsAux = true,
            IsInfusing = false,
            Expires = 100
        };

        await _calculatedObservations.Map(pumpObservation);


        _observationServiceMock.Verify(d => d.InsertObservation(It.Is<PatientObservation>(arg =>
            arg.Value.ToString() == "Rack Aux 1 Bomba 2"), true, true));
    }

    /// <summary>
    /// Verifies that a <see cref="PatientObservation"/> representing a pump volumetric air occlusion alarm is correctly mapped by the calculated observations mapper, returning a non-null result with a matching name.
    /// </summary>
    [Test]
        public async Task Map_PatientObservation_Alarm_Pump_Retur_obs()
        {
            PatientObservation patientObservation = new()
            {
                CodingSystem = "ADAS_ALARM",
                Code = "Pump_VolumetricAirOclusion",
                Name = "Alarm_Pump_VolumetricAirOclusion",
                Value = "Rack 1 Bomba 1",
                PatientId = PatientId,
                Time = Now
            };
    
            var result = await _calculatedObservations.Map(patientObservation, false);
    
            Assert.That(result, Is.Not.Null);
            Assert.That(result!.Name, Is.EqualTo(patientObservation.Name));
        }
}