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

namespace adas_core.Test.Repositories;

[TestFixture]
public class PoCSettingsRepositoryTest
{
    [OneTimeSetUp]
    public async Task Init()
    {
        _optionsApiSettings = Options.Create(_apiSettings);

        await IntegrationDb.Database.DropCollectionAsync(_apiSettings.PoCSettings);
        await IntegrationDb.Database.CreateCollectionAsync(_apiSettings.PoCSettings);

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

        await _repository.InsertOneAsync(TestPoCSettings);
    }

    private PoCSettingsRepository _repository;

    private readonly ApiSettings _apiSettings = new()
    {
        PoCSettings = "poc_settings"
    };

    private IOptions<ApiSettings> _optionsApiSettings;

    private static readonly ObjectId TestObjectId = ObjectId.GenerateNewId();
    private static readonly PatientLocation TestLocation = new("POC1", "Bed1");

    private static readonly PoCSettings TestPoCSettings = new()
    {
        Id = TestObjectId,
        PatientLocation = TestLocation
    };

    [Test]
    public async Task Delete_WhenCalled_ShouldRemovePoCSettings()
    {
        // Arrange
        var newObjectId = ObjectId.GenerateNewId();
        var newPoCSettings = new PoCSettings
        {
            Id = newObjectId,
            PatientLocation = new PatientLocation("poc2", "bed2")
        };
        await _repository.InsertOneAsync(newPoCSettings);

        // Act
        await _repository.Delete(newObjectId);

        // Assert
        var result = await _repository.FindById(newObjectId);
        Assert.That(result, Is.Null);
    }

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

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

    [Test]
    public async Task FindById_WhenCalled_ShouldReturnPoCSettings()
    {
        // Act
        var result = await _repository.FindById(TestObjectId);

        // Assert
        Assert.That(result, Is.Not.Null);
        Assert.That(result?.Id, Is.EqualTo(TestObjectId));
    }

    [Test]
    public async Task FindByLocation_WhenCalled_ShouldReturnPoCSettings()
    {
        // Act
        var result = await _repository.FindByLocation(TestLocation);

        // Assert
        Assert.That(result, Is.Not.Null);
        Assert.That(result?.PatientLocation, Is.EqualTo(TestLocation));
    }

    [Test]
    public async Task Update_WhenCalled_ShouldUpdatePoCSettings()
    {
        // Arrange
        var updatedPoCSettings = new PoCSettings
        {
            Id = TestObjectId,
            PatientLocation = new PatientLocation("POC3", "Bed3")
        };

        // Act
        await _repository.Update(updatedPoCSettings);

        // Assert
        var result = await _repository.FindById(TestObjectId);
        Assert.That(result, Is.Not.Null);
        //Assert.That(result?.PatientLocation?.PointOfCare, Is.EqualTo("POC3"));
        Assert.That(result?.PatientLocation?.Bed, Is.EqualTo("Bed3"));
    }
}