using AsbCloudApp.Data;
using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudInfrastructure.Services;
using AsbCloudInfrastructure.Tests.Services.DataSaubStat;
using Mapster;
using NSubstitute;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace AsbCloudInfrastructure.Tests.Services;

public class DataSaubStatDtillingQualityServiceTest
{
    private readonly IDataSaubStatRepository<DataSaubStatDrillingQualityDto> dataSaubStatRepositoryMock = Substitute.For<IDataSaubStatRepository<DataSaubStatDrillingQualityDto>>();
    private readonly ITelemetryDataCache<TelemetryDataSaubDto> telemetryDataCacheMock = Substitute.For<ITelemetryDataCache<TelemetryDataSaubDto>>();
    private readonly ITelemetryDataSaubService dataSaubServiceMock = Substitute.For<ITelemetryDataSaubService>();
    private readonly ITelemetryService telemetryServiceMock = Substitute.For<ITelemetryService>();

    private DataSaubStatDrillingQualityService dataSaubStatService;

    public DataSaubStatDtillingQualityServiceTest()
    {
        dataSaubStatService = new DataSaubStatDrillingQualityService(
            dataSaubStatRepositoryMock,
            telemetryDataCacheMock,
            dataSaubServiceMock,
            telemetryServiceMock);
    }

    [Theory]
    [InlineData("DataSaubStat.test3.csv", "DataSaubStat.test3_result.csv")]
    [InlineData("DataSaubStat.test2.csv", "DataSaubStat.test2_result.csv")]
    [InlineData("DataSaubStat.test1.csv", "DataSaubStat.test1_result.csv")]
    public async Task Create_DataSaubStatDrillingQuality_From_CSVFile_ShouldReturn_Success(
        string pathMockData,
        string pathResult
        )
    {
        var mockData = CsvMockHelper.Get<TelemetryDataSaubMap>(pathMockData);
        var dtoMockData = mockData.Select(x => x.Adapt<TelemetryDataSaubDto>()).ToArray();

        dataSaubServiceMock
            .Get(Arg.Any<int>(), Arg.Any<bool>(), Arg.Any<DateTimeOffset>(), Arg.Any<DateTimeOffset>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
            .Returns(dtoMockData);

        //act
        var actualData = await dataSaubStatService.CreateStatDrillingQualityForTelemetry(1, DateTimeOffset.UnixEpoch, CancellationToken.None);

        var mockDataResult = CsvMockHelper.Get<DataSaubStatDrillingQualityDtoMap>(pathResult);
        var expectedData = mockDataResult.Select(x => x.Adapt<DataSaubStatDrillingQualityDto>()).ToArray();

        //assert
        var actual = actualData
            .OrderBy(d => d.IdFeedRegulator)
            .ToArray();

        var expected = expectedData
            .OrderBy(d => d.IdFeedRegulator)
            .ToArray();

        Assert.Equal(expected.Count(), actual.Count());

        for (var i = 0; i < actual.Count(); i++)
        {
            var expectedItem = expected[i];
            var actualItem = actual[i];

            Assert.True(Math.Abs(expectedItem.DepthStart - actualItem.DepthStart) < 0.000001);
            Assert.True(Math.Abs(expectedItem.DepthEnd - actualItem.DepthEnd) < 0.000001);
            Assert.True(Math.Abs(expectedItem.DepthDrillingQuality - actualItem.DepthDrillingQuality) < 0.000001);
        }
    }
}