from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session, joinedload from typing import List from datetime import datetime from ..database import get_db from ..models import Court, CourtReservation from ..schemas import CourtCreate, CourtStatusUpdate, ReservationCreate, ReservationOut, CourtOut router = APIRouter(prefix="/api/courts", tags=["courts"]) @router.get("/", response_model=List[CourtOut]) def list_courts(db: Session = Depends(get_db)): courts = db.query(Court).options(joinedload(Court.reservations).joinedload(CourtReservation.player)).all() return courts @router.post("/", response_model=CourtOut) def create_court(data: CourtCreate, db: Session = Depends(get_db)): court = Court(**data.model_dump()) db.add(court) db.commit() db.refresh(court) return court @router.get("/{court_id}", response_model=CourtOut) def get_court(court_id: int, db: Session = Depends(get_db)): court = db.query(Court).options(joinedload(Court.reservations).joinedload(CourtReservation.player)).filter(Court.id == court_id).first() if not court: raise HTTPException(status_code=404, detail="Court not found") return court @router.patch("/{court_id}/status") def update_court_status(court_id: int, data: CourtStatusUpdate, db: Session = Depends(get_db)): court = db.query(Court).filter(Court.id == court_id).first() if not court: raise HTTPException(status_code=404, detail="Court not found") valid_statuses = ["available", "in_use", "reserved", "maintenance"] if data.status not in valid_statuses: raise HTTPException(status_code=400, detail=f"Status must be one of {valid_statuses}") court.status = data.status db.commit() return {"ok": True, "status": data.status} @router.get("/{court_id}/reservations", response_model=List[ReservationOut]) def list_reservations(court_id: int, db: Session = Depends(get_db)): return db.query(CourtReservation).filter(CourtReservation.court_id == court_id).order_by(CourtReservation.start_time).all() @router.post("/{court_id}/reservations", response_model=ReservationOut) def create_reservation(court_id: int, data: ReservationCreate, db: Session = Depends(get_db)): court = db.query(Court).filter(Court.id == court_id).first() if not court: raise HTTPException(status_code=404, detail="Court not found") reservation = CourtReservation(court_id=court_id, **data.model_dump()) db.add(reservation) # Update court status to reserved if it's currently available if court.status == "available": court.status = "reserved" db.commit() db.refresh(reservation) return reservation @router.delete("/reservations/{reservation_id}") def delete_reservation(reservation_id: int, db: Session = Depends(get_db)): reservation = db.query(CourtReservation).filter(CourtReservation.id == reservation_id).first() if not reservation: raise HTTPException(status_code=404, detail="Reservation not found") court = db.query(Court).filter(Court.id == reservation.court_id).first() db.delete(reservation) db.commit() # Check if court has any remaining reservations remaining = db.query(CourtReservation).filter(CourtReservation.court_id == reservation.court_id).count() if remaining == 0 and court and court.status == "reserved": court.status = "available" db.commit() return {"ok": True}