using adas_core.Application.Repositories.Interfaces;
using adas_core.Application.Services;
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.MongoModels;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using Moq;
using Options = Microsoft.Extensions.Options.Options;

/*
 * Tests shift observations
 */

namespace adas_core.Test.Services;

[TestFixture]
public class ObservationServiceTest
{
    /// <summary>
    /// Initializes the test fixture for the <see cref="ObservationService"/> by creating and configuring
    /// all required dependency mocks, instantiating the service under test with the mocked collaborators,
    /// and pre-configuring common lookup behavior for the default "UCI5C" unit (including <c>FindByName</c>
    /// and <c>FindById</c>) along with the <c>ICalculatedObservationsService.Map</c> passthrough.
    /// </summary>
    [SetUp]
        public void Setup()
        {
            //_observationServiceMock = new Mock<IObservationService>();
    
            //var medicineServiceMock = new Mock<IMedicineService>();1
            var groupedObservationServiceMock = new Mock<IGroupedObservationService>();
            var alarmServiceMock = new Mock<IAlarmService>();
    
            var clientMessageServiceMock = new Mock<IClientMessageService>();
    
            var subscribersServiceMock = new Mock<ISubscribersService>();
    
            var subscriberGroupedServiceMock = new Mock<ISubscriberGroupedService>();
    
            _patientServiceMock = new Mock<IPatientService>();
    
            _configObservationService = new Mock<IConfigObservationService>();
    
            _observationRepository = new Mock<IObservationRepository>();
    
            var observationArchiveRepository = new Mock<IObservationArchiveRepository>();
    
            var calculatedObservationsServiceMock = new Mock<ICalculatedObservationsService>();
            var calculatedObservationsServiceLazy =
                new Lazy<ICalculatedObservationsService>(() => calculatedObservationsServiceMock.Object);
            calculatedObservationsServiceMock.Setup(o => o.Map(It.IsAny<PatientObservation>(), It.IsAny<bool>()))
                .ReturnsAsync((PatientObservation obs, bool _) => obs);
    
            _configUnitsService = new Mock<IConfigUnitsService>();
            _unitServiceMock = new Mock<IUnitService>();
    
            var diagnosisServiceMock = new Mock<IDiagnosisService>();
    
            _optionsApiSettings = Options.Create(_apiSettings);
            Options.Create(_recordingSettings);
            _optionsCacheSettings = Options.Create(_cacheSettings);
            
            var balizaService = new Mock<ILightBeaconService>();
            var pocService = new Mock<IPointOfCareService>();
            var relayService = new Mock<IRelayService>();
            var recordingService = new Mock<IRecordingService>();
    
            _logger = new Mock<ILogger<ObservationService>>();
    
            _observationService = new ObservationService(
                _patientServiceMock.Object,
                //Ipoc.Object,
                _configObservationService.Object,
                _observationRepository.Object,
                observationArchiveRepository.Object,
                _configUnitsService.Object,
                diagnosisServiceMock.Object,
                _optionsApiSettings,
                _optionsCacheSettings,
                balizaService.Object,
                relayService.Object,
                recordingService.Object,
                _logger.Object,
                groupedObservationServiceMock.Object,
                alarmServiceMock.Object,
                clientMessageServiceMock.Object,
                subscribersServiceMock.Object,
                subscriberGroupedServiceMock.Object,
                calculatedObservationsServiceLazy,
                _httpContextAccessor.Object,
                _auditService.Object,
                pocService.Object,
                Mock.Of<ICacheService>()
            );
    
            // Create a mock of the singleton class subscribers
            var mockSingleton = new Mock<ICalculatedObservationsService>();
    
            // Set up the mock object to return a specific value when a method is called
            mockSingleton.Setup(x => x.Map(It.IsAny<PatientObservation>(), It.IsAny<bool>()))
                .ReturnsAsync((PatientObservation? value, bool _) => value);
            var unitId = ObjectId.GenerateNewId();
            var unit = new Unit
            {
                Id = unitId,
                Name = "UCI5C",
                Title = "CONTROLC",
                Configuration = new UnitConfiguration
                {
                    AutoAdt = true
                }
            };
    
            _unitServiceMock.Setup(u => u.FindByName(unit.Name)).ReturnsAsync(unit);
            _unitServiceMock.Setup(u => u.FindById(unit.Id)).ReturnsAsync(unit);
        }

