using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Nuuru.Server.Auth; using Nuuru.Server.DTOs; using Nuuru.Server.DTOs.Notification; using Nuuru.Server.Extensions; using Nuuru.Server.Services; namespace Nuuru.Server.Controllers { [ApiController] [Route("api/notifications")] [Authorize] public class NotificationController : ControllerBase { private readonly INotificationService _notificationService; private readonly IForumPostService _forumPostService; private readonly IMessageService _messageService; private readonly ILogger _logger; public NotificationController(INotificationService notificationService, IForumPostService forumPostService, IMessageService messageService, ILogger logger) { _notificationService = notificationService; _forumPostService = forumPostService; _messageService = messageService; _logger = logger; } /// /// Get current user's notifications /// [HttpGet] public async Task GetNotifications([FromQuery] int page = 1, [FromQuery] int pageSize = 20) { try { var userId = User.GetUserId(); if (userId == null) return Unauthorized(); if (page < 1) page = 1; if (pageSize < 1 || pageSize > 100) pageSize = 20; var (notifications, totalCount) = await _notificationService.GetUserNotificationsPagedAsync(userId.Value, page, pageSize); var dtos = notifications.ToDto().ToList(); foreach (var dto in dtos) { if (dto.RelatedForumPostId.HasValue && dto.RelatedForumThreadId.HasValue) { dto.RelatedForumPostPage = await _forumPostService.GetPostPageAsync( dto.RelatedForumThreadId.Value, dto.RelatedForumPostId.Value) ?? 1; } if (dto.RelatedConversationId.HasValue && dto.RelatedMessageId.HasValue) { dto.RelatedMessagePage = await _messageService.GetMessagePageAsync( dto.RelatedConversationId.Value, dto.RelatedMessageId.Value) ?? 1; } } return Ok(new PagedResult { Items = dtos, TotalCount = totalCount, Page = page, PageSize = pageSize }); } catch (Exception ex) { _logger.LogError(ex, "Error retrieving notifications"); return StatusCode(500, new { error = "Failed to retrieve notifications" }); } } /// /// Get unread notification count /// [HttpGet("unread-count")] public async Task GetUnreadCount() { try { var userId = User.GetUserId(); if (userId == null) return Unauthorized(); var count = await _notificationService.GetUnreadCountAsync(userId.Value); return Ok(new { count }); } catch (Exception ex) { _logger.LogError(ex, "Error retrieving unread count"); return StatusCode(500, new { error = "Failed to retrieve unread count" }); } } /// /// Mark a notification as read /// [HttpPost("{id:guid}/read")] public async Task MarkAsRead(Guid id) { try { var userId = User.GetUserId(); if (userId == null) return Unauthorized(); await _notificationService.MarkAsReadAsync(id, userId.Value); return NoContent(); } catch (Exception ex) { _logger.LogError(ex, "Error marking notification {NotificationId} as read", id); return StatusCode(500, new { error = "Failed to mark notification as read" }); } } /// /// Mark all notifications as read /// [HttpPost("read-all")] public async Task MarkAllAsRead() { try { var userId = User.GetUserId(); if (userId == null) return Unauthorized(); await _notificationService.MarkAllAsReadAsync(userId.Value); return NoContent(); } catch (Exception ex) { _logger.LogError(ex, "Error marking all notifications as read"); return StatusCode(500, new { error = "Failed to mark all notifications as read" }); } } /// /// Delete a notification /// [HttpDelete("{id:guid}")] public async Task DeleteNotification(Guid id) { try { var userId = User.GetUserId(); if (userId == null) return Unauthorized(); await _notificationService.DeleteNotificationAsync(id, userId.Value); return NoContent(); } catch (Exception ex) { _logger.LogError(ex, "Error deleting notification {NotificationId}", id); return StatusCode(500, new { error = "Failed to delete notification" }); } } /// /// Create a system announcement (admin only) /// [HttpPost("announcement")] [Authorize(Policy = Permissions.Admin.SendAnnouncements)] public async Task CreateAnnouncement([FromBody] CreateAnnouncementRequest request) { try { if (string.IsNullOrWhiteSpace(request.Message)) { return BadRequest(new { error = "Message is required" }); } await _notificationService.CreateSystemAnnouncementAsync(request.Message); return Ok(new { message = "Announcement created" }); } catch (Exception ex) { _logger.LogError(ex, "Error creating announcement"); return StatusCode(500, new { error = "Failed to create announcement" }); } } } }