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

namespace adas_core.Test.Repositories;

[TestFixture]
[Category("Integration")]
public class AppointmentArchiveRepositoryTest
{
    /// <summary>
    /// One-time test setup that initializes the appointments archive collection with two seed
    /// <see cref="PatientAppointment"/> records — a minimal appointment and a fully populated one with
    /// visit number, reason, and resource group location — for use by integration tests against
    /// <see cref="AppointmentArchiveRepository"/>.
    /// </summary>
    /// <returns>A <see cref="Task"/> that completes when the collection has been recreated and both
    /// seed appointments have been inserted.</returns>
    [OneTimeSetUp]
        public async Task Init()
        {
            _optionsApiSettings = Options.Create(_apiSettings);
    
            var patient = new Person
            {
                FirstName = "firstName",
                SecondName = "secondName",
                BirthDate = Now.AddYears(-10),
                Gender = PatientEnum.Gender.Female,
                Ids = new Dictionary<string, string> { { "MR", "123456" }, { "VN", "654321" } }
            };
    
            PatientAppointment testPatientAppointment = new()
            {
                PatientId = PatientId,
                Patient = patient,
                CreateTime = Now.AddHours(-2),
                UpdateTime = Now.AddHours(-2)
            };
    
            PatientAppointment testPatientAppointment2 = new()
            {
                PatientId = PatientId,
                Patient = patient,
                CreateTime = Now.AddHours(-3),
                UpdateTime = Now.AddHours(-3),
                VisitNumber = "654321",
                AppointmentReason = "appointmentReason",
                ResourceGroups =
                [
                    new PatientAppointmentResourceGroup
                    {
                        Locations = [new PatientLocation("UCI5C", "Box4")]
                    }
                ]
            };
    
            await IntegrationDb.Database.DropCollectionAsync("patients_appointments");
            await IntegrationDb.Database.CreateCollectionAsync("patients_appointments");
    
            _repository = new AppointmentArchiveRepository(_optionsApiSettings, IntegrationDb.Database);
    
            await _repository.InsertOneAsync(testPatientAppointment);
            await _repository.InsertOneAsync(testPatientAppointment2);
        }

    private AppointmentArchiveRepository _repository;

    private readonly ApiSettings _apiSettings = new()
    {
        ArchivePatientsAppointments = "archive_patients_appointments"
    };

    private IOptions<ApiSettings> _optionsApiSettings;
    //Mock<ILogger<ObservationRepository>> logger;

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


    /// <summary>
    /// Verifies that the repository's <c>DeleteBeforeDate</c> method correctly removes all records
    /// with a timestamp earlier than the specified cutoff date (two hours before the current time),
    /// while retaining records dated at or after the cutoff for the given patient.
    /// </summary>
    [Test]
        public async Task DeleteBeforeDate()
        {
            var result = await _repository.Collection.FindAsync(p => p.PatientId == PatientId);
    
            Assert.That(result, Is.Not.Null);
            Assert.That(result.ToList(), Has.Count.GreaterThan(1));
    
            await _repository.DeleteBeforeDate(Now.AddHours(-2));
    
            var resultDelete = await _repository.Collection.FindAsync(p => p.PatientId == PatientId);
    
            Assert.That(resultDelete, Is.Not.Null);
            Assert.That(resultDelete.ToList(), Has.Count.EqualTo(1));
        }
}