using adas_core.Domain.Enums;
using adas_core.Domain.Models;
using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Models.GroupedObservations;
using adas_core.Domain.Models.MongoModels;
using adas_core.Infrastructure.Repositories;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
using Moq;
using static NUnit.Framework.Is;
using static adas_core.Domain.Enums.GroupedObservationEnum;
using Options = Microsoft.Extensions.Options.Options;

namespace adas_core.Test.Repositories;

[TestFixture]
[Order(1)]
[Category("Integration")]
public class ObservationRepositoryTest
{
    [OneTimeSetUp]
    public async Task Init()
    {
        _optionsApiSettings = Options.Create(_apiSettings);

        var patientObservation1 = new PatientObservation
        {
            Id = Id,
            PatientId = PatientId,
            Code = "code1",
            CodingSystem = "SNM",
            Name = "name1",
            Status = StatusEnum.Type.Ok,
            Time = Now,
            Value = "value1",
            SystemId = "systemId1"
        };

        var patientObservation2 = new PatientObservation
        {
            PatientId = PatientId,
            Code = "code2",
            CodingSystem = "MDC",
            Name = "name2",
            Status = StatusEnum.Type.Ok,
            Time = Now,
            Value = "value2"
        };

        var patientObservation3 = new PatientObservation
        {
            PatientId = PatientId,
            Code = "code1",
            CodingSystem = "SNM",
            Name = "name1",
            Status = StatusEnum.Type.Ok,
            Time = Now.AddDays(-1),
            Value = "value3",
            SystemId = "systemId1"
        };

        var patientObservation4 = new PatientObservation
        {
            PatientId = PatientId,
            Code = "code2",
            CodingSystem = "MDC",
            Name = "name2",
            Status = StatusEnum.Type.Ok,
            Time = Now.AddDays(-1),
            Value = "value4"
        };

        var patientObservation5 = new PatientObservation
        {
            PatientId = PatientId,
            Code = "code1",
            CodingSystem = "SNM",
            Name = "name1",
            Status = StatusEnum.Type.Ok,
            Time = Now.AddDays(-2),
            Value = "value5",
            SystemId = "systemId1"
        };

        var patientObservation6 = new PatientObservation
        {
            PatientId = PatientId,
            Code = "code2",
            CodingSystem = "MDC",
            Name = "name2",
            Status = StatusEnum.Type.Ok,
            Time = Now.AddDays(-2),
            Value = "value6"
        };

        await IntegrationDb.Database.DropCollectionAsync("patients_observations");
        await IntegrationDb.Database.CreateCollectionAsync("patients_observations");

        _logger = new Mock<ILogger<ObservationRepository>>();

        _repository = new ObservationRepository(_optionsApiSettings, IntegrationDb.Database, _logger.Object);

        await _repository.InsertOneAsync(patientObservation1);
        await _repository.InsertOneAsync(patientObservation2);
        await _repository.InsertOneAsync(patientObservation3);
        await _repository.InsertOneAsync(patientObservation4);
        await _repository.InsertOneAsync(patientObservation5);
        await _repository.InsertOneAsync(patientObservation6);
    }

    private ObservationRepository _repository;

    private readonly ApiSettings _apiSettings = new()
    {
        PatientsObservations = "patients_observations"
    };

    private IOptions<ApiSettings> _optionsApiSettings;
    private Mock<ILogger<ObservationRepository>> _logger;

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


    [Test]
    public async Task FindLastObservations_Return_List()
    {
        var result = await _repository.FindLastObservations(PatientId, "SNM", "code1");

        var patientObservations = result.ToList();
        Assert.That(patientObservations, Not.Null);
        Assert.That(patientObservations.Count(), EqualTo(2));
    }