    private ObservationService _observationService;

    //Mock<IObservationService> _observationServiceMock ;
    private Mock<IPatientService> _patientServiceMock;
    private Mock<IConfigObservationService> _configObservationService;
    private Mock<IConfigUnitsService> _configUnitsService;
    private Mock<IObservationRepository> _observationRepository;
    private Mock<IUnitService> _unitServiceMock;
    private readonly Mock<IHttpContextAccessor> _httpContextAccessor = new();
    private readonly Mock<ILocalAuditService> _auditService = new();


    private readonly ApiSettings _apiSettings = new()
    {
        ConfigObservation = new ConfigObservationSettings
        {
            IgnoreUnknownObservation = false
        },
        Customize = "H12O",
        IntravenousLinesCode = ["10546003"],
        AllergiesCode = ["473011001"],
        DrainageCode = ["56868008"],
        IsolationCode = ["302147001"],
        PositionCode = ["386053000"]
    };

    private readonly CacheSettings _cacheSettings = new();
    
    private IOptions<ApiSettings> _optionsApiSettings;
    private IOptions<CacheSettings> _optionsCacheSettings;


    private readonly RecordingSettings _recordingSettings = new();

    private Mock<ILogger<ObservationService>> _logger;

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

    [Test]
    public async Task ProcessAllergiesObservation__apiRequest_No_Allergies_Return_Nothing()
    {
        var patientObs = new Person
        {
            FirstName = "Miguel",
            LastName = "Villanueva",
            Ids = new Dictionary<string, string> { { "MR", "437537" } }
        };

        var patient = new Patient
        {
            Id = ObjectId.GenerateNewId(),
            UnitString = "UCI5C",
            Bed = "Box4",
            PatientNumber = "437537",
            Person = patientObs
        };

        var apiRequest = new ApiRequest
        {
            Location = new PatientLocation("UCI5C", "Box4"),
            ObservationData = new ObservationData
            {
                Code = "473011001",
                CodingSystem = "SNM",
                Text = "Alergias",
                Time = Now,
                Value = ""
            },
            Observations =
            [
                new PatientObservation
                {
                    Code = "263490005",
                    CodingSystem = "SNM",
                    Name = "Estado",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Sin alergias conocidas"
                },

                new PatientObservation
                {
                    Code = "300916003",
                    CodingSystem = "SNM",
                    Name = "�Alergia al l�tex?",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "No"
                }
            ],
            Patient = patientObs,
            PatientNumber = "437537",
            Type = "ORU_R01",
            PatientId = PatientId.ToString()
        };

        //PatientObservation expectedObs = new();

        _patientServiceMock.Setup(cm => cm.FindPatientByApiRequest(apiRequest)).ReturnsAsync(patient);

        await _observationService.SaveRequest(apiRequest);

        _observationRepository.Verify(o => o.InsertOneAsync(It.Is<PatientObservation>(arg =>
            arg.Name == "AllergiesObs" &&
            arg.PatientId == PatientId
        )), Times.Never);
    }

