using System; using System.Linq; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudApp.Services.Notifications; using Microsoft.Extensions.DependencyInjection; namespace AsbCloudInfrastructure.Services.Notifications; public class NotificationService : INotificationService { private readonly ICrudRepository notificationCategoryRepository; private readonly INotificationRepository notificationRepository; private readonly IServiceProvider serviceProvider; public NotificationService(ICrudRepository notificationCategoryRepository, INotificationRepository notificationRepository, IServiceProvider serviceProvider) { this.notificationCategoryRepository = notificationCategoryRepository; this.notificationRepository = notificationRepository; this.serviceProvider = serviceProvider; } public async Task NotifyAsync(int idUser, int idNotificationCategory, string title, string message, int idTransportType, CancellationToken cancellationToken) { var notificationCategory = await notificationCategoryRepository .GetOrDefaultAsync(idNotificationCategory, cancellationToken); if(notificationCategory is null) throw new ArgumentInvalidException("Категория уведомления не найдена", nameof(idNotificationCategory)); var notification = new NotificationDto() { IdUser = idUser, IdNotificationCategory = idNotificationCategory, Title = title, Message = message, IdTransportType = idTransportType }; notification.Id = await notificationRepository.InsertAsync(notification, cancellationToken); notification.NotificationCategory = notificationCategory; var notificationTransportService = GetNotificationTransportService(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.SentDate = DateTime.UtcNow; } await notificationRepository.UpdateAsync(notification, cancellationToken); } public async Task ResendNotificationAsync(int idUser, NotificationRequest request, CancellationToken cancellationToken) { 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 = serviceProvider.GetServices() .FirstOrDefault(s => s.IdTransportType == idTransportType); if(notificationTransportService is null) throw new ArgumentInvalidException("Доставщик уведомлений не найден", nameof(idTransportType)); return notificationTransportService; } }