using adas_core.Application.Repositories.Interfaces;
using adas_core.Domain.Enums;
using adas_core.Domain.Models.AppSettings;
using adas_core.Infrastructure.Repositories;
using adas_core.Test.Utilities;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using Moq;

namespace adas_core.Test.Repositories;

[TestFixture]
public class DisplayConfigTest
{
    /// <summary>
    /// Performs one-time setup for integration tests by initializing the display configuration, card configuration, and detail configuration repositories with test data, including a valid display configuration, a card configuration, and a nurse card details configuration.
    /// </summary>
    [OneTimeSetUp]
        public async Task SetUp()
        {
            Options.Create(new ApiSettings());
            _unitRepository = new Mock<IUnitRepository>();
            _displayCardConfigRepository =
                new DisplayCardConfigRepository(
                    IntegrationDb.Database,
                    new ApiSettings(),
                    new Mock<ILogger<DisplayCardConfigRepository>>().Object
                );
            _displayConfigRepository =
                new DisplayConfigRepository(
                    IntegrationDb.Database,
                    new ApiSettings(),
                    new Mock<ILogger<DisplayConfigRepository>>().Object,
                    _unitRepository.Object
                );
            _displayDetailConfigRepository =
                new DisplayDetailConfigRepository(
                    IntegrationDb.Database,
                    new ApiSettings(),
                    new Mock<ILogger<DisplayDetailConfigRepository>>().Object
                );
    
            await _displayDetailConfigRepository.InsertOneAsync(
                TestUtilities.CreateValidCardDetailsNurseConfig(_configDisplayCardDetailsId));
            await _displayCardConfigRepository.InsertOneAsync(TestUtilities.CreateValidCardConfig(_configDisplayCardId));
            await _displayConfigRepository.InsertOneAsync(TestUtilities.CreateValidDisplayConfig(
                DisplayConfigEnums.DisplayType.DisplayNurse, _configDisplayId, _configDisplayCardId,
                _configDisplayCardDetailsId));
        }

    /// <summary>
    /// One-time teardown method that cleans up the integration test database by dropping the display configuration collections created during testing.
    /// </summary>
    [OneTimeTearDown]
        public async Task Cleanup()
        {
            // Clean up database after tests
            await IntegrationDb.Database.DropCollectionAsync("config_displays");
            await IntegrationDb.Database.DropCollectionAsync("config_displays_card");
            await IntegrationDb.Database.DropCollectionAsync("config_displays_detail");
        }

    private DisplayConfigRepository _displayConfigRepository;
    private DisplayCardConfigRepository _displayCardConfigRepository;
    private DisplayDetailConfigRepository _displayDetailConfigRepository;
    private Mock<IUnitRepository> _unitRepository;
    private readonly ObjectId _configDisplayId = ObjectId.GenerateNewId();
    private readonly ObjectId _configDisplayCardId = ObjectId.GenerateNewId();
    private readonly ObjectId _configDisplayCardDetailsId = ObjectId.GenerateNewId();

    /// <summary>
    /// Verifies that retrieving a display configuration by its identifier returns a non-null result with the associated card and detail configurations populated.
    /// </summary>
    [Test]
        public async Task GetByIdShouldReturnAllConfigsAssociated()
        {
            var result = await _displayConfigRepository.GetById(_configDisplayId);
            Assert.That(result, Is.Not.Null);
            using (Assert.EnterMultipleScope())
            {
                Assert.That(result.CardConfigId, Is.Not.Null);
                Assert.That(result.CardConfig, Is.Not.Null);
                Assert.That(result.DetailConfigId, Is.Not.Null);
                Assert.That(result.DetailConfig, Is.Not.Null);
            };
        }
}