package com.android.trisolarisserver.controller import com.android.trisolarisserver.db.repo.GuestRepo import com.android.trisolarisserver.models.booking.Guest import com.android.trisolarisserver.models.property.Property import com.android.trisolarisserver.models.room.RoomStay import com.android.trisolarisserver.repo.PropertyRepo import com.android.trisolarisserver.repo.RoomStayRepo import org.springframework.http.HttpStatus import org.springframework.web.server.ResponseStatusException import java.time.OffsetDateTime import java.time.ZoneId import java.util.UUID internal data class PropertyGuest( val property: Property, val guest: Guest ) internal fun requireProperty(propertyRepo: PropertyRepo, propertyId: UUID): Property { return propertyRepo.findById(propertyId).orElseThrow { ResponseStatusException(HttpStatus.NOT_FOUND, "Property not found") } } internal fun requirePropertyGuest( propertyRepo: PropertyRepo, guestRepo: GuestRepo, propertyId: UUID, guestId: UUID ): PropertyGuest { val property = requireProperty(propertyRepo, propertyId) val guest = guestRepo.findById(guestId).orElseThrow { ResponseStatusException(HttpStatus.NOT_FOUND, "Guest not found") } if (guest.property.id != property.id) { throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Guest not in property") } return PropertyGuest(property, guest) } internal fun requireRoomStayForProperty( roomStayRepo: RoomStayRepo, propertyId: UUID, roomStayId: UUID ): RoomStay { val stay = roomStayRepo.findById(roomStayId).orElseThrow { ResponseStatusException(HttpStatus.NOT_FOUND, "Room stay not found") } if (stay.property.id != propertyId) { throw ResponseStatusException(HttpStatus.NOT_FOUND, "Room stay not found for property") } return stay } internal fun requireOpenRoomStayForProperty( roomStayRepo: RoomStayRepo, propertyId: UUID, roomStayId: UUID, closedMessage: String ): RoomStay { val stay = requireRoomStayForProperty(roomStayRepo, propertyId, roomStayId) if (stay.toAt != null) { throw ResponseStatusException(HttpStatus.CONFLICT, closedMessage) } return stay } internal fun parseOffset(value: String?): OffsetDateTime? { if (value.isNullOrBlank()) return null return try { OffsetDateTime.parse(value.trim()) } catch (_: Exception) { throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid timestamp") } } internal fun nowForProperty(timezone: String?): OffsetDateTime { val zone = try { if (timezone.isNullOrBlank()) ZoneId.of("Asia/Kolkata") else ZoneId.of(timezone) } catch (_: Exception) { ZoneId.of("Asia/Kolkata") } return OffsetDateTime.now(zone) }