from fastapi import APIRouter, Depends, Query, HTTPException, UploadFile, File, Form from sqlmodel import Session, select from typing import Optional, List import os import shutil from uuid import uuid4, UUID from app.core.database import get_session from app.models.shuttle import Shuttle from app.api.deps import get_current_admin router = APIRouter(prefix="/api/shuttles", tags=["shuttles"]) UPLOAD_DIR = "uploads" @router.get("", response_model=List[Shuttle]) async def get_shuttles( origin: Optional[str] = Query(None), destination: Optional[str] = Query(None), company_name: Optional[str] = Query(None), trip_type: Optional[str] = Query(None), is_active: bool = Query(True), session: Session = Depends(get_session) ): """Get all shuttles with optional filters.""" statement = select(Shuttle).where(Shuttle.is_active == is_active) if origin: statement = statement.where(Shuttle.origin.contains(origin)) if destination: statement = statement.where(Shuttle.destination.contains(destination)) if company_name: statement = statement.where(Shuttle.company_name.contains(company_name)) if trip_type: statement = statement.where(Shuttle.trip_type == trip_type) shuttles = session.exec(statement).all() return shuttles @router.post("", response_model=Shuttle) async def create_shuttle( route_name: str = Form(...), origin: str = Form(...), destination: str = Form(...), vehicle_type: str = Form(...), company_name: Optional[str] = Form(None), trip_type: str = Form("one_way"), price_per_person: Optional[float] = Form(None), price_private_trip: Optional[float] = Form(None), estimated_duration: str = Form(...), contact_whatsapp: str = Form(...), phone_number: Optional[str] = Form(None), english_speaking: bool = Form(False), description: Optional[str] = Form(None), departure_times: Optional[str] = Form(None), is_active: bool = Form(True), image: Optional[UploadFile] = File(None), session: Session = Depends(get_session), _: bool = Depends(get_current_admin) ): """Create a new shuttle trip (Admin only).""" image_url = None if image: ext = os.path.splitext(image.filename)[1] filename = f"{uuid4()}{ext}" path = os.path.join(UPLOAD_DIR, "vehicles", filename) with open(path, "wb") as buffer: shutil.copyfileobj(image.file, buffer) image_url = f"/uploads/vehicles/{filename}" shuttle = Shuttle( route_name=route_name, origin=origin, destination=destination, vehicle_type=vehicle_type, company_name=company_name, trip_type=trip_type, price_per_person=price_per_person, price_private_trip=price_private_trip, estimated_duration=estimated_duration, contact_whatsapp=contact_whatsapp, phone_number=phone_number, english_speaking=english_speaking, description=description, departure_times=departure_times, image_url=image_url, is_active=is_active ) session.add(shuttle) session.commit() session.refresh(shuttle) return shuttle @router.put("/{shuttle_id}", response_model=Shuttle) async def update_shuttle( shuttle_id: UUID, route_name: str = Form(...), origin: str = Form(...), destination: str = Form(...), vehicle_type: str = Form(...), company_name: Optional[str] = Form(None), trip_type: str = Form("one_way"), price_per_person: Optional[float] = Form(None), price_private_trip: Optional[float] = Form(None), estimated_duration: str = Form(...), contact_whatsapp: str = Form(...), phone_number: Optional[str] = Form(None), english_speaking: bool = Form(False), description: Optional[str] = Form(None), departure_times: Optional[str] = Form(None), is_active: bool = Form(True), image: Optional[UploadFile] = File(None), session: Session = Depends(get_session), _: bool = Depends(get_current_admin) ): """Update a shuttle trip (Admin only).""" db_shuttle = session.get(Shuttle, shuttle_id) if not db_shuttle: raise HTTPException(status_code=404, detail="Shuttle not found") db_shuttle.route_name = route_name db_shuttle.origin = origin db_shuttle.destination = destination db_shuttle.vehicle_type = vehicle_type db_shuttle.company_name = company_name db_shuttle.trip_type = trip_type db_shuttle.price_per_person = price_per_person db_shuttle.price_private_trip = price_private_trip db_shuttle.estimated_duration = estimated_duration db_shuttle.contact_whatsapp = contact_whatsapp db_shuttle.phone_number = phone_number db_shuttle.english_speaking = english_speaking db_shuttle.description = description db_shuttle.departure_times = departure_times db_shuttle.is_active = is_active if image: ext = os.path.splitext(image.filename)[1] filename = f"{uuid4()}{ext}" path = os.path.join(UPLOAD_DIR, "vehicles", filename) with open(path, "wb") as buffer: shutil.copyfileobj(image.file, buffer) db_shuttle.image_url = f"/uploads/vehicles/{filename}" session.add(db_shuttle) session.commit() session.refresh(db_shuttle) return db_shuttle @router.delete("/{shuttle_id}") async def delete_shuttle( shuttle_id: UUID, session: Session = Depends(get_session), _: bool = Depends(get_current_admin) ): """Delete a shuttle trip (Admin only).""" db_shuttle = session.get(Shuttle, shuttle_id) if not db_shuttle: raise HTTPException(status_code=404, detail="Shuttle not found") session.delete(db_shuttle) session.commit() return {"ok": True}