    [Test]
    public async Task ProcessAllergiesObservation_apiRequest_Allergies_Latex_Return_AllergiesObs_Latex()
    {
        //Falla CalculatedObservationService.Instance = null

        var patientObs = new Person
        {
            FirstName = "Miguel",
            LastName = "Villanueva",
            Ids = new Dictionary<string, string> { { "MR", "437537" } }
        };

        var patient = new Patient
        {
            Id = ObjectId.GenerateNewId(),
            UnitString = "UCI5C",
            Bed = "Box4",
            PatientNumber = "437537",
            Person = patientObs,
            UnitId = ObjectId.GenerateNewId(),
            PointOfCareId = ObjectId.GenerateNewId()
        };

        var apiRequest = new ApiRequest
        {
            Location = new PatientLocation("UCI5C", "Box4"),
            ObservationData = new ObservationData
            {
                Code = "473011001",
                CodingSystem = "SNM",
                Text = "Alergias",
                Time = Now
            },
            Observations =
            [
                new PatientObservation
                {
                    Code = "263490005",
                    CodingSystem = "SNM",
                    Name = "Estado",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Alergias"
                },

                new PatientObservation
                {
                    Code = "300916003",
                    CodingSystem = "SNM",
                    Name = "�Alergia al l�tex?",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Si"
                }
            ],
            Patient = patientObs,
            PatientNumber = "437537",
            Type = "ORU_R01",
            PatientId = PatientId.ToString()
        };

        List<PatientAllergiesValue> expectePatientAllergiesValues =
        [
            new()
            {
                Type = "Latex",
                Value = "Si"
            }
        ];

        PatientObservation expectedObs = new()
        {
            Time = apiRequest.ObservationData.Time.Value,

            Code = apiRequest.ObservationData.Code,
            CodingSystem = apiRequest.ObservationData.CodingSystem,
            PatientId = patient.Id,
            ParentData = new ParentDataClass
            {
                Code = apiRequest.ObservationData.Code,
                CodingSystem = apiRequest.ObservationData.CodingSystem,
                Name = apiRequest.ObservationData.Text
            },
            Value = expectePatientAllergiesValues
        };

        _patientServiceMock.Setup(cm => cm.FindPatientByApiRequest(apiRequest)).ReturnsAsync(patient);
        _configObservationService.Setup(o => o.Map(It.IsAny<PatientObservation>(), false)).ReturnsAsync(expectedObs);
        _configUnitsService.Setup(o => o.Map(It.IsAny<PatientObservation>())).ReturnsAsync(expectedObs);

        _configObservationService.Setup(o => o.RetentionActions(It.IsAny<PatientObservation>()))
            .ReturnsAsync(new ObservatitonRetentionResult());
        _unitServiceMock.Setup(o => o.FindById(It.IsAny<ObjectId>())).ReturnsAsync(new Unit
            { Configuration = new UnitConfiguration { AutoAdt = true } });
        await _observationService.SaveRequest(apiRequest);

        _observationRepository.Verify(o => o.InsertOneAsync(expectedObs));
    }

