using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using RacePlannerApi.Data; using RacePlannerApi.DTOs; using RacePlannerApi.Models; namespace RacePlannerApi.Controllers; [ApiController] [Route("api/[controller]")] [Authorize] public class DashboardController : ControllerBase { private readonly RacePlannerDbContext _context; public DashboardController(RacePlannerDbContext context) { _context = context; } [HttpGet("organizer")] [Authorize(Roles = "Organizer")] public async Task> GetOrganizerDashboard() { var userId = GetCurrentUserId(); if (userId == null) { return Unauthorized(); } var events = await _context.Events .Include(e => e.Registrations) .ThenInclude(r => r.Payments) .Where(e => e.OrganizerId == userId.Value) .ToListAsync(); var totalEvents = events.Count; var publishedEvents = events.Count(e => e.Status == EventStatus.Published); var draftEvents = events.Count(e => e.Status == EventStatus.Draft); var allRegistrations = events.SelectMany(e => e.Registrations).ToList(); var totalRegistrations = allRegistrations.Count; var pendingRegistrations = allRegistrations.Count(r => r.Status == RegistrationStatus.Pending); var confirmedRegistrations = allRegistrations.Count(r => r.Status == RegistrationStatus.Confirmed); var cancelledRegistrations = allRegistrations.Count(r => r.Status == RegistrationStatus.Cancelled); var totalRevenue = allRegistrations .SelectMany(r => r.Payments) .Sum(p => p.Amount); var upcomingEvents = events .Where(e => e.EventDate >= DateTime.UtcNow && e.EventDate <= DateTime.UtcNow.AddDays(30)) .OrderBy(e => e.EventDate) .Take(5) .Select(e => new EventSummaryDto { Id = e.Id, Name = e.Name, EventDate = e.EventDate, Location = e.Location, RegistrationCount = e.Registrations.Count(r => r.Status != RegistrationStatus.Cancelled), MaxParticipants = e.MaxParticipants }) .ToList(); var eventsNearCapacity = events .Where(e => e.MaxParticipants.HasValue && e.Status == EventStatus.Published) .Select(e => new EventCapacityDto { Id = e.Id, Name = e.Name, EventDate = e.EventDate, RegistrationCount = e.Registrations.Count(r => r.Status != RegistrationStatus.Cancelled), MaxParticipants = e.MaxParticipants }) .Where(e => e.CapacityPercentage >= 80) .OrderByDescending(e => e.CapacityPercentage) .Take(5) .ToList(); var dashboard = new OrganizerDashboardDto { TotalEvents = totalEvents, PublishedEvents = publishedEvents, DraftEvents = draftEvents, TotalRegistrations = totalRegistrations, PendingRegistrations = pendingRegistrations, ConfirmedRegistrations = confirmedRegistrations, CancelledRegistrations = cancelledRegistrations, TotalRevenue = totalRevenue, UpcomingEvents = upcomingEvents, EventsNearCapacity = eventsNearCapacity }; return Ok(dashboard); } [HttpGet("participant")] public async Task> GetParticipantDashboard() { var userId = GetCurrentUserId(); if (userId == null) { return Unauthorized(); } var registrations = await _context.Registrations .Include(r => r.Event) .Where(r => r.ParticipantId == userId.Value) .ToListAsync(); var totalRegistrations = registrations.Count; var upcomingEvents = registrations.Count(r => r.Event.EventDate >= DateTime.UtcNow && r.Status != RegistrationStatus.Cancelled); var completedEvents = registrations.Count(r => r.Event.EventDate < DateTime.UtcNow && r.Status == RegistrationStatus.Completed); var cancelledRegistrations = registrations.Count(r => r.Status == RegistrationStatus.Cancelled); var registrationSummaries = registrations .OrderByDescending(r => r.Event.EventDate) .Take(10) .Select(r => new RegistrationSummaryDto { Id = r.Id, EventId = r.EventId, EventName = r.Event.Name, EventDate = r.Event.EventDate, Status = r.Status.ToString(), RegisteredAt = r.CreatedAt }) .ToList(); var upcomingEventList = registrations .Where(r => r.Event.EventDate >= DateTime.UtcNow && r.Status != RegistrationStatus.Cancelled) .OrderBy(r => r.Event.EventDate) .Take(5) .Select(r => new UpcomingEventDto { Id = r.EventId, Name = r.Event.Name, EventDate = r.Event.EventDate, Location = r.Event.Location }) .ToList(); var dashboard = new ParticipantDashboardDto { TotalRegistrations = totalRegistrations, UpcomingEvents = upcomingEvents, CompletedEvents = completedEvents, CancelledRegistrations = cancelledRegistrations, MyRegistrations = registrationSummaries, UpcomingEventList = upcomingEventList }; return Ok(dashboard); } private Guid? GetCurrentUserId() { var userIdClaim = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value; if (Guid.TryParse(userIdClaim, out var userId)) { return userId; } return null; } }