using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Services.Notifications;
using AsbCloudInfrastructure.Background;
using Microsoft.Extensions.DependencyInjection;

namespace AsbCloudWebApi.SignalR.Services;

public class SignalRNotificationTransportService : INotificationTransportService
{
	private readonly NotificationBackgroundWorker backgroundWorker;

	public SignalRNotificationTransportService(NotificationBackgroundWorker backgroundWorker)
	{
		this.backgroundWorker = backgroundWorker;
	}

	public int IdTransportType => 0;

	public Task SendAsync(NotificationDto notification,
		CancellationToken cancellationToken) => SendRangeAsync(new[] { notification }, cancellationToken);

	public Task SendRangeAsync(IEnumerable<NotificationDto> notifications, 
		CancellationToken cancellationToken)
	{
		var workId = HashCode.Combine(notifications.Select(n => n.Id)).ToString("x");

		if (backgroundWorker.Contains(workId)) 
			return Task.CompletedTask;

		var workAction = MakeSignalRSendWorkAction(notifications);
		var work = new WorkBase(workId, workAction);
		backgroundWorker.Push(work);

		return Task.CompletedTask;
	}

	private Func<string, IServiceProvider, CancellationToken, Task> MakeSignalRSendWorkAction(IEnumerable<NotificationDto> notifications)
	{
		return async (_, serviceProvider, cancellationToken) =>
		{
			var notificationPublisher = serviceProvider.GetRequiredService<NotificationPublisher>();

			var groupedNotificationsByUsers = notifications.GroupBy(n => n.IdUser);
			
			foreach (var groupedNotificationByUser in groupedNotificationsByUsers)
			{
				await notificationPublisher.PublishAsync(groupedNotificationByUser, cancellationToken);	
			}
		};
	}
}