using Fitness_core_BE.DTOs.Facility; using Fitness_core_BE.Helpers; using Fitness_core_BE.Interfaces.Services; using Fitness_core_BE.Models.IOs; using Microsoft.AspNetCore.Mvc; using static Fitness_core_BE.Helpers.JwtMiddleware; using static Fitness_core_BE.Helpers.ApiResponseHelper; namespace Fitness_core_BE.Controllers { // Staff/owner-facing facility + facility-session management. Gated on the "bookings" nav // permission (NavItem seeded in CentralDbContext.OnModelCreating). [ApiController] [Route("api/client/facilities")] public class FacilityController : ControllerBase { private readonly IFacilityService _facilityService; public FacilityController(IFacilityService facilityService) { _facilityService = facilityService; } [CustomMiddleware] [TenantResolution] [RequiresPermission("bookings")] [HttpGet("")] public async Task>> GetAllFacilities([FromQuery] bool includeInactive = false) => Response(await _facilityService.GetAllFacilities(new { includeInactive }, HttpContext)); [CustomMiddleware] [TenantResolution] [RequiresPermission("bookings")] [HttpPost("")] public async Task>> CreateFacility([FromBody] CreateFacilityRequest request) => Response(await _facilityService.CreateFacility(new { name = request.Name, facilityType = request.FacilityType, description = request.Description, defaultCapacity = request.DefaultCapacity }, HttpContext)); [CustomMiddleware] [TenantResolution] [RequiresPermission("bookings")] [HttpPut("{id:guid}")] public async Task>> UpdateFacility(Guid id, [FromBody] UpdateFacilityRequest request) { var payload = new Dictionary { ["facilityId"] = id }; if (request.Name != null) payload["name"] = request.Name; if (request.FacilityType != null) payload["facilityType"] = request.FacilityType; if (request.Description != null) payload["description"] = request.Description; if (request.DefaultCapacity.HasValue) payload["defaultCapacity"] = request.DefaultCapacity.Value; if (request.IsActive.HasValue) payload["isActive"] = request.IsActive.Value; return Response(await _facilityService.UpdateFacility(payload, HttpContext)); } [CustomMiddleware] [TenantResolution] [RequiresPermission("bookings")] [HttpPatch("{id:guid}/status")] public async Task>> SetFacilityStatus(Guid id, [FromBody] SetFacilityStatusRequest request) => Response(await _facilityService.SetFacilityStatus(new { facilityId = id, isActive = request.IsActive }, HttpContext)); [CustomMiddleware] [TenantResolution] [RequiresPermission("bookings")] [HttpPost("sessions")] public async Task>> CreateFacilitySession([FromBody] CreateFacilitySessionRequest request) => Response(await _facilityService.CreateFacilitySession(new { facilityId = request.FacilityId, startTime = request.StartTime.ToString("o"), endTime = request.EndTime.ToString("o"), capacity = request.Capacity }, HttpContext)); [CustomMiddleware] [TenantResolution] [RequiresPermission("bookings")] [HttpGet("sessions")] public async Task>> GetSessions( [FromQuery] Guid? facilityId, [FromQuery] DateTime? fromDate, [FromQuery] DateTime? toDate) => Response(await _facilityService.GetSessions(new { facilityId, fromDate = fromDate?.ToString("o"), toDate = toDate?.ToString("o") }, HttpContext)); [CustomMiddleware] [TenantResolution] [RequiresPermission("bookings")] [HttpDelete("sessions/{id:guid}")] public async Task>> CancelFacilitySession(Guid id) => Response(await _facilityService.CancelFacilitySession(new { facilitySessionId = id }, HttpContext)); } }