    [Test]
    public async Task FindLastObservationsByCodingSystem_Return_List()
    {
        var result = await _repository.FindLastObservationsByCodingSystem(PatientId, "SNM");

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(3));
    }


    [Test]
    public async Task AggregatedPatientLastObservations_Null_Filter_Return_List()
    {
        var result = await _repository.AggregatedPatientLastObservations(PatientId, 2);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(4));
    }

    [Test]
    public async Task AggregatedPatientLastObservations_Filter_Return_List()
    {
        var filter = new List<string> { "name1" };

        var result = await _repository.AggregatedPatientLastObservations(PatientId, 2, filter);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(2));
    }

    [Test]
    public async Task AggregatedPatientLastObservations_Filter_Not_Find_Return_Empty_List()
    {
        var filter = new List<string> { "name3" };

        var result = await _repository.AggregatedPatientLastObservations(PatientId, 2, filter);

        Assert.That(result, Not.Null);
        Assert.That(result, Empty);
    }

    [Test]
    public async Task AggregatedPatientLastObservationsByLastDate_Null_Filter_Return_List()
    {
        var result = await _repository.AggregatedPatientLastObservationsByLastDate(PatientId, 2, Now);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(4));
    }

    [Test]
    public async Task AggregatedPatientLastObservationsByLastDate_Filter_Return_List()
    {
        var filter = new List<string> { "name1" };

        var result = await _repository.AggregatedPatientLastObservationsByLastDate(PatientId, 2, Now, filter);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(2));
    }

    [Test]
    public async Task AggregatedPatientLastObservationsByLastDate_Filter_Not_Find_Return_Empty_List()
    {
        var filter = new List<string> { "name3" };

        var result = await _repository.AggregatedPatientLastObservationsByLastDate(PatientId, 2, Now, filter);

        Assert.That(result, Not.Null);
        Assert.That(result, Empty);
    }

    [Test]
    public async Task AggregatedPatientLastObservationsByField_Null_Filter_Return_List()
    {
        var result = await _repository.AggregatedPatientLastObservationsByField(PatientId, null);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(6));
    }

    [Test]
    public async Task AggregatedPatientLastObservationsByField_Filter_Return_List()
    {
        var field = new List<Field> { new() { Name = "name1" } };

        var result = await _repository.AggregatedPatientLastObservationsByField(PatientId, field);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(1));
    }


    [Test]
    public async Task AggregatedPatientLastObservationsByField_Filter_OnlyExpired_Return_Empty_List()
    {
        var field = new List<Field> { new() { Name = "name1", OnlyExpired = true } };

        var result = await _repository.AggregatedPatientLastObservationsByField(PatientId, field);

        Assert.That(result, Not.Null);
        Assert.That(result, Empty);
    }


    [Test]
    public async Task DeleteByPatientId()
    {
        var patientObservation = new PatientObservation
        {
            Id = ObjectId.GenerateNewId(),
            PatientId = ObjectId.GenerateNewId(),
            Code = "code",
            CodingSystem = "MDC",
            Name = "name",
            Status = StatusEnum.Type.Ok,
            Time = Now,
            Value = "value"
        };

        await _repository.InsertOneAsync(patientObservation);

        var result = await _repository.Collection.FindAsync(t => t.PatientId == patientObservation.PatientId);

        Assert.That(result, Not.Null);
        Assert.That(result.ToList(), Has.Count.EqualTo(1));

        await _repository.DeleteByPatientId(patientObservation.PatientId);

        var resultDelete = await _repository.Collection.FindAsync(t => t.PatientId == patientObservation.PatientId);

        Assert.That(resultDelete, Not.Null);
        Assert.That(resultDelete.ToList(), Empty);
    }

    [Test]
    public async Task FindByPatientIdAsync_Return_Cursor()
    {
        var result = await _repository.FindByPatientIdAsync(PatientId);

        Assert.That(result, Not.Null);
        Assert.That(result.ToList(), Has.Count.EqualTo(6));
    }

    [Test]
    public async Task DeleteAsync()
    {
        var patientObservation = new PatientObservation
        {
            Id = ObjectId.GenerateNewId(),
            PatientId = ObjectId.GenerateNewId(),
            Code = "code",
            CodingSystem = "MDC",
            Name = "name",
            Status = StatusEnum.Type.Ok,
            Time = Now,
            Value = "value"
        };

        await _repository.InsertOneAsync(patientObservation);

        var result = await _repository.Collection.FindAsync(t => t.Id == patientObservation.Id);

        Assert.That(result, Not.Null);
        Assert.That(result.ToList(), Has.Count.EqualTo(1));

        await _repository.DeleteAsync(patientObservation.Id);

        var resultDelete = await _repository.Collection.FindAsync(t => t.Id == patientObservation.Id);

        Assert.That(resultDelete, Not.Null);
        Assert.That(resultDelete.ToList(), Empty);
    }

    [Test]
    public async Task DeleteOlderDaysAsync()
    {
        var patientObservation = new PatientObservation
        {
            Id = ObjectId.GenerateNewId(),
            PatientId = ObjectId.GenerateNewId(),
            Code = "code",
            CodingSystem = "MDC",
            Name = "name",
            Status = StatusEnum.Type.Ok,
            Time = Now,
            Value = "value"
        };

        var patientObservationOld = new PatientObservation
        {
            Id = ObjectId.GenerateNewId(),
            PatientId = patientObservation.PatientId,
            Code = "code",
            CodingSystem = "MDC",
            Name = "name",
            Status = StatusEnum.Type.Ok,
            Time = Now.AddDays(-15),
            Value = "value"
        };

        await _repository.InsertOneAsync(patientObservation);
        await _repository.InsertOneAsync(patientObservationOld);

        var result = await _repository.Collection.FindAsync(t => t.Name == patientObservation.Name);

        Assert.That(result, Not.Null);
        Assert.That(result.ToList(), Has.Count.EqualTo(2));

        await _repository.DeleteOlderDaysAsync(patientObservation.Name, 10);

        var resultDelete = await _repository.Collection.FindAsync(t => t.Name == patientObservation.Name);

        Assert.That(resultDelete, Not.Null);
        Assert.That(resultDelete.ToList(), Has.Count.EqualTo(1));

        await _repository.DeleteByPatientId(patientObservation.PatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == patientObservation.PatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Empty);
    }

    [Test]
    public async Task DeleteOlderSecondsAsync()
    {
        var patientObservation = new PatientObservation
        {
            Id = ObjectId.GenerateNewId(),
            PatientId = ObjectId.GenerateNewId(),
            Code = "code",
            CodingSystem = "MDC",
            Name = "name",
            Status = StatusEnum.Type.Ok,
            Time = Now,
            Value = "value"
        };

        var patientObservationOld = new PatientObservation
        {
            Id = ObjectId.GenerateNewId(),
            PatientId = patientObservation.PatientId,
            Code = "code",
            CodingSystem = "MDC",
            Name = "name",
            Status = StatusEnum.Type.Ok,
            Time = Now.AddSeconds(-15),
            Value = "value"
        };


        await _repository.InsertOneAsync(patientObservation);
        await _repository.InsertOneAsync(patientObservationOld);

        var result = await _repository.Collection.FindAsync(t => t.Name == patientObservation.Name);

        Assert.That(result, Not.Null);
        Assert.That(result.ToList(), Has.Count.EqualTo(2));

        await _repository.DeleteOlderSecondsAsync(patientObservation.Name, 10);

        var resultDelete = await _repository.Collection.FindAsync(t => t.Name == patientObservation.Name);

        Assert.That(resultDelete, Not.Null);
        Assert.That(resultDelete.ToList(), Has.Count.EqualTo(1));

        await _repository.DeleteByPatientId(patientObservation.PatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == patientObservation.PatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Empty);
    }

    [Test]
    public async Task DeleteOlderNumberAsync()
    {
        var patientObservation = new PatientObservation
        {
            Id = ObjectId.GenerateNewId(),
            PatientId = ObjectId.GenerateNewId(),
            Code = "code",
            CodingSystem = "MDC",
            Name = "name",
            Status = StatusEnum.Type.Ok,
            Time = Now,
            Value = "value"
        };

        var patientObservationOld1 = new PatientObservation
        {
            Id = ObjectId.GenerateNewId(),
            PatientId = patientObservation.PatientId,
            Code = "code",
            CodingSystem = "MDC",
            Name = "name",
            Status = StatusEnum.Type.Ok,
            Time = Now.AddSeconds(-10),
            Value = "value"
        };

        var patientObservationOld2 = new PatientObservation
        {
            Id = ObjectId.GenerateNewId(),
            PatientId = patientObservation.PatientId,
            Code = "code",
            CodingSystem = "MDC",
            Name = "name",
            Status = StatusEnum.Type.Ok,
            Time = Now.AddSeconds(-15),
            Value = "value"
        };


        await _repository.InsertOneAsync(patientObservation);
        await _repository.InsertOneAsync(patientObservationOld1);
        await _repository.InsertOneAsync(patientObservationOld2);

        var result = await _repository.Collection.FindAsync(t => t.Name == patientObservation.Name);

        Assert.That(result, Not.Null);
        Assert.That(result.ToList(), Has.Count.EqualTo(3));

        await _repository.DeleteOlderNumberAsync(patientObservation.Name, 2);

        var resultDelete = await _repository.Collection.FindAsync(t => t.Name == patientObservation.Name);

        Assert.That(resultDelete, Not.Null);
        Assert.That(resultDelete.ToList(), Has.Count.EqualTo(2));

        await _repository.DeleteByPatientId(patientObservation.PatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == patientObservation.PatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Empty);
    }

    [Test]
    public async Task ExistBySystemId_Return_List()
    {
        var result = await _repository.ExistBySystemId(PatientId, "systemId1");

        //Assert.That(result, Is.Not.Null);
        Assert.That(result, True);
    }

    [Test]
    public async Task FindLastObservationBeforeDate_Return_Obs()
    {
        var result = await _repository.FindLastObservationBeforeDate(PatientId, "name1", Now);

        Assert.That(result, Not.Null);
        Assert.That(result!.Time, LessThan(Now));
    }

    [Test]
    public async Task FindAnyWithSameDate_Return_List_Obs()
    {
        var result = await _repository.FindAnyWithSameDate(PatientId, "name1", Now);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(1));
    }

    [Test]
    public async Task FindAnyBeforeDate_Return_List_Obs()
    {
        var result = await _repository.FindAnyBeforeDate(PatientId, Now.AddDays(-1));

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(2));
    }

    [Test]
    public async Task AggregatedPatientActiveIntravenousLinesObservations_Null_Filter_Return_List_Obs()
    {
        var result = await _repository.AggregatedPatientActiveIntravenousLinesObservations(PatientId);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(0));
    }

    [Test]
    public async Task
        AggregatedPatientActiveIntravenousLinesObservations_Filter_Not_PatientIntravenousLineasValue_Return_List_Obs()
    {
        var result = await _repository.AggregatedPatientActiveIntravenousLinesObservations(PatientId);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(0));
    }

    [Test]
    public async Task
        AggregatedPatientActiveIntravenousLinesObservations_Filter_PatientIntravenousLineasValue_Return_List_Obs()
    {
        var intravenousLines = new PatientIntravenousLinesValue
        {
            Action = "action1", Duration = "duration1", InsertTime = Now, RemoveTime = Now, Location = "location1",
            Type = "type1"
        };

        var patientObservation = new PatientObservation
        {
            Id = ObjectId.GenerateNewId(),
            PatientId = ObjectId.GenerateNewId(),
            Code = "codeIntra",
            CodingSystem = "MDC",
            Name = "IntravenousLinesObs",
            Status = StatusEnum.Type.Ok,
            Time = Now,
            Value = intravenousLines
        };

        await _repository.InsertOneAsync(patientObservation);

        var result =
            await _repository.AggregatedPatientActiveIntravenousLinesObservations(patientObservation.PatientId);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(1));

        await _repository.DeleteByPatientId(patientObservation.PatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == patientObservation.PatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));
    }

    [Test]
    public async Task FindAllLastPatientObservationTime_Return_List()
    {
        var result = await _repository.FindAllLastPatientObservationTime();

        Assert.That(result, Not.Null);
        Assert.That(result.ToList(), Not.Empty);
    }

    [Test]
    public async Task FindById_Return_null()
    {
        var result = await _repository.FindById(ObjectId.GenerateNewId());

        Assert.That(result, Null);
    }

    [Test]
    public async Task FindById_Return_Obs()
    {
        var result = await _repository.FindById(Id);

        Assert.That(result, Not.Null);
        Assert.That(result!.Id, EqualTo(Id));
    }

    [Test]
    public async Task UpdateExpiredObservations()
    {
        var newPatientId = ObjectId.GenerateNewId();

        var lastNumber = 5;

        for (var i = 0; i < lastNumber; i++)
        {
            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameUpdate",
                Status = StatusEnum.Type.Ok,
                Time = Now.AddHours(-i),
                Value = $"value-{i}",
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var list = _repository.Collection.Find(p => p.PatientId == newPatientId).ToList();

        Assert.That(list, Not.Null);
        using (Assert.EnterMultipleScope())
        {
            Assert.That(list.Count(l => l.Expired), EqualTo(0));
            Assert.That(list.Count(l => !l.Expired), EqualTo(5));
        };
        await _repository.UpdateExpiredObservations(list);

        var result = await _repository.Collection.FindAsync(p => p.PatientId == newPatientId);
        var listResult = result.ToList();
        Assert.That(listResult, Not.Null);
        using (Assert.EnterMultipleScope())
        {
            Assert.That(listResult.Count(l => l.Expired), EqualTo(5));
            Assert.That(listResult.Count(l => !l.Expired), EqualTo(0));
        };
        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);
        var resultClearList = resultClear.ToList();
        Assert.That(resultClearList, Not.Null);
        Assert.That(resultClearList, Has.Count.EqualTo(0));
    }

    [Test]
    public async Task FindAll_Return_List_Obs()
    {
        var result = await _repository.FindAll();

        var patientObservations = result as PatientObservation[] ?? result.ToArray();
        Assert.That(patientObservations, Not.Null);
        Assert.That(patientObservations, Not.Empty);
    }

    [Test]
    public async Task FindNotExpired_Return_List_Obs()
    {
        var result = await _repository.FindNotExpired(["name1", "name2", "name2"]);

        var patientObservations = result as PatientObservation[] ?? result.ToArray();
        Assert.That(patientObservations, Not.Null);
        Assert.That(patientObservations.Count(), GreaterThan(0));
    }

    [Test]
    public async Task ExpireExpiredObservations()
    {
        var configObservationItems = new List<ConfigObservation>
        {
            new()
            {
                Id = ObjectId.GenerateNewId(),
                Name = "name1",
                Expires = 480
            },
            new()
            {
                Id = ObjectId.GenerateNewId(),
                Name = "name2",
                Expires = 480
            },
            new()
            {
                Id = ObjectId.GenerateNewId(),
                Name = "name3",
                Expires = 480
            },
            new()
            {
                Id = ObjectId.GenerateNewId(),
                Name = "name4",
                Expires = 480
            }
        };

        await _repository.ExpireExpiredObservations(configObservationItems);

        var result = await _repository.FindNotExpired(["name1", "name2", "name2"]);

        var patientObservations = result as PatientObservation[] ?? result.ToArray();
        Assert.That(patientObservations, Not.Null);
        Assert.That(patientObservations.ToList(), Has.Count.EqualTo(2));
    }

    [Test]
    public async Task FindByName_Return_List_Obs()
    {
        var result = await _repository.FindByName("name1");

        var patientObservations = result as PatientObservation[] ?? result.ToArray();
        Assert.That(patientObservations, Not.Null);
        Assert.That(patientObservations.Count(), GreaterThan(0));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Null_groupedField_Return_List_Emty()
    {
        var groupedField = new GroupedField();

        var result = await _repository.AggregatedPatientGroupedObservations(PatientId, groupedField);
        using (Assert.EnterMultipleScope())
        {
            Assert.That(result, Not.Null);
            Assert.That(!result.Any(), True);
        };
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Hour_Firs_Return_List_9()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.First],
            Max = 8
        };

        const int lastNumber = 30;

        var newPatientId = ObjectId.GenerateNewId();

        for (var i = 0; i < lastNumber; i++)
        {
            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = Now.AddHours(-i),
                Value = $"value-{i}",
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(9));

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Hour_Firs_Since_Last_Return_List_8()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.First],
            Max = 8,
            Since = Since.Last
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 30;

        for (var i = 0; i < lastNumber; i++)
        {
            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = Now.AddHours(-i),
                Value = $"value-{i}",
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(8));

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Insert_5_Hour_Firs_Return_List_5()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.First],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 5;

        for (var i = 0; i < lastNumber; i++)
        {
            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = Now.AddHours(-i),
                Value = $"value-{i}",
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        Assert.That(result, Not.Null);
        //Assert.That(result, Has.Count.EqualTo(5));
        Assert.That(result, Has.Count.EqualTo(5).Or.EqualTo(4));
        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));
    }


    [Test]
    public async Task AggregatedPatientGroupedObservations_second_Firs_Return_List()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Second,
            Result = [Result.First],
            Max = 60
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 120;

        for (var i = 0; i < lastNumber; i++)
        {
            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = Now.AddSeconds(-i),
                Value = $"value-{i}",
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        Assert.That(result, Not.Null);
        Assert.That(result, Not.Empty);

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Minute_Firs_Return_List_8()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Minute,
            Result = [Result.First],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 30;

        for (var i = 0; i < lastNumber; i++)
        {
            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = Now.AddMinutes(-i),
                Value = $"value-{i}",
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(8));

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Day_Firs_Return_List_8()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Day,
            Result = [Result.First],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 30;

        for (var i = 0; i < lastNumber; i++)
        {
            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = Now.AddDays(-i),
                Value = $"value-{i}",
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(8));

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Shift_Firs_Return_List_9()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Shift,
            Result = [Result.First],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 30;

        for (var i = 0; i < lastNumber; i++)
        {
            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = Now.AddHours(-i),
                Value = $"value-{i}",
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(9));
        Assert.That(result.FindAll(r => r.Contains("first")), Has.Count.EqualTo(9));

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Insert_5_Hour_last_Return_List_5()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.Last],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 5;

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 30, 00, 00);

            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = $"value-{i}",
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 15, 00, 00);


            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = $"value-{i}",
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(5));
        //Assert.That(result, Has.Count.EqualTo(5).Or.EqualTo(4));
        Assert.That(result.FindAll(r => r.Contains("last")), Has.Count.EqualTo(5));

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Insert_5_Hour_sum_Return_List_5()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.Sum],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 5;

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 30, 00, 00);

            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 5,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 15, 00, 00);


            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 5,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        using (Assert.EnterMultipleScope())
        {
            Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));

            Assert.That(result, Not.Null);
        };

        Assert.That(result, Has.Count.EqualTo(5));
        //Assert.That(result, Has.Count.EqualTo(5).Or.EqualTo(4));
        Assert.That(result.FindAll(r => r.Contains("sum")), Has.Count.EqualTo(5));


        for (var i = 0; i < lastNumber; i++) Assert.That(result[i]["sum"].ToInt32(), EqualTo(10).Or.EqualTo(5));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Insert_5_Hour_Min_Return_List_5()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.Min],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 5;

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 30, 00, 00);

            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 5,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 15, 00, 00);


            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 3,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(5));
        //Assert.That(result, Has.Count.EqualTo(5).Or.EqualTo(4));
        Assert.That(result.FindAll(r => r.Contains("min")), Has.Count.EqualTo(5));
        for (var i = 0; i < lastNumber; i++) Assert.That(result[i]["min"]["value"].ToInt32(), EqualTo(3));

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Insert_5_Hour_Max_Return_List_5()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.Max],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 5;

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 30, 00, 00);

            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 5,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 15, 00, 00);


            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 3,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        using (Assert.EnterMultipleScope())
        {
            Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));

            Assert.That(result, Not.Null);
        };

        Assert.That(result, Has.Count.EqualTo(5));
        //Assert.That(result, Has.Count.EqualTo(5).Or.EqualTo(4));
        Assert.That(result.FindAll(r => r.Contains("max")), Has.Count.EqualTo(5));
        for (var i = 0; i < lastNumber; i++) Assert.That(result[i]["max"]["value"].ToInt32(), EqualTo(5).Or.EqualTo(3));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Insert_5_Hour_Average_Return_List_5()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.Average],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 5;

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 30, 00, 00);

            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 5,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 15, 00, 00);


            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 3,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        using (Assert.EnterMultipleScope())
        {
            Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));

            Assert.That(result, Not.Null);
        };
        Assert.That(result, Has.Count.EqualTo(5));
        //Assert.That(result, Has.Count.EqualTo(5).Or.EqualTo(4));
        Assert.That(result.FindAll(r => r.Contains("average")), Has.Count.EqualTo(5));

        for (var i = 0; i < lastNumber; i++) Assert.That(result[i]["average"].ToInt32(), EqualTo(4).Or.EqualTo(3));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Insert_5_Hour_Count_Return_List_5()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.Count],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 5;

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 30, 00, 00);

            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 5,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 15, 00, 00);


            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 3,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        using (Assert.EnterMultipleScope())
        {
            Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));

            Assert.That(result, Not.Null);
        };

        Assert.That(result, Has.Count.EqualTo(5));
        //Assert.That(result.Count, Is.EqualTo(5).Or.EqualTo(4));
        Assert.That(result.FindAll(r => r.Contains("count")), Has.Count.EqualTo(5));
        for (var i = 0; i < lastNumber; i++) Assert.That(result[i]["count"].ToInt32(), EqualTo(2).Or.EqualTo(1));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Insert_5_Hour_HalfHour_Return_List_5()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.HalfHour],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 5;

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 31, 00, 00);

            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 5,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 15, 00, 00);


            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 3,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        using (Assert.EnterMultipleScope())
        {
            Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));

            Assert.That(result, Not.Null);
        };

        Assert.That(result, Has.Count.EqualTo(5));
        //Assert.That(result, Has.Count.EqualTo(5).Or.EqualTo(3));

        Assert.That(result.FindAll(r => r.Contains("all")), Has.Count.EqualTo(5).Or.EqualTo(3));
        //lastNumber = result.Count;

        //for (var i = 0; i < lastNumber; i++)
        //{
        //    Assert.Multiple(() =>
        //    {
        //        Assert.That(result[i]["all"][0]["value"].ToInt32(), Is.EqualTo(3));
        //        Assert.That(result[i]["all"][1]["value"].ToInt32(), Is.EqualTo(5).Or.EqualTo(3));
        //    });
        //}
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Insert_5_Hour_LastFilled_Return_List_5()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.LastFilled],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        var lastNumber = 5;

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 31, 00, 00);

            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 5,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 15, 00, 00);


            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 3,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        using (Assert.EnterMultipleScope())
        {
            Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));

            Assert.That(result, Not.Null);
        };

        Assert.That(result, Has.Count.EqualTo(5));
        //Assert.That(result, Has.Count.EqualTo(5).Or.EqualTo(4));
        Assert.That(result.FindAll(r => r.Contains("lastfilled")), Has.Count.EqualTo(5).Or.Count.EqualTo(3));
        lastNumber = result.Count;
        for (var i = 0; i < lastNumber; i++)
            Assert.That(result[i]["lastfilled"]["value"].ToInt32(), EqualTo(5).Or.EqualTo(3));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Insert_5_Hour_LastAll_Return_List_5()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Hour,
            Result = [Result.LastAll],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 5;

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 31, 00, 00);

            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 5,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        for (var i = 0; i < lastNumber; i++)
        {
            var time = new DateTime(Now.Year, Now.Month, Now.Day, Now.AddHours(-i).Hour, 15, 00, 00);


            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = time,
                Value = 3,
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        Assert.That(result, Not.Null);
        Assert.That(result, Has.Count.EqualTo(5));
        //Assert.That(result, Has.Count.EqualTo(5).Or.EqualTo(4));

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear, Not.Null);
        Assert.That(resultClear.ToList(), Has.Count.EqualTo(0));
    }

    [Test]
    public async Task AggregatedPatientGroupedObservations_Times_Firs_Return_List_8()
    {
        var groupedField = new GroupedField
        {
            Name = "nameG",
            Group = "nameGroup",
            Regularity = Regularity.Times,
            Result = [Result.First],
            Max = 8
        };

        var newPatientId = ObjectId.GenerateNewId();

        const int lastNumber = 30;

        for (var i = 0; i < lastNumber; i++)
        {
            var obs = new PatientObservation
            {
                Id = ObjectId.GenerateNewId(),
                PatientId = newPatientId,
                Code = "code",
                CodingSystem = "SNM",
                Name = "nameG",
                Status = StatusEnum.Type.Ok,
                Time = DateTime.Now,
                Value = $"value-{i}",
                SystemId = "systemId1"
            };

            await _repository.InsertOneAsync(obs);
        }

        //Thread.Sleep(TimeSpan.FromSeconds(1));

        await _repository.FindAll();

        var result = await _repository.AggregatedPatientGroupedObservations(newPatientId, groupedField);

        Assert.That(result,
            Has.Count.AnyOf(8,
                7)); //TODO: RevisarHay algún test que interfiere en el resultado. La primera vez que se lanza devuelve 7 y la segunda 8 

        await _repository.DeleteByPatientId(newPatientId);

        var resultClear = await _repository.Collection.FindAsync(t => t.PatientId == newPatientId);

        Assert.That(resultClear.ToList(), Empty);
    }
}