    [Test]
    public async Task ProcessAllergiesObservation_apiRequest_Allergies_Return_AllergiesObs()
    {
        //Falla CalculatedObservationService.Instance = null

        var patientObs = new Person
        {
            FirstName = "Miguel",
            LastName = "Villanueva",
            Ids = new Dictionary<string, string> { { "MR", "437537" } }
        };

        var patient = new Patient
        {
            Id = ObjectId.GenerateNewId(),
            UnitId = ObjectId.GenerateNewId(),
            UnitString = "UCI5C",
            Bed = "Box4",
            PatientNumber = "437537",
            Person = patientObs
        };

        var apiRequest = new ApiRequest
        {
            Location = new PatientLocation("UCI5C", "Box4"),
            ObservationData = new ObservationData
            {
                Code = "473011001",
                CodingSystem = "SNM",
                Text = "Alergias",
                Time = Now
            },
            Observations =
            [
                new PatientObservation
                {
                    Code = "263490005",
                    CodingSystem = "SNM",
                    Name = "Estado",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Alergias"
                },

                new PatientObservation
                {
                    Code = "419199007",
                    CodingSystem = "SNM",
                    Name = "Tipo",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Alergia ambienta"
                },

                new PatientObservation
                {
                    Code = "277054007",
                    CodingSystem = "SNM",
                    Name = "Alergeno",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Estacional"
                },

                new PatientObservation
                {
                    Code = "281296001",
                    CodingSystem = "SNM",
                    Name = "Comentarios",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "epitelio de perro, mezcla de gram�neas salvajes,"
                },

                new PatientObservation
                {
                    Code = "419199007",
                    CodingSystem = "SNM",
                    Name = "Tipo",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Alergia a f�rmacos"
                },

                new PatientObservation
                {
                    Code = "416098002",
                    CodingSystem = "SNM",
                    Name = "F�rmacos al�rgenos",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "METILPREDNISOLONA"
                },

                new PatientObservation
                {
                    Code = "281296001",
                    CodingSystem = "SNM",
                    Name = "Comentarios",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Tolera dexametasona y actocortina"
                },

                new PatientObservation
                {
                    Code = "419199007",
                    CodingSystem = "SNM",
                    Name = "Tipo",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Alergia a f�rmacos"
                },

                new PatientObservation
                {
                    Code = "277054007",
                    CodingSystem = "SNM",
                    Name = "Alergeno",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Penicilina/cefalosporinas"
                }
            ],
            Patient = patientObs,
            PatientNumber = "437537",
            Type = "ORU_R01",
            PatientId = PatientId.ToString()
        };

        List<PatientAllergiesValue> expectePatientAllergiesValues =
        [
            new()
            {
                Type = "Alergia ambienta",
                Value = "Estacional",
                Notes = "epitelio de perro, mezcla de gram�neas salvajes,"
            },

            new()
            {
                Type = "Alergia a f�rmacos",
                Value = "METILPREDNISOLONA",
                Notes = "Tolera dexametasona y actocortina"
            },

            new()
            {
                Type = "Alergia a f�rmacos",
                Value = "Penicilina/cefalosporinas"
            }
        ];

        PatientObservation expectedObs = new()
        {
            Time = apiRequest.ObservationData.Time.Value,

            Code = apiRequest.ObservationData?.Code,
            CodingSystem = apiRequest.ObservationData?.CodingSystem,
            PatientId = patient.Id,
            ParentData = new ParentDataClass
            {
                Code = apiRequest.ObservationData?.Code,
                CodingSystem = apiRequest.ObservationData?.CodingSystem,
                Name = apiRequest.ObservationData?.Text
            },
            Value = expectePatientAllergiesValues
        };

        _patientServiceMock.Setup(cm => cm.FindPatientByApiRequest(apiRequest)).ReturnsAsync(patient);
        _configObservationService.Setup(o => o.Map(It.IsAny<PatientObservation>(), false)).ReturnsAsync(expectedObs);
        _configUnitsService.Setup(o => o.Map(It.IsAny<PatientObservation>())).ReturnsAsync(expectedObs);
        _unitServiceMock.Setup(o => o.FindById(It.IsAny<ObjectId>())).ReturnsAsync(new Unit
            { Configuration = new UnitConfiguration { AutoAdt = true } });
        // sectionServiceMock.Setup(s => s.FindByPatient(It.Is<ObjectId>(arg => arg == patient.id))).Returns(Task.FromResult<Section>(null));
        _configObservationService.Setup(o => o.RetentionActions(It.IsAny<PatientObservation>()))
            .ReturnsAsync(new ObservatitonRetentionResult());

        await _observationService.SaveRequest(apiRequest);

        _observationRepository.Verify(o => o.InsertOneAsync(expectedObs));
    }


