using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using AsbCloudWebApi.SignalR.Clients;
using AsbCloudWebApi.SignalR.Messages;
using Microsoft.AspNetCore.SignalR;

namespace AsbCloudWebApi.SignalR.Services;

public class NotificationPublisher
{
   private readonly ConnectionManagerService connectionManagerService;
   private readonly IHubContext<NotificationHub, INotificationHubClient> notificationHubContext;
   private readonly INotificationRepository notificationRepository;

   public NotificationPublisher(ConnectionManagerService connectionManagerService,
      IHubContext<NotificationHub, INotificationHubClient> notificationHubContext,
      INotificationRepository notificationRepository)
   {
      this.connectionManagerService = connectionManagerService;
      this.notificationHubContext = notificationHubContext;
      this.notificationRepository = notificationRepository;
   }

   public async Task PublishAsync(IGrouping<int, NotificationDto> groupedNotifications, CancellationToken cancellationToken)
   {
      const int idTransportType = 0;
      
      var connectionId = connectionManagerService.GetConnectionIdByUserId(groupedNotifications.Key);

      if (!string.IsNullOrWhiteSpace(connectionId))
      {
         foreach (var notification in groupedNotifications)
         {
            notification.SentDate = DateTimeOffset.UtcNow;
         }

         var notifications = groupedNotifications.Select(n => n);
         
         await notificationRepository.UpdateRangeAsync(notifications, 
            cancellationToken);
         
         await PublishMessageAsync(connectionId, new NotificationMessage
         {
            Notifications = notifications,
            CountUnread = await notificationRepository.GetUnreadCountAsync(groupedNotifications.Key,
               idTransportType,
               cancellationToken)
         }, cancellationToken);
      }
   }

   public async Task PublishCountUnreadAsync(int idUser, CancellationToken cancellationToken)
   {
      var connectionId = connectionManagerService.GetConnectionIdByUserId(idUser);

      if (!string.IsNullOrWhiteSpace(connectionId))
      {
         await PublishMessageAsync(connectionId, new NotificationMessage
         {
            CountUnread =  await notificationRepository.GetUnreadCountAsync(idUser, 0,
               cancellationToken)
         }, cancellationToken);
      }
   }

   private async Task PublishMessageAsync(string connectionId, NotificationMessage message,
      CancellationToken cancellationToken)
   {
      await notificationHubContext.Clients.Client(connectionId)
         .ReceiveNotifications(message, cancellationToken);
   }
}