using BookingMicroservice.Exceptions; using BookingMicroservice.Models; using BookingMicroservice.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using System.Security.Claims; using Stripe.Checkout; using Stripe; namespace BookingMicroservice.Controllers { [ApiController] [Route("api/[Controller]")] public class BookingController : ControllerBase { private readonly IReservationComplianceService reservationComplianceService; private readonly IBookingService bookingService; private readonly IStripeService stripeService; private readonly IConfiguration configuration; public BookingController(IReservationComplianceService reservationComplianceService, IBookingService bookingService, IStripeService stripeService, IConfiguration configuration) { this.reservationComplianceService = reservationComplianceService; this.bookingService = bookingService; this.stripeService = stripeService; this.configuration = configuration; } [Authorize] [HttpGet()] public IActionResult GetBookings(int? flightId = null, int? userId = null, BookingClass? bookingClass = null) { List<Booking> bookings = bookingService.GetBookings(flightId, userId, bookingClass); if (bookings == null) return BadRequest("Unable to get bookings"); return Ok(bookings); } [Authorize] [HttpGet("{id}")] public IActionResult GetBooking([FromRoute] int id) { Booking? booking = bookingService.GetBooking(id); if(booking == null) return NotFound($"Could not find booking with id: {id}"); return Ok(booking); } [Authorize] [HttpPost()] public async Task<IActionResult> MakeBooking([FromBody] BookingCreation bookingCreationModel) { string? userIdValue = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; if (!int.TryParse(userIdValue, out int userId)) return BadRequest("Unable to get User Id from Token"); try { bool isPaymentSuccessful = await stripeService.VerifyPaymentIntent(bookingCreationModel.PaymentIntentId); if (!isPaymentSuccessful) { return BadRequest("Payment verification failed."); } Booking? booking = await reservationComplianceService.TryCreateBookingAsync(bookingCreationModel.FlightId, userId, bookingCreationModel.BookingClass, bookingCreationModel.SeatId); if (booking == null) return BadRequest("Error in creating booking"); return Ok(booking); } catch (InvalidOperationException exception) { return BadRequest(exception.Message); } catch (BookingException exception) { return BadRequest(exception.Message); } } [Authorize] [HttpPut("{bookingId}")] public async Task<IActionResult> UpdatedBookingSeat([FromRoute] int bookingId, [FromBody] BookingUpdate bookingUpdateModel) { try { await reservationComplianceService.TryBookSeatAsync(bookingId, bookingUpdateModel.SeatId); return Ok(new { BookedSeat = true, Message = "Seat booked successfully." }); } catch (InvalidOperationException exception) { return BadRequest(exception.Message); } catch (BookingException exception) { return Ok(new { BookedSeat = false, Message = exception.Message }); } } [Authorize] [HttpGet("upcoming")] public async Task<IActionResult> GetUpcomingFlightBookings() { string? userIdValue = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; if (!int.TryParse(userIdValue, out int userId)) return BadRequest("Unable to get User Id from Token"); try { IEnumerable<FlightBookingInfo> flights = await reservationComplianceService.TryGetUpcomingFlightsAsync(userId); return Ok(flights); } catch(InvalidOperationException exception) { return BadRequest(exception.Message); } } [Authorize] [HttpGet("history")] public async Task<IActionResult> GetPreviousFlightBookings() { string? userIdValue = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; if (!int.TryParse(userIdValue, out int userId)) return BadRequest("Unable to get User Id from Token"); try { IEnumerable<FlightBookingInfo> flights = await reservationComplianceService.TryGetPreviousFlightsAsync(userId); return Ok(flights); } catch (InvalidOperationException exception) { return BadRequest(exception.Message); } } [HttpPost("create-payment-intent")] public async Task<IActionResult> CreatePaymentIntent([FromBody] PaymentIntentCreateRequest request) { var paymentIntentService = new PaymentIntentService(); var paymentIntent = paymentIntentService.Create(new PaymentIntentCreateOptions { Amount = stripeService.CalculateOrderAmount(request.Items), Currency = "eur", AutomaticPaymentMethods = new PaymentIntentAutomaticPaymentMethodsOptions { Enabled = true, }, }); return new JsonResult(new { clientSecret = paymentIntent.ClientSecret }); } } }