using adas_core.Domain.Enums;
using adas_core.Domain.Models;
using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Models.Pumps;
using adas_core.Infrastructure.Repositories;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using Options = Microsoft.Extensions.Options.Options;

namespace adas_core.Test.Repositories;

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

        var pump1 = new PumpObservation
        {
            Code = "Tile-6",
            Time = Now,
            Name = "g-1-pump-Tile-6",
            Number = 2,
            Total = 7,
            TotalAux = 0,
            Status = PumpEnum.Status.Infusing,
            PumpMode = PumpEnum.Mode.Infusing,
            InfusingStatus = PumpEnum.InfusingStatus.Infusing,
            Pressure = new CommonPumpTypes.PumpValue
            {
                Value = 6,
                Units = "mmHg"
            },
            DrugName = "Nutrición Parenteral",
            Concentration = new CommonPumpTypes.PumpValue
            {
                Value = 1,
                Units = "ml/ml"
            },
            DrugAmount = new CommonPumpTypes.PumpValue
            {
                Value = 1,
                Units = "ml"
            },
            DiluentVolume = new CommonPumpTypes.PumpValue
            {
                Value = 1,
                Units = "ml"
            },
            DoseRate = new CommonPumpTypes.PumpValue
            {
                Value = 27,
                Units = "ml/h"
            },
            Rate = new CommonPumpTypes.PumpValue
            {
                Value = 27,
                Units = "ml/h"
            },
            VolumeInfused = new CommonPumpTypes.PumpValue
            {
                Value = 127.52,
                Units = "ml"
            },
            VolumeRemaining = new CommonPumpTypes.PumpValue
            {
                Value = 0.00001
            },
            TimeRemaining = new CommonPumpTypes.PumpValue
            {
                Value = 0,
                Units = "min"
            },
            PatientWeight = new CommonPumpTypes.PumpValue
            {
                Value = 1,
                Units = "kg"
            },
            AlarmType = PumpEnum.AlarmType.Attention,
            GatewayNumber = 1,
            IsAux = false,
            IsInfusing = true
        };

        var pump2 = new PumpObservation
        {
            Code = "Tile-6",
            Time = Now.AddDays(-10),
            Name = "g-1-pump-Tile-6",
            Number = 2,
            Total = 7,
            TotalAux = 0,
            Status = PumpEnum.Status.Infusing,
            PumpMode = PumpEnum.Mode.Infusing,
            InfusingStatus = PumpEnum.InfusingStatus.Infusing,
            Pressure = new CommonPumpTypes.PumpValue
            {
                Value = 6,
                Units = "mmHg"
            },
            DrugName = "Nutrición Parenteral",
            Concentration = new CommonPumpTypes.PumpValue
            {
                Value = 1,
                Units = "ml/ml"
            },
            DrugAmount = new CommonPumpTypes.PumpValue
            {
                Value = 1,
                Units = "ml"
            },
            DiluentVolume = new CommonPumpTypes.PumpValue
            {
                Value = 1,
                Units = "ml"
            },
            DoseRate = new CommonPumpTypes.PumpValue
            {
                Value = 27,
                Units = "ml/h"
            },
            Rate = new CommonPumpTypes.PumpValue
            {
                Value = 27,
                Units = "ml/h"
            },
            VolumeInfused = new CommonPumpTypes.PumpValue
            {
                Value = 127.52,
                Units = "ml"
            },
            VolumeRemaining = new CommonPumpTypes.PumpValue
            {
                Value = 0.00001
            },
            TimeRemaining = new CommonPumpTypes.PumpValue
            {
                Value = 0,
                Units = "min"
            },
            PatientWeight = new CommonPumpTypes.PumpValue
            {
                Value = 1,
                Units = "kg"
            },
            AlarmType = PumpEnum.AlarmType.Attention,
            GatewayNumber = 1,
            IsAux = false,
            IsInfusing = true
        };

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

        _repository = new PumpArchiveRepository(_optionsApiSettings, IntegrationDb.Database);

        await _repository.InsertOneAsync(pump1);
        await _repository.InsertOneAsync(pump2);

        Assert.That(await _repository.Collection.CountDocumentsAsync(_ => true), Is.EqualTo(2));
    }

    private PumpArchiveRepository _repository;

    private readonly ApiSettings _apiSettings = new()
    {
        ArchivePatientsPumpobservations = "archive_patients_pumpobservations"
    };

    private IOptions<ApiSettings> _optionsApiSettings;

    private static readonly DateTime Now = DateTime.Now;


    /// <summary>
    /// Verifies that the <c>DeleteBeforeDate</c> repository method removes all records with a date earlier than the specified cutoff, retaining only records dated on or after that cutoff.
    /// </summary>
    [Test]
        public async Task DeleteBeforeDate()
        {
            var result = await _repository.Collection.FindAsync(_ => true);
    
            Assert.That(result, Is.Not.Null);
            Assert.That(result.ToList(), Has.Count.GreaterThan(1));
    
            await _repository.DeleteBeforeDate(Now.AddDays(-1));
    
            var resultDelete = await _repository.Collection.FindAsync(_ => true);
    
            Assert.That(resultDelete, Is.Not.Null);
            Assert.That(resultDelete.ToList(), Has.Count.EqualTo(1));
        }
}