using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using OnProfNext.Server.Data; using OnProfNext.Shared.Models; using OnProfNext.Shared.Models.DTOs; using System.Text.Json; namespace OnProfNext.Server.Controllers { [ApiController] [Route("api/[controller]")] [Authorize] public class BookingsController : ControllerBase { private readonly AppDbContext _context; public BookingsController(AppDbContext context) { _context = context; } private int GetCurrentUserId() { var userIdClaim = User.FindFirst("UserId")?.Value; if (string.IsNullOrEmpty(userIdClaim)) throw new UnauthorizedAccessException("Kein User-Claim im Token gefunden."); return int.Parse(userIdClaim); } [HttpGet("mine")] public async Task>> GetMyBookings() { var userId = GetCurrentUserId(); var bookings = await _context.Bookings .Include(b => b.Order) .Where(b => b.UserId == userId) .OrderByDescending(b => b.Date) .Select(b => new BookingDto { Id = b.Id, OrderId = b.OrderId, OrderTitle = b.Order != null ? b.Order.Titel : "", UserId = b.UserId, Date = b.Date, Hours = b.Hours, Description = b.Description, MandantId = b.MandantId, IsPending = false }) .ToListAsync(); Console.WriteLine($"Returning bookings: {JsonSerializer.Serialize(bookings, new JsonSerializerOptions { WriteIndented = true })}"); return Ok(bookings); } [HttpGet("byproject/{projectId}")] public async Task>> GetBookingsByProject(int projectId) { var bookings = await _context.Bookings .Include(b => b.Order) .ThenInclude(o => o.Project) .Include(b => b.User) .Where(b => b.Order!.ProjectId == projectId) .Select(b => new BookingDto { Id = b.Id, OrderId = b.OrderId, OrderTitle = b.Order!.Titel, UserId = b.UserId, Username = $"{b.User!.FirstName} {b.User.LastName}", Date = b.Date, Hours = b.Hours, Description = b.Description, MandantId = b.MandantId, IsPending = false }) .ToListAsync(); Console.WriteLine($"Returning bookings for project {projectId}: {JsonSerializer.Serialize(bookings, new JsonSerializerOptions { WriteIndented = true })}"); return Ok(bookings); } [HttpPost] public async Task> CreateBooking([FromBody] BookingCreateDto dto) { var userId = GetCurrentUserId(); // Logge die rohe HTTP-Payload var rawRequest = await new StreamReader(Request.BodyReader.AsStream()).ReadToEndAsync(); Console.WriteLine($"Raw HTTP request body: {rawRequest}"); Console.WriteLine($"Received booking DTO: {JsonSerializer.Serialize(dto, new JsonSerializerOptions { WriteIndented = true })}"); Console.WriteLine($"Received booking: Date={dto.Date.ToString("dd.MM.yyyy HH:mm:ss")} (Kind: {dto.Date.Kind})"); var booking = new Booking { OrderId = dto.OrderId, UserId = userId, Date = dto.Date, Hours = dto.Hours, Description = dto.Description, MandantId = dto.MandantId, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; _context.Bookings.Add(booking); await _context.SaveChangesAsync(); var createdDto = new BookingDto { Id = booking.Id, OrderId = booking.OrderId, UserId = booking.UserId, Date = booking.Date, Hours = booking.Hours, Description = booking.Description, MandantId = booking.MandantId, IsPending = false }; Console.WriteLine($"Created booking: ID={booking.Id}, Date={booking.Date.ToString("dd.MM.yyyy HH:mm:ss")} (Kind: {booking.Date.Kind})"); return CreatedAtAction(nameof(GetMyBookings), new { id = booking.Id }, createdDto); } [HttpPut("{id}")] public async Task UpdateBooking(int id, BookingCreateDto dto) { var userId = GetCurrentUserId(); Console.WriteLine($"Updating booking ID={id}: Date={dto.Date.ToString("dd.MM.yyyy HH:mm:ss")} (Kind: {dto.Date.Kind})"); var booking = await _context.Bookings.FirstOrDefaultAsync(b => b.Id == id && b.UserId == userId); if (booking == null) return NotFound(); booking.OrderId = dto.OrderId; booking.Date = dto.Date; booking.Hours = dto.Hours; booking.Description = dto.Description; booking.UpdatedAt = DateTime.UtcNow; await _context.SaveChangesAsync(); Console.WriteLine($"Updated booking ID={id}: Date={booking.Date.ToString("dd.MM.yyyy HH:mm:ss")} (Kind: {booking.Date.Kind})"); return NoContent(); } [HttpDelete("{id}")] public async Task DeleteBooking(int id) { var userId = GetCurrentUserId(); var booking = await _context.Bookings.FirstOrDefaultAsync(b => b.Id == id && b.UserId == userId); if (booking == null) return NotFound(); Console.WriteLine($"Deleting booking ID={id}"); _context.Bookings.Remove(booking); await _context.SaveChangesAsync(); Console.WriteLine($"Deleted booking ID={id}"); return NoContent(); } } }