using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
namespace AsbCloudApp.Services.Notifications;
///
/// Сервис для работы с уведомлениями
///
public class NotificationService
{
private readonly ICrudRepository notificationCategoryRepository;
private readonly IUserRepository userRepository;
private readonly INotificationRepository notificationRepository;
private readonly IEnumerable notificationTransportServices;
///
/// Сервис для работы с уведомлениями
///
///
///
///
///
public NotificationService(ICrudRepository notificationCategoryRepository,
IUserRepository userRepository,
INotificationRepository notificationRepository,
IEnumerable notificationTransportServices)
{
this.userRepository = userRepository;
this.notificationCategoryRepository = notificationCategoryRepository;
this.notificationRepository = notificationRepository;
this.notificationTransportServices = notificationTransportServices;
}
///
/// Отправка нового уведомления
///
///
///
public async Task NotifyAsync(NotifyRequest request,
CancellationToken cancellationToken)
{
var notificationCategory = await notificationCategoryRepository
.GetOrDefaultAsync(request.IdNotificationCategory, cancellationToken)
?? throw new ArgumentInvalidException("Категория уведомления не найдена", nameof(request.IdNotificationCategory));
var user = await userRepository.GetOrDefaultAsync(request.IdUser, cancellationToken)
?? throw new ArgumentInvalidException("Пользователь не найден" , nameof(request.IdUser));
var notification = new NotificationDto
{
IdUser = request.IdUser,
RegistrationDate = DateTime.UtcNow,
IdNotificationCategory = request.IdNotificationCategory,
Title = request.Title,
Message = request.Message,
IdTransportType = request.IdTransportType,
};
notification.Id = await notificationRepository.InsertAsync(notification, cancellationToken);
notification.NotificationCategory = notificationCategory;
notification.User = user;
var notificationTransportService = GetNotificationTransportService(request.IdTransportType);
await notificationTransportService.SendAsync(notification, cancellationToken);
}
///
/// Обновление уведомления
///
///
///
///
///
public async Task UpdateNotificationAsync(int idNotification,
bool isRead,
CancellationToken cancellationToken)
{
var notification = await notificationRepository.GetOrDefaultAsync(idNotification,
cancellationToken)
?? throw new ArgumentInvalidException("Уведомление не найдено", nameof(idNotification));
if (isRead)
{
if (notification.SentDate == null)
throw new ArgumentInvalidException("Уведомление не может быть прочитано", nameof(isRead));
notification.ReadDate = DateTime.UtcNow;
}
await notificationRepository.UpdateAsync(notification,
cancellationToken);
}
///
/// Отправка уведомлений, которые не были отправлены
///
///
///
///
///
public async Task ResendNotificationAsync(int idUser,
NotificationRequest request,
CancellationToken cancellationToken)
{
if (!request.IdTransportType.HasValue)
throw new ArgumentInvalidException("Id типа доставки уведомления должен иметь значение",
nameof(request.IdTransportType));
var result = await notificationRepository.GetNotificationsAsync(idUser,
request,
cancellationToken);
var notificationTransportService = GetNotificationTransportService(request.IdTransportType.Value);
await notificationTransportService.SendRangeAsync(result.Items,
cancellationToken);
}
private INotificationTransportService GetNotificationTransportService(int idTransportType)
{
var notificationTransportService = notificationTransportServices
.FirstOrDefault(s => s.IdTransportType == idTransportType)
?? throw new ArgumentInvalidException("Доставщик уведомлений не найден", nameof(idTransportType));
return notificationTransportService;
}
}