using AsbCloudApp.Data;
using AsbCloudApp.Data.User;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services.Notifications;
using AsbCloudInfrastructure.Services.Email;
using Microsoft.Extensions.Configuration;
using NSubstitute;
using System;
using System.Collections.Generic;
using System.Net.Mail;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace AsbCloudInfrastructure.Tests.Services.Notification;

public class EmailNotificationTransportServiceTests
{
    private IUserRepository userRepository;
    private INotificationTransportService notificationTransportService;

    private readonly NotificationDto notification = new NotificationDto()
    {
        Message = "Message",
        Title = "Title",
        IdUser = 1,
        IdTransportType = 1,
        IdState = 0,
        RegistrationDate = DateTimeOffset.Now,
        IdNotificationCategory = 10000,
    };
    private readonly UserExtendedDto user = new UserExtendedDto()
    {
        Id = 1,
        IdCompany = 1,
        Email = "studio@yandex.ru",
        IdState = 1,
        Login = "studio",
        Name = "Test",
        Patronymic = "Test",
        Phone = "22-22-22",
        Position = "Test",
        Surname = "Test",
    };

    private static Dictionary<string, string?> configSettings = new()
    {
        { "email:sender", "bot@digitaldrilling.ru" },
        { "email:password", "8wZrXSfP" },
        { "email:smtpServer", "smtp.timeweb.ru" }
    };

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

        userRepository = Substitute.For<IUserRepository>();

        notificationTransportService = new EmailNotificationTransportService(configuration, userRepository);
    }

    [Fact]
    public async Task SendAsyncThrowsMailboxUnavailable()
    {
        userRepository.GetOrDefaultAsync(Arg.Any<int>(), Arg.Any<CancellationToken>()).Returns(user);
        var exception = await Assert.ThrowsAsync<SmtpException>(() => notificationTransportService.SendAsync(notification, CancellationToken.None));
        Assert.Equal(SmtpStatusCode.MailboxUnavailable, exception.StatusCode);
    }
}