using LiteCharms.Features.Extensions; using LiteCharms.Features.Models; using LiteCharms.Features.Shop.Notifications.Models; using LiteCharms.Features.Shop.Postgres; namespace LiteCharms.Features.Shop.Notifications; public class NotificationService(IDbContextFactory contextFactory) { public async ValueTask> CreateNotificationAsync(CreateNotification request, CancellationToken cancellationToken = default) { try { using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var newNotification = context.Notifications.Add(new Entities.Notification { Direction = request.Direction, SenderName = request.Sender, SenderAddress = request.SenderAddress, RecipientName = request.Recipient, RecipientAddress = request.RecipientAddress, Subject = request.Subject, Message = request.Message, Platform = request.Platform, Priority = request.Priority, CorrelationId = request.CorrelationId, CorrelationIdType = request.CorrelationIdType, IsInternal = request.IsInternal, IsHtml = request.IsHtml, Processed = false }); return await context.SaveChangesAsync(cancellationToken) > 0 ? Result.Ok(newNotification.Entity.Id) : Result.Fail(new Error("Failed to create notification")); } catch (Exception ex) { return Result.Fail(new Error(ex.Message).CausedBy(ex)); } } public async ValueTask> GetNotificationAsync(Guid notificationId, CancellationToken cancellationToken = default) { try { await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var notification = await context.Notifications.FirstOrDefaultAsync(n => n.Id == notificationId, cancellationToken); return notification is not null ? Result.Ok(notification.ToModel()) : Result.Fail(new Error($"Notification with id {notificationId} not found")); } catch (Exception ex) { return Result.Fail(new Error(ex.Message).CausedBy(ex)); } } public async ValueTask> GetNotificationsAsync(DateRange range, CancellationToken cancellationToken = default) { try { var fromDate = range.From.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc); var toDate = range.To.ToDateTime(TimeOnly.MaxValue, DateTimeKind.Utc); using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var notifications = await context.Notifications.AsNoTracking() .Where(n => n.CreatedAt >= fromDate && n.CreatedAt <= toDate) .OrderByDescending(n => n.CreatedAt) .Take(range.MaxRecords) .ToArrayAsync(cancellationToken); return notifications?.Length > 0 ? Result.Ok(notifications.Select(n => n.ToModel()).ToArray()) : Result.Fail(new Error($"No notifications found for the specified date range {range.From} to {range.To}.")); } catch (Exception ex) { return Result.Fail(new Error(ex.Message).CausedBy(ex)); } } public async ValueTask UpdateNotificationAsync(UpdateNotification request, CancellationToken cancellationToken = default) { try { using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var notification = await context.Notifications.FirstOrDefaultAsync(n => n.Id == request.NotificationId, cancellationToken); if (notification is null) return Result.Fail(new Error($"Notification with id {request.NotificationId} not found.")); notification.Processed = request.Processed; notification.UpdatedAt = DateTime.UtcNow; if (request.HasError) { notification.HasError = request.HasError; notification.Errors = request.Errors; } return await context.SaveChangesAsync(cancellationToken) > 0 ? Result.Ok() : Result.Fail(new Error($"Failed to update notification with id {request.NotificationId}.")); } catch (Exception ex) { return Result.Fail(new Error(ex.Message).CausedBy(ex)); } } }