using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Services;

using Microsoft.Extensions.Logging;

using Moq;

using System.Collections.Concurrent;

namespace FabApprovalWorkerServiceTests;
public class TrainingRecordServiceTests {
    private static readonly ILogger<TrainingRecordService> MOCK_LOGGER = Mock.Of<ILogger<TrainingRecordService>>();

    private TrainingRecordService _trainingRecordService;

    [SetUp]
    public void Setup() {
        _trainingRecordService = new TrainingRecordService(MOCK_LOGGER);
    }

    [Test]
    public void ScrapeTrainingRecordsWithNullCsvReaderShouldThrowException() {
        Assert.Throws<ArgumentNullException>(() => _trainingRecordService.ScrapeTrainingRecordsFromCsvFile(null));
    }

    [Test]
    public void SortAndFilterWithNullArgShouldThrowException() {
        Assert.Throws<ArgumentNullException>(() => _trainingRecordService.SortAndFilterTrainingRecordsByCompletionDate(null));
    }

    [Test]
    public void SortAndFilterShouldProduceExpectedResult() {
        List<TrainingRecord> trainingRecords = new List<TrainingRecord>() { 
            new TrainingRecord() {
                ItemId = "item1",
                UserId = "User1",
                LastName = "LastName1",
                FirstName = "FirstName1",
                CompletionDate = DateTime.Now
            },
            new TrainingRecord() {
                ItemId = "item1",
                UserId = "User2",
                LastName = "LastName2",
                FirstName = "FirstName2",
                CompletionDate = DateTime.Now
            },
            new TrainingRecord() {
                ItemId = "item1",
                UserId = "User1",
                LastName = "LastName1",
                FirstName = "FirstName1",
                CompletionDate = DateTime.Now.AddDays(-1)
            },
            new TrainingRecord() {
                ItemId = "item1",
                UserId = "User2",
                LastName = "LastName2",
                FirstName = "FirstName2",
                CompletionDate = DateTime.Now.AddDays(-1)
            },
            new TrainingRecord() {
                ItemId = "item1",
                UserId = "User1",
                LastName = "LastName1",
                FirstName = "FirstName1",
                CompletionDate = DateTime.Now.AddDays(-30)
            },
            new TrainingRecord() {
                ItemId = "item1",
                UserId = "User2",
                LastName = "LastName2",
                FirstName = "FirstName2",
                CompletionDate = DateTime.Now.AddDays(-30)
            },
            new TrainingRecord() {
                ItemId = "item2",
                UserId = "User1",
                LastName = "LastName1",
                FirstName = "FirstName1",
                CompletionDate = DateTime.Now
            },
            new TrainingRecord() {
                ItemId = "item2",
                UserId = "User2",
                LastName = "LastName2",
                FirstName = "FirstName2",
                CompletionDate = DateTime.Now
            },
            new TrainingRecord() {
                ItemId = "item2",
                UserId = "User1",
                LastName = "LastName1",
                FirstName = "FirstName1",
                CompletionDate = DateTime.Now.AddDays(-5)
            },
            new TrainingRecord() {
                ItemId = "item2",
                UserId = "User2",
                LastName = "LastName2",
                FirstName = "FirstName2",
                CompletionDate = DateTime.Now.AddDays(-5)
            }
        };

        ConcurrentDictionary<(string, string), TrainingRecord> actualRecords = _trainingRecordService.SortAndFilterTrainingRecordsByCompletionDate(trainingRecords);

        Assert.That(actualRecords.Count, Is.EqualTo(4));
        Assert.That(actualRecords[("FirstName1LastName1", "item1")].CompletionDate, Is.GreaterThan(DateTime.Now.AddDays(-1)));
        Assert.That(actualRecords[("FirstName2LastName2", "item2")].CompletionDate, Is.GreaterThan(DateTime.Now.AddDays(-5)));
    }
}
