using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using YaleAccess.Models; using YaleAccess.Models.Options; using YaleAccess.Services; using YaleAccess.Services.Interfaces; namespace YaleAccess.Controllers { [ApiController] [Route("api/[controller]")] [EnableCors] [Authorize] public class YaleController( ILogger logger, IYaleAccessor yaleAccessor, IOptions codeOptions, SMSService smsService ) : ControllerBase { [HttpGet("codes")] public async Task GetUserCodes() { try { // Get the home code first YaleUserCode homeCode = await yaleAccessor.GetCodeInformationAsync(codeOptions.Value.Home); homeCode.IsHome = true; // Get the guest codes List guestCodes = new(); foreach (int code in Enumerable.Range(codeOptions.Value.GuestCodeRangeStart, codeOptions.Value.GuestCodeRangeCount)) { guestCodes.Add(await yaleAccessor.GetCodeInformationAsync(code)); } // Add the home code to the list guestCodes.Add(homeCode); // Return the codes return Ok(new ApiResponse(guestCodes)); } catch(Exception ex) { logger.LogError(ex, "An error occurred retriving the codes."); return BadRequest(new ApiResponse("An error occurred retriving the codes.")); } } [HttpPost("code/{id}")] public async Task SetUserCode([FromRoute] int id, [FromBody] string newCode) { try { // First validate the user code string validCode = YaleAccessor.ValidateCode(newCode); if (validCode != string.Empty) { return BadRequest(new ApiResponse(validCode)); } // Set the new code bool result = await yaleAccessor.SetUserCode(id, newCode); // Return the result if (result) { logger.LogInformation("Updated code for user {id} to {code}", id, newCode); return Ok(new ApiResponse(true)); } else { logger.LogInformation("Failed to update code for user {id} to {code}", id, newCode); return BadRequest(new ApiResponse("An error occurred setting the code.")); } } catch (Exception ex) { logger.LogError(ex, "An error occurred setting the code."); return BadRequest(new ApiResponse("An error occurred setting the code.")); } } [HttpPost("code/{id}/status")] public async Task SetUserCodeStatusAsAvailable([FromRoute] int id) { try { // First validate the user code string validCode = YaleAccessor.ValidateClearCode(id, codeOptions.Value.Home); if (validCode != string.Empty) { return BadRequest(new ApiResponse(validCode)); } // Set the available status bool result = await yaleAccessor.SetCodeAsAvailable(id); // Return the result if (result) { logger.LogInformation("Updated code status for user {id} to available", id); return Ok(new ApiResponse(true)); } else { logger.LogInformation("Failed to update code status for user {id} to available", id); return BadRequest(new ApiResponse("An error occurred setting the code status.")); } } catch (Exception ex) { logger.LogError(ex, "An error occurred setting the code status."); return BadRequest(new ApiResponse("An error occurred setting the code status.")); } } [HttpPost("code/{id}/send")] public async Task SendUserCode([FromRoute] int id, [FromBody] string phoneNumber) { try { // Get the user code YaleUserCode userCode = await yaleAccessor.GetCodeInformationAsync(id); // Send the code via SMS to the phone number await smsService.SendCodeViaSMSAsync(userCode.Code, phoneNumber); // Return success return Ok(new ApiResponse(true)); } catch (Exception ex) { logger.LogError(ex, "An error occurred sending the code."); return BadRequest(new ApiResponse("An error occurred sending the code.")); } } } }