using adas_core.Domain.Enums;
using adas_core.Domain.Models.Masters;
using MongoDB.Bson;
namespace adas_core.Domain.Models.MongoModels;
///
/// Represents a patient entity, typically used to encapsulate patient-related data and behavior within a healthcare or medical information system.
///
public class Patient
{
public ObjectId Id { get; set; }
public string? PatientNumber { get; set; }
public string? PatientId { get; set; }
public DateTime? AdmTime { get; set; }
//Estado del Alta: Altable, no Altable, Exitus, Transferible
public OptionList? DischargeStatus { get; set; }
public OptionList? Altable { get; set; }
//Procedencia
public OptionList? Origin { get; set; }
public string? OriginAux { get; set; }
//Diagnósticos
public OptionList? Diagnosis { get; set; }
public string? DiagnosisAux { get; set; }
//Visitas
public OptionList? Visits { get; set; }
public OptionList? AccessControl { get; set; }
//Aislamiento: por defecto No Aislado
public OptionList? Insulation { get; set; }
//NEMS
public OptionList? PatientStatus { get; set; }
//Movilidad: por defecto sin asignar
public OptionList? Mobility { get; set; }
//Techo terapeutico
public OptionList? TherapeuticCeiling { get; set; }
// Intervenciones
public List? Procedures { get; set; }
//Pruebas (tests)
public List? Tests { get; set; }
//Terapias
public List? Treatment { get; set; }
//Facultativos
public List? Doctors { get; set; }
//Alergias
public List? Allergies { get; set; }
public List? LanguageBarrier { get; set; }
public OptionList? PassiveSitting { get; set; }
public DateTime? DisTime { get; set; }
public Person? Person { get; set; }
public Person? AttendingDoctor { get; set; }
public DateTime? LastObservationDate { get; set; }
public DateTime? CreationDate { get; set; }
public DateTime? UpdateDate { get; set; }
public DateTime? ArchiveDate { get; set; }
public ObjectId? PointOfCareId { get; set; }
public ObjectId? UnitId { get; set; }
public List? HistoricalLocations { get; set; }
///
/// Returns a human-readable string representation of the person, including the identifier and any
/// available contextual details such as point of care, bed, patient numbers, admission and discharge
/// timestamps, assigned patient, attending doctor, and relevant date metadata. Optional fields are
/// appended to the output only when their values are present (non-null, non-empty, or with a value
/// for nullable types).
///
/// A formatted string prefixed with "person[" and containing the included fields joined by commas.
public override string ToString()
{
List items = [$"id: {Id}"];
if (!string.IsNullOrEmpty(UnitString)) items.Add($"pointOfCare: {UnitString}");
if (!string.IsNullOrEmpty(Bed)) items.Add($"bed: {Bed}");
if (!string.IsNullOrEmpty(PatientNumber)) items.Add($"patientNumber: {PatientNumber}");
if (!string.IsNullOrEmpty(PatientId)) items.Add($"patientId: {PatientId}");
if (AdmTime.HasValue) items.Add($"admTime: {AdmTime}");
if (DisTime.HasValue) items.Add($"disTime: {DisTime}");
if (Person != null) items.Add($"patient: {Person}");
if (AttendingDoctor != null) items.Add($"attendingDoctor: {AttendingDoctor}");
if (LastObservationDate.HasValue) items.Add($"lastObservationDate: {LastObservationDate}");
if (CreationDate.HasValue) items.Add($"creationDate: {CreationDate}");
if (UpdateDate.HasValue) items.Add($"updateDate: {UpdateDate}");
if (ArchiveDate.HasValue) items.Add($"archiveDate: {UpdateDate}");
return "person[" + string.Join(", ", items) + "]";
}
///
/// Determines whether the current represents an inactive Virtual Point of Care by checking that it is not null and is not defined as a value of the enumeration.
///
/// true if UnitString is not null and does not match any defined value; otherwise, false.
public bool IsInActivePoC()
{
return UnitString != null && !Enum.IsDefined(typeof(VirtualPointOfCare), UnitString);
}
///
/// Creates a copy of the current instance by performing a shallow copy.
///
/// A new object that is a shallow copy of the current instance.
public Patient DeepCopy()
{
return (Patient)MemberwiseClone();
}
#region UnMap
public string? Bed { get; set; }
public string? Room { get; set; }
public string? UnitString { get; set; }
public PointOfCare? PointOfCare { get; set; }
public PatientLocation Location
{
get => new(UnitString, Bed, Room ?? Bed);
set
{
if (value == null || (UnitString == value.UnitName && Bed == value.Bed))
return;
UnitString = value.UnitName;
Bed = value.Bed;
HistoricalLocations ??= [];
var currentUtc = DateTime.UtcNow;
bool shouldAdd = true;
if (HistoricalLocations.Count > 0)
{
var last = HistoricalLocations[^1];
if (last.PatientLocation?.Bed == value.Bed && last.PatientLocation?.UnitName == value.UnitName)
{
shouldAdd = false;
}
else if (currentUtc.ToString("o").Equals(last.AdmTime.ToString()))
{
currentUtc = currentUtc.AddSeconds(1);
}
}
if (shouldAdd)
{
HistoricalLocations.Add(new HistoricalLocation(
currentUtc,
new PatientLocation(value.UnitName, value.Bed, value.Room)
));
}
}
}
#endregion
}
///
/// Represents data related to a patient's income information.
///
public class PatientIncomeData
{
public DateTime? AdmTime { get; set; }
public OptionList? Origin { get; set; }
public string? OriginAux { get; set; }
public OptionList? Diagnosis { get; set; }
public string? DiagnosisAux { get; set; }
}