using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudInfrastructure.Services.ProcessMaps;
using NSubstitute;
using Xunit;

namespace AsbCloudWebApi.Tests.Services.ProcessMaps;

public class ProcessMapPlanServiceTests
{
    private const int idWellSectionPlan = 1;
    private const int idWell = 3;
    private const int idWellSectionType = 54;

    private readonly IEnumerable<WellSectionPlanDto> fakeCollectionWellSectionPlan = new WellSectionPlanDto[]
    {
        new()
        {
            Id = idWellSectionPlan,
            IdWell = idWell,
            IdSectionType = idWellSectionType,
            DepthStart = 80,
            DepthEnd = 150
        }
    };

    private readonly IEnumerable<WellSectionTypeDto> fakeCollectionWellSectionTypes = new WellSectionTypeDto[]
    {
        new()
        {
            Id = idWellSectionType,
            Caption = "Направление 1",
            Order = 1
        }
    };

    private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepositoryMock =
        Substitute.For<ICrudRepository<WellSectionTypeDto>>();

    private readonly IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanRepositoryMock =
        Substitute.For<IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto>>();

    private readonly IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepositoryMock =
        Substitute.For<IRepositoryWellRelated<WellSectionPlanDto>>();

    private readonly ProcessMapPlanService<ProcessMapPlanWellDrillingDto> processMapPlanService;

    public ProcessMapPlanServiceTests()
    {
        processMapPlanService = new ProcessMapPlanService<ProcessMapPlanWellDrillingDto>(wellSectionTypeRepositoryMock,
            processMapPlanRepositoryMock, wellSectionPlanRepositoryMock);

        wellSectionPlanRepositoryMock.GetByIdWellAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
            .ReturnsForAnyArgs(fakeCollectionWellSectionPlan);

        wellSectionTypeRepositoryMock.GetAllAsync(Arg.Any<CancellationToken>())
            .ReturnsForAnyArgs(fakeCollectionWellSectionTypes);
    }

    [Theory]
    [InlineData(80, 150, true)]
    [InlineData(90, 140, true)]
    [InlineData(0, 110, false)]
    [InlineData(110, 200, false)]
    public async Task GetAsync_ReturnsValidatedCollectionProcessMapPlanWellDrilling(int depthStart, int depthEnd, bool isValidCollection)
    {
        //arrange
        var fakeCollectionProcessMapPlanWellDrilling = new ProcessMapPlanWellDrillingDto[]
        {
            new()
            {
                IdWellSectionType = idWellSectionType,
                DepthStart = depthStart,
                DepthEnd = depthEnd
            }
        };

        processMapPlanRepositoryMock.GetByIdWellAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
            .ReturnsForAnyArgs(fakeCollectionProcessMapPlanWellDrilling);

        //act
        var result = (await processMapPlanService.GetAsync(idWell, CancellationToken.None)).ToArray();

        //assert
        Assert.Equal(isValidCollection, result.All(r => r.IsValid));
        Assert.Single(result);
    }
}