using Application.Abstractions.Data;
using Application.Abstractions.Hub;
using Application.Abstractions.Notification;
using Domain.Entities.Notifications.ValueObject;
using Infrastructure.Hubs;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;

namespace Infrastructure.Notification;

internal sealed class NotificationService(
    IAppDbContext db,
    IHubContext<AppHub, IAppHubClient>? appHub = null
) : INotificationService
{
    public async Task SendAsync(
        int memberID, NotificationType type, string title, string message,
        string? actionUrl, string? relatedType, int? relatedID, string? imageUrl,
        CancellationToken ct)
    {
        var notification = Domain.Entities.Notifications.Notification.Create(
            memberID, type, title, message, actionUrl, relatedType, relatedID, imageUrl
        );

        db.Notification.Add(notification);
        await db.SaveChangesAsync(ct);

        // SignalR Push (Hub가 등록된 경우에만)
        if (appHub is not null)
        {
            await appHub.Clients.Group($"member:{memberID}").ReceiveNotification(new
            {
                notification.ID, notification.Type, notification.Title,
                notification.Message, notification.ActionUrl, notification.ImageUrl,
                notification.CreatedAt
            });

            var unreadNotif = await db.Notification.CountAsync(n => n.MemberID == memberID && !n.IsRead, ct);
            var unreadNote = await db.Note.CountAsync(n => n.ReceiverMemberID == memberID && !n.IsDeletedByReceiver && !n.IsRead, ct);
            await appHub.Clients.Group($"member:{memberID}").ReceiveUnreadCounts(unreadNotif, unreadNote);
        }
    }

    public async Task SendToManyAsync(
        IEnumerable<int> memberIDs, NotificationType type, string title, string message,
        string? actionUrl, string? relatedType, int? relatedID, string? imageUrl,
        CancellationToken ct)
    {
        foreach (var memberID in memberIDs)
        {
            await SendAsync(memberID, type, title, message, actionUrl, relatedType, relatedID, imageUrl, ct);
        }
    }
}