    [Test]
    public async Task ProcessDrainagesObservation_apiRequest_Drainages_Return_DrainagesObs()
    {
        //Falla CalculatedObservationService.Instance = null

        var patientObs = new Person
        {
            FirstName = "Miguel",
            LastName = "Villanueva",
            Ids = new Dictionary<string, string> { { "MR", "437537" } }
        };

        var patient = new Patient
        {
            Id = ObjectId.GenerateNewId(),
            UnitId = ObjectId.GenerateNewId(),
            UnitString = "UCI5C",
            Bed = "Box4",
            PatientNumber = "437537",
            Person = patientObs
        };

        var apiRequest = new ApiRequest
        {
            Location = new PatientLocation("UCI5C", "Box4"),
            ObservationData = new ObservationData
            {
                Code = "56868008",
                CodingSystem = "SNM",
                Text = "Drenaje: Cabeza",
                Time = Now
            },
            Observations =
            [
                new PatientObservation
                {
                    Code = "56868008",
                    CodingSystem = "SNM",
                    Name = "Volumen",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = 100
                },

                new PatientObservation
                {
                    Code = "10546003",
                    CodingSystem = "SNM",
                    Name = "Localizaci�n",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Cabeza"
                },

                new PatientObservation
                {
                    Code = "138875005",
                    CodingSystem = "SNM",
                    Name = "Tipo de drenaje",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Drenaje ventricular"
                },

                new PatientObservation
                {
                    Code = "138875005",
                    CodingSystem = "SNM",
                    Name = "Altura columna(cmH2O)",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = 88
                }
            ],
            Patient = patientObs,
            PatientNumber = "437537",
            Type = "ORU_R01",
            PatientId = PatientId.ToString()
        };

        List<PatientDrainagesValue> expectePatientDraingesValues =
        [
            new()
            {
                Type = "Drenaje ventricular",
                Location = "Cabeza",
                Volume = 1001,
                Height = 8
            }
        ];

        PatientObservation expectedObs = new()
        {
            Time = apiRequest.ObservationData.Time.Value,

            Code = apiRequest.ObservationData.Code,
            CodingSystem = apiRequest.ObservationData.CodingSystem,
            PatientId = patient.Id,
            ParentData = new ParentDataClass
            {
                Code = apiRequest.ObservationData.Code,
                CodingSystem = apiRequest.ObservationData.CodingSystem,
                Name = apiRequest.ObservationData.Text
            },
            Value = expectePatientDraingesValues
        };

        _patientServiceMock.Setup(cm => cm.FindPatientByApiRequest(apiRequest)).ReturnsAsync(patient);
        _configObservationService
            .Setup(o => o.Map(It.Is<PatientObservation>(arg => arg.PatientId == patient.Id), false))
            .ReturnsAsync(expectedObs);
        _configUnitsService.Setup(o => o.Map(It.Is<PatientObservation>(arg => arg.PatientId == patient.Id)))
            .ReturnsAsync(expectedObs);

        _configObservationService.Setup(o => o.RetentionActions(It.IsAny<PatientObservation>()))
            .ReturnsAsync(new ObservatitonRetentionResult());
        _unitServiceMock.Setup(o => o.FindById(It.IsAny<ObjectId>())).ReturnsAsync(new Unit
            { Configuration = new UnitConfiguration { AutoAdt = true } });
        await _observationService.SaveRequest(apiRequest);


        _observationRepository.Verify(o => o.InsertOneAsync(It.Is<PatientObservation>(arg =>
            arg.Value == expectedObs.Value &&
            arg.PatientId == expectedObs.PatientId &&
            arg.ParentData == expectedObs.ParentData &&
            arg.Time == expectedObs.Time &&
            arg.Code == expectedObs.Code &&
            arg.CodingSystem == expectedObs.CodingSystem
        )));
    }

    /// <summary>
    /// Verifies that when an isolation observation is processed through SaveRequest, the configuration observation and units mapping services are invoked, and the resulting mapped observation is inserted into the observation repository with the expected value, patient identifier, name, time, message time, and coding system.
    /// </summary>
    [Test]
        public async Task ProcessIsolationObservation_Return_IsolationObs()
        {
            var patientObs = new Person
            {
                FirstName = "Miguel",
                LastName = "Villanueva",
                Ids = new Dictionary<string, string> { { "MR", "437537" } }
            };
    
            var patient = new Patient
            {
                Id = ObjectId.GenerateNewId(),
                UnitId = ObjectId.GenerateNewId(),
                UnitString = "UCI5C",
                Bed = "Box4",
                PatientNumber = "437537",
                Person = patientObs
            };
    
            var apiRequest = new ApiRequest
            {
                Location = new PatientLocation("UCI5C", "Box4"),
                ObservationData = new ObservationData
                {
                    Code = "302147001",
                    CodingSystem = "SNM",
                    Value = "Aire; Contacto; Preventivo",
                    Text = "Aislamiento",
                    Time = Now
                },
                Observations =
                [
                    new PatientObservation
                    {
                        Code = "code",
                        CodingSystem = "SNM",
                        Name = "name",
                        Status = StatusEnum.Type.Ok,
                        Time = Now,
                        Value = "value"
                    }
                ],
                Patient = patientObs,
                PatientNumber = "437537",
                Type = "ORU_R01",
                PatientId = PatientId.ToString(),
                MessageTime = Now
            };
    
            var newObs = new PatientObservation
            {
                Value = "Aire, Contacto, Preventivo",
                Name = "Isolation",
                CodingSystem = "ADAS",
                PatientId = patient.Id,
                MessageTime = Now,
                Time = Now
            };
    
            _patientServiceMock.Setup(cm => cm.FindPatientByApiRequest(apiRequest)).ReturnsAsync(patient);
            _configObservationService
                .Setup(o => o.Map(It.Is<PatientObservation>(arg => arg.PatientId == patient.Id), false))
                .ReturnsAsync(newObs);
            _configUnitsService.Setup(o => o.Map(It.Is<PatientObservation>(arg => arg.PatientId == patient.Id)))
                .ReturnsAsync(newObs);
            _configObservationService.Setup(o => o.RetentionActions(It.IsAny<PatientObservation>()))
                .ReturnsAsync(new ObservatitonRetentionResult());
            _unitServiceMock.Setup(o => o.FindById(It.IsAny<ObjectId>())).ReturnsAsync(new Unit
                { Configuration = new UnitConfiguration { AutoAdt = true } });
            await _observationService.SaveRequest(apiRequest);
    
    
            _observationRepository.Verify(o => o.InsertOneAsync(It.Is<PatientObservation>(arg =>
                arg.Value == newObs.Value &&
                arg.PatientId == newObs.PatientId &&
                arg.Name == newObs.Name &&
                arg.Time == newObs.Time &&
                arg.MessageTime == newObs.MessageTime &&
                arg.CodingSystem == newObs.CodingSystem
            )));
        }


