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;
namespace adas_core.Application.Customizations.HGM;
//Custom for Hospital Gregorio Marañón
///
/// Represents a collection of calculated observations, providing a concrete implementation of the contract.
///
///
public class CalculatedObservations : ICalculatedObservations
{
private readonly List _highFrequencyVentilation = [];
private readonly List _invasiveVentilation = [];
private readonly ILogger _logger;
private readonly List _nonInvasiveVentilation = [];
private readonly Lazy _observationService;
///
/// Initializes a new instance of the class by resolving its required dependencies from the supplied and loading the configured high-frequency, invasive, and non-invasive ventilation category lists from .
///
/// The used to resolve , , and a .
/// Thrown when a required dependency cannot be resolved from .
///
public CalculatedObservations(IServiceProvider serviceProvider)
{
var apiSettings = serviceProvider.GetRequiredService>().Value;
_logger = serviceProvider.GetRequiredService>();
_observationService = serviceProvider.GetRequiredService>();
var highFrequencyVentilation = apiSettings.HighFrequencyVentilation ?? null;
highFrequencyVentilation?.ForEach(x => _highFrequencyVentilation.Add(x.Trim()));
var invasiveVentilation = apiSettings.InvasiveVentilation ?? null;
invasiveVentilation?.ForEach(x => _invasiveVentilation.Add(x.Trim()));
var nonInvasiveVentilation = apiSettings.NonInvasiveVentilation ?? null;
nonInvasiveVentilation?.ForEach(x => _nonInvasiveVentilation.Add(x.Trim()));
}
///
/// Maps a patient observation by applying domain-specific transformations based on the observation name.
/// Handles the "Resp_Mode" case by calculating the ventilation mode, while observations with a null or empty name are returned unchanged.
///
/// The patient observation to be mapped.
/// Flag indicating whether the mapping should be restricted to name-based criteria.
/// The mapped patient observation, or the original observation if no applicable mapping is found.
///
public async Task Map(T obs, bool onlyByName = false) where T : BasePatientObservation
{
if (string.IsNullOrEmpty(obs.Name)) return obs;
switch (obs.Name)
{
case "Resp_Mode":
await CalculateVentilationMode(obs);
break;
}
return obs;
}
///
/// Asynchronously maps the specified to a result.
///
/// The instance to be mapped.
/// A task that represents the asynchronous mapping operation, containing the resulting .
/// Thrown to indicate that the method has not yet been implemented.
///
public Task Map(PatientTreatment treatment)
{
throw new NotImplementedException();
}
///
/// Maps the provided patient diagnosis to the target representation asynchronously.
///
/// The patient diagnosis to be mapped.
/// A task that represents the asynchronous mapping operation, containing the mapped .
/// Thrown when the method is invoked, as the mapping logic has not been implemented yet.
///
public Task Map(PatientDiagnosis diagnosis)
{
throw new NotImplementedException();
}
///
/// Maps the provided by returning it unchanged, wrapped in a completed task.
///
/// The pump observation to map.
/// A completed task containing the provided .
///
public async Task Map(PumpObservation pumpObservation)
{
return await Task.FromResult(pumpObservation);
}
///
/// Asynchronously calculates the active bolus for the specified patient.
///
/// The unique identifier of the patient for whom the active bolus is calculated.
/// The method is not yet implemented.
///
public Task CalculateActiveBolus(ObjectId patientId)
{
throw new NotImplementedException();
}
///
/// Calculates the medicine observation for a patient based on the provided active medicines.
///
/// The list of active medicines currently associated with the patient.
/// The unique identifier of the patient for whom the observation is being calculated.
/// The method is not yet implemented.
///
public Task CalculateMedicineObservation(List activeMedicines, ObjectId patientId)
{
throw new NotImplementedException();
}
///
/// Resolves time inconsistencies between the specified and the last recorded patient observation, returning a corrected observation when applicable.
///
/// The new patient observation to reconcile against the last recorded observation.
/// A task that returns the corrected , or null when no last observation is available to compare against.
/// The method is not yet implemented.
///
public Task FixTimeInconsistencyWithLast(PatientObservation newObservation)
{
throw new NotImplementedException();
}
///
/// Retrieves the active treatments currently associated with the specified patient.
///
/// The identifier of the patient whose active treatments are being requested.
/// A task that yields a collection of active entries for the patient.
/// Thrown because the method has not been implemented yet.
///
public Task> GetActiveTreatmentsByPatient(ObjectId id)
{
throw new NotImplementedException();
}
///
/// Pre-maps the provided list of patient observations before further processing, returning the list as-is in a completed task.
///
/// The list of patient observations to be pre-mapped.
/// A completed task containing the provided list of patient observations.
///
public Task> PreMapList(List listToInsert)
{
return Task.FromResult(listToInsert);
}
///
/// Maps a source alarm to a patient observation, returning the provided observation as the result.
///
/// The patient observation to return as the mapped result.
/// The patient observation alarm to be considered during mapping.
/// A containing the provided .
///
public Task MapSourceAlarm(PatientObservation obs, PatientObservationAlarm alarmToInsert)
{
return Task.FromResult(obs);
}
///
/// Sends an alarm for the specified patient observation.
///
/// The patient observation that triggers the alarm.
/// The name associated with the alarm.
/// The optional alarm code identifying the alarm type.
/// A task that represents the asynchronous alarm sending operation.
/// Thrown when the method is invoked, as it is not yet implemented.
///
public Task SendAlarm(PatientObservation obs, string name, AlarmEnum.Name? code)
{
throw new NotImplementedException();
}
///
/// Calculates and persists the ventilation mode (Resp_Type) for a patient observation by mapping the observed value against known high-frequency, invasive, and non-invasive ventilation vocabularies, defaulting to None when the value is empty or unrecognized.
///
/// The base patient observation whose value is used to derive the respiration type; it is cast to to access the value.
///
private async Task CalculateVentilationMode(BasePatientObservation obs)
{
var pobs = (PatientObservation)obs;
var respTypeObs = new PatientObservation
{
Name = "Resp_Type",
CodingSystem = "ADAS",
PatientId = obs.PatientId,
Time = obs.Time
};
var strValue = pobs.Value.ToString();
if (string.IsNullOrEmpty(strValue))
respTypeObs.Value = nameof(RespirationType.None);
else
respTypeObs.Value = _highFrequencyVentilation.Contains(strValue)
? nameof(RespirationType.HighFrequencyVentilation)
: _invasiveVentilation.Contains(strValue)
? respTypeObs.Value = nameof(RespirationType.Invasive)
: _nonInvasiveVentilation.Contains(strValue)
? respTypeObs.Value = nameof(RespirationType.NonInvasive)
: nameof(RespirationType.None);
var wasInserted = await _observationService.Value.InsertIfChanged("Resp_Type", respTypeObs);
if (wasInserted)
_logger.LogDebug("Calculated Resp_Type for patientid: {respTypeObsPatientid} value: {respType}",
respTypeObs.PatientId, respTypeObs.Value);
}
}