using adas_core.Application.Repositories.Interfaces;
using adas_core.Application.Services;
using adas_core.Application.Services.Interfaces;
using adas_core.Domain.Enums;
using adas_core.Domain.Models.MongoModels;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Moq;

namespace adas_core.Test.Services;

[TestFixture]
[NonParallelizable]
internal class HistoricalConfigChangesServiceTest
{
    [SetUp]
    public void Setup()
    {
        _mockRepo = new Mock<IHistoricalConfigChangesRepository>();
        _mockLogger = new Mock<ILogger<HistoricalConfigChangesService>>();
        _service = new HistoricalConfigChangesService(_mockRepo.Object, _mockLogger.Object, _httpContextAccessor.Object,
            _auditService.Object);
    }

    private HistoricalConfigChangesService _service;
    private Mock<IHistoricalConfigChangesRepository> _mockRepo;
    private Mock<ILogger<HistoricalConfigChangesService>> _mockLogger;
    private readonly Mock<IHttpContextAccessor> _httpContextAccessor = new();
    private readonly Mock<ILocalAuditService> _auditService = new();


    [Test]
    public async Task FindLastConfigChanges_ReturnsLastConfigChange()
    {
        // Arrange
        var configType = DisplayConfigEnums.ConfigTypes.ObservationCfg;
        var mockResult = new List<HistoricalConfigChanges>
        {
            new() // Mock object with desired properties
        };
        _mockRepo.Setup(r => r.FindLastHistoricalConfigChangesByType(configType, 10)).ReturnsAsync(mockResult);

        // Act
        var result = await _service.FindLastConfigChanges(configType);

        // Assert
        Assert.That(result, Is.Not.Null);
        // Further assertions based on the expected result
    }

    [Test]
    public async Task InsertOne_WhenExceptionOccurs_ReturnsNull()
    {
        // Arrange
        var mockChange = new HistoricalConfigChanges();
        _mockRepo.Setup(r => r.InsertOneAsync(mockChange)).Throws(new Exception());

        // Act
        var result = await _service.InsertOne(mockChange);

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


    [Test]
    public async Task GetAll_ReturnsAllConfigChanges()
    {
        // Arrange
        var mockResult = new List<HistoricalConfigChanges>
        {
            new(),
            new()
        };
        _mockRepo.Setup(r => r.FindAll()).ReturnsAsync(mockResult);

        // Act
        var result = await _service.GetAll();

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

    [Test]
    public async Task GetByType_ReturnsCorrectAmountOfConfigs()
    {
        // Arrange
        var configType = DisplayConfigEnums.ConfigTypes.ObservationCfg;
        var mockResult = new List<HistoricalConfigChanges>
        {
            new(),
            new(),
            new()
        };
        _mockRepo.Setup(r => r.FindLastHistoricalConfigChangesByType(configType, 3)).ReturnsAsync(mockResult);

        // Act
        var result = await _service.GetByType(configType, 3);

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

    [Test]
    public async Task GetByUser_ReturnsCorrectConfigs()
    {
        // Arrange
        var user = "TestUser";
        var mockResult = new List<HistoricalConfigChanges>
        {
            new(),
            new()
        };
        _mockRepo.Setup(r => r.FindLastHistoricalConfigChangesByUser(user, null, 2)).ReturnsAsync(mockResult);

        // Act
        var result = await _service.GetByUser(user, null, 2);

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

    [Test]
    public async Task UpdateHistoricalConfigChange_WhenExceptionOccurs_ReturnsNull()
    {
        // Arrange
        var mockChange = new HistoricalConfigChanges();
        _mockRepo.Setup(r => r.Update(mockChange)).Throws(new Exception());

        // Act
        var result = await _service.UpdateHistoricalConfigChange(mockChange);

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