using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using AsbCloudInfrastructure.Services;
using Microsoft.Extensions.Configuration;
using NSubstitute;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace AsbCloudInfrastructure.Tests.Services;

public class HelpPageServiceTest
{
    private const string urlPage = "test";
    private const string fileName = "Справка_для_страницы_test.pdf";
    private const int idCategory = 20000;

    private static Dictionary<string, string?> configSettings = new()
    {
        { "DirectoryNameHelpPageFiles", "helpPages" }
    };

    private static readonly MemoryStream fileStream = new(Array.Empty<byte>());

    private static readonly HelpPageDto existingHelpPage = new()
    {
        Id = 178,
        IdCategory = idCategory,
        UrlPage = "test2",
        Name = "Справка_для_страницы_test2.pdf"
    };

    private readonly IHelpPageRepository helpPageRepositoryMock = Substitute.For<IHelpPageRepository>();
    private readonly IFileStorageRepository fileStorageRepositoryMock = Substitute.For<IFileStorageRepository>();

    private readonly HelpPageService helpPageService;

    public HelpPageServiceTest()
    {
        IConfiguration configuration = new ConfigurationBuilder()
            .AddInMemoryCollection(configSettings)
            .Build();

        helpPageRepositoryMock.GetOrDefaultByUrlPageAndIdCategoryAsync(existingHelpPage.UrlPage, existingHelpPage.IdCategory, Arg.Any<CancellationToken>())
            .Returns(existingHelpPage);

        helpPageRepositoryMock.InsertAsync(Arg.Any<HelpPageDto>(), Arg.Any<CancellationToken>())
            .ReturnsForAnyArgs(1);

        fileStorageRepositoryMock.SaveFileAsync(Arg.Any<string>(), Arg.Any<Stream>(), Arg.Any<CancellationToken>());

        helpPageService = new HelpPageService(helpPageRepositoryMock,
            fileStorageRepositoryMock,
            configuration);
    }

    [Fact]
    public async Task AddOrUpdateAsync_ShouldReturn_AddedHelpPage()
    {
        //act
        var result = await helpPageService.AddOrUpdateAsync(urlPage,
            idCategory,
            fileName,
            fileStream,
            CancellationToken.None);

        //assert
        await helpPageRepositoryMock.Received().InsertAsync(Arg.Any<HelpPageDto>(), Arg.Any<CancellationToken>());
        await fileStorageRepositoryMock.Received().SaveFileAsync(Arg.Any<string>(), Arg.Any<Stream>(), Arg.Any<CancellationToken>());

        Assert.NotEqual(existingHelpPage.Id, result);
        Assert.NotEqual(urlPage, existingHelpPage.UrlPage);
        Assert.NotEqual(fileName, existingHelpPage.Name);
        Assert.Equal(idCategory, existingHelpPage.IdCategory);
    }


    [Fact]
    public async Task UpdateAsync_ShouldReturn_UpdatedHelpPage()
    {
        //act
        var result = await helpPageService.AddOrUpdateAsync(existingHelpPage.UrlPage,
            existingHelpPage.IdCategory,
            existingHelpPage.Name,
            fileStream,
            CancellationToken.None);

        //assert
        await helpPageRepositoryMock.Received().UpdateAsync(Arg.Any<HelpPageDto>(), Arg.Any<CancellationToken>());
        await fileStorageRepositoryMock.Received().SaveFileAsync(Arg.Any<string>(), Arg.Any<Stream>(), Arg.Any<CancellationToken>());

        Assert.Equal(existingHelpPage.Id, result);
    }
}