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

namespace AsbCloudWebApi.SignalR.Services;

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

	public NotificationPublisher(ConnectionManagerService connectionManagerService,
		IHubContext<NotificationHub> 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 = DateTime.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)
			.SendAsync("receiveNotifications",
				message,
				cancellationToken);
	}
}