    /// <summary>
    /// Verifies that processing a position observation through the observation service persists a new <see cref="PatientObservation"/> with the expected values (Value, PatientId, Name, Time, MessageTime, and CodingSystem) when a valid API request is provided.
    /// </summary>
    [Test]
        public async Task ProcessPositionObservation_Return_PositionObs()
        {
            var patientObs = new Person
            {
                FirstName = "Miguel",
                LastName = "Villanueva",
                Ids = new Dictionary<string, string> { { "MR", "437537" } }
            };
    
            var patient = new Patient
            {
                Id = ObjectId.GenerateNewId(),
                UnitId = ObjectId.GenerateNewId(),
                UnitString = "UCI5C",
                Bed = "Box4",
                PatientNumber = "437537",
                Person = patientObs
            };
    
            var apiRequest = new ApiRequest
            {
                Location = new PatientLocation("UCI5C", "Box4"),
                ObservationData = new ObservationData
                {
                    Code = "386053000",
                    CodingSystem = "SNM",
                    Text = "CAMBIOS POSTURALES",
                    Value = "Cama Hill-rom",
                    Time = Now
                },
                Observations =
                [
                    new PatientObservation
                    {
                        Code = "code",
                        CodingSystem = "SNM",
                        Name = "name",
                        Status = StatusEnum.Type.Ok,
                        Time = Now,
                        Value = "Cama Hill-rom"
                    }
                ],
                Patient = patientObs,
                PatientNumber = "437537",
                Type = "ORU_R01",
                PatientId = PatientId.ToString(),
                MessageTime = Now
            };
    
            var newObs = new PatientObservation
            {
                Value = "Cama Hill-rom",
                Name = "Patient_Position",
                CodingSystem = "ADAS",
                PatientId = patient.Id,
                MessageTime = Now,
                Time = Now
            };
    
            _patientServiceMock.Setup(cm => cm.FindPatientByApiRequest(apiRequest)).ReturnsAsync(patient);
            _configObservationService
                .Setup(o => o.Map(It.Is<PatientObservation>(arg => arg.PatientId == patient.Id), false))
                .ReturnsAsync(newObs);
            _configUnitsService.Setup(o => o.Map(It.Is<PatientObservation>(arg => arg.PatientId == patient.Id)))
                .ReturnsAsync(newObs);
            _configObservationService.Setup(o => o.RetentionActions(It.IsAny<PatientObservation>()))
                .ReturnsAsync(new ObservatitonRetentionResult());
            _unitServiceMock.Setup(o => o.FindById(It.IsAny<ObjectId>())).ReturnsAsync(new Unit
                { Configuration = new UnitConfiguration { AutoAdt = true } });
            await _observationService.SaveRequest(apiRequest);
    
    
            _observationRepository.Verify(o => o.InsertOneAsync(It.Is<PatientObservation>(arg =>
                arg.Value == newObs.Value &&
                arg.PatientId == newObs.PatientId &&
                arg.Name == newObs.Name &&
                arg.Time == newObs.Time &&
                arg.MessageTime == newObs.MessageTime &&
                arg.CodingSystem == newObs.CodingSystem
            )));
        }

