File size: 4,156 Bytes
4433399
ccc2569
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d8a7fc4
 
 
 
ccc2569
 
 
d8a7fc4
 
 
ccc2569
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313d29f
 
 
 
 
 
 
 
 
 
ccc2569
 
 
 
 
 
4433399
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using LibraryManagement.Shared.Models;
using FirebaseAdmin.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DbConnect.Data;
using DbConnect.Entities;
using Microsoft.EntityFrameworkCore;

namespace Backend.Features.Notification;

public class NotificationService : INotificationService
{
    private readonly AppDbContext _context;

    public NotificationService(AppDbContext context)
    {
        _context = context;
    }

    public async Task<bool> SendNotificationAsync(string token, string title, string body, Dictionary<string, string>? data = null)
    {
        var message = new Message()
        {
            Token = token,
            Notification = new FirebaseAdmin.Messaging.Notification()
            {
                Title = title,
                Body = body
            },
            Data = data
        };

       try

      {string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
        return !string.IsNullOrEmpty(response);
        }
        catch (Exception ex)
        {
           Console.WriteLine($"Error sending FCM message: {ex.Message}");
           return false;
       }
    }

    public async Task<bool> SendAndSaveNotificationAsync(Guid userId, string? token, string title, string body, string type = "Info", string? actionLink = null, string? actionText = null)
    {
        // 0. Verify User Exists
        var userExists = await _context.Users.AnyAsync(u => u.Id == userId);
        if (!userExists)
        {
            Console.WriteLine($"[NotificationService] Error: User with ID {userId} not found. Cannot save notification.");
            return false;
        }

        // 1. Save to Database
        var notification = new DbConnect.Entities.Notification
        {
            UserId = userId,
            Title = title,
            Message = body,
            Type = type,
            ActionLink = actionLink,
            ActionText = actionText,
            CreatedAt = DateTime.Now,
            IsRead = false
        };

        _context.Notifications.Add(notification);
        await _context.SaveChangesAsync();

        // 2. Send via FCM if token exists
        if (!string.IsNullOrEmpty(token))
        {
            var data = new Dictionary<string, string>
            {
                { "type", type }
            };
            if (!string.IsNullOrEmpty(actionLink)) data.Add("actionLink", actionLink);
            if (!string.IsNullOrEmpty(actionText)) data.Add("actionText", actionText);

            return await SendNotificationAsync(token, title, body, data);
        }

        return true;
    }

    public async Task<List<NotificationDto>> GetUserNotificationsAsync(Guid userId)
    {
        return await _context.Notifications
            .Where(n => n.UserId == userId)
            .OrderByDescending(n => n.CreatedAt)
            .Select(n => new NotificationDto
            {
                Id = n.Id,
                Title = n.Title,
                Message = n.Message,
                Type = n.Type,
                ActionLink = n.ActionLink,
                ActionText = n.ActionText,
                IsRead = n.IsRead,
                CreatedAt = n.CreatedAt
            })
            .ToListAsync();
    }

    public async Task<bool> MarkAllAsReadAsync(Guid userId)
    {
        var unread = await _context.Notifications
            .Where(n => n.UserId == userId && !n.IsRead)
            .ToListAsync();

        if (unread.Any())
        {
            foreach (var n in unread)
            {
                n.IsRead = true;
            }
            await _context.SaveChangesAsync();
        }

        return true;
    }

    public async Task<bool> MarkAsReadAsync(int id)
    {
        var notif = await _context.Notifications.FindAsync(id);
        if (notif == null) return false;

        notif.IsRead = true;
        await _context.SaveChangesAsync();
        return true;
    }

    public async Task<int> GetUnreadCountAsync(Guid userId)
    {
        return await _context.Notifications
            .CountAsync(n => n.UserId == userId && !n.IsRead);
    }
}