    [Test]
    public async Task ProcessIntravenousLinesObservation_Return_PositionObs()
    {
        var patientObs = new Person
        {
            FirstName = "Miguel",
            LastName = "Villanueva",
            Ids = new Dictionary<string, string> { { "MR", "437537" } }
        };

        var patient = new Patient
        {
            Id = ObjectId.GenerateNewId(),
            UnitId = ObjectId.GenerateNewId(),
            UnitString = "UCI5C",
            Bed = "Box4",
            PatientNumber = "437537",
            Person = patientObs
        };

        var apiRequest = new ApiRequest
        {
            Location = new PatientLocation("UCI5C", "Box4"),
            ObservationData = new ObservationData
            {
                Code = "10546003",
                CodingSystem = "SNM",
                Text = "Cat�ter EPICUT�NEO PERIF�RICO: Zona temporal derecha",
                Time = Now
            },
            Observations =
            [
                new PatientObservation
                {
                    Code = "439272007",
                    CodingSystem = "SNM",
                    Name = "Fecha inserci�n",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = Now
                },

                new PatientObservation
                {
                    Code = "228864003",
                    CodingSystem = "SNM",
                    Name = "Duraci�n (d�as)",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = 7
                },

                new PatientObservation
                {
                    Code = "273248003",
                    CodingSystem = "SNM",
                    Name = "Actuaci�n",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Insertado"
                },

                new PatientObservation
                {
                    Code = "10546003",
                    CodingSystem = "SNM",
                    Name = "Localizaci�n",
                    Status = StatusEnum.Type.Ok,
                    Time = Now,
                    Value = "Zona temporal derecha"
                }
            ],
            Patient = patientObs,
            PatientNumber = "437537",
            Type = "ORU_R01",
            PatientId = PatientId.ToString(),
            MessageTime = Now
        };

        var obsIntravenousLines = new PatientIntravenousLinesValue
        {
            Type = "Cat�ter EPICUT�NEO PERIF�RICO",
            Location = "Zona temporal derecha",
            Action = "Insertado",
            InsertTime = Now,
            Duration = "7"
        };

        var newObs = new PatientObservation
        {
            Value = obsIntravenousLines,
            Code = "10546003",
            CodingSystem = "SNM",
            PatientId = patient.Id,
            MessageTime = Now,
            Time = Now
        };

        _patientServiceMock.Setup(cm => cm.FindPatientByApiRequest(apiRequest)).ReturnsAsync(patient);
        _configObservationService
            .Setup(o => o.Map(It.Is<PatientObservation>(arg => arg.PatientId == patient.Id), false))
            .ReturnsAsync(newObs);
        _configUnitsService.Setup(o => o.Map(It.Is<PatientObservation>(arg => arg.PatientId == patient.Id)))
            .ReturnsAsync(newObs);
        _configObservationService.Setup(o => o.RetentionActions(It.IsAny<PatientObservation>()))
            .ReturnsAsync(new ObservatitonRetentionResult());
        _unitServiceMock.Setup(o => o.FindById(It.IsAny<ObjectId>())).ReturnsAsync(new Unit
            { Configuration = new UnitConfiguration { AutoAdt = true } });
        await _observationService.SaveRequest(apiRequest);


        _observationRepository.Verify(o => o.InsertOneAsync(It.Is<PatientObservation>(arg =>
            arg.Value == newObs.Value &&
            arg.PatientId == newObs.PatientId &&
            arg.Code == newObs.Code &&
            arg.Time == newObs.Time &&
            arg.MessageTime == newObs.MessageTime &&
            arg.CodingSystem == newObs.CodingSystem
        )));
    }
}