from typing import Annotated from loguru import logger from fastapi import APIRouter, Depends, HTTPException, Request from dependency_injector.wiring import inject, Provide from app.dependencies.containers import Container from app.dto.request import ( DialogflowWebhookRequest, SeatQueryRequest, StopRequest, TicketRequest, TripQueryRequest, ) from app.dto.response import ( DialogServiceResult, DialogflowResponseBuilder, ) from app.services.trip_service import TripService router = APIRouter(prefix="/trip", tags=["Trip"]) @router.post("/option") @inject async def trips_option( request: Request, service: TripService = Depends(Provide[Container.trip_service]) ): body = await request.json() params = body.get("sessionInfo", {}).get("parameters", {}) try: data = TripQueryRequest(**params) except Exception as e: raise HTTPException(status_code=400, detail="Invalid location parameters") rs: DialogServiceResult = await service.get_trips_option(data) return ( DialogflowResponseBuilder() .add_text(rs.text) .add_choice_chips(options=rs.options, key="route") .set_parameters(rs.parameters) .build() ) @router.post("/confirm-info") @inject async def confirm( request: Request, service: TripService = Depends(Provide[Container.trip_service]) ): body = await request.json() body = DialogflowWebhookRequest(**body) parameters = body.get_parameters() try: data = TripQueryRequest(**parameters) except Exception as e: logger.error(f"Error parsing trip parameters {e}", exc_info=True) raise HTTPException(status_code=400, detail="Invalid trip query parameters") rs: DialogServiceResult = service.confirm_trip_search_input(data=data) return ( DialogflowResponseBuilder() .add_text(rs.text) .add_choice_chips(options=rs.options) .build() ) @router.post("/validate-trip-selection") @inject async def validate_trip_selection( request: Request, service: TripService = Depends(Provide[Container.trip_service]) ): body = await request.json() body = DialogflowWebhookRequest(**body) params = body.get_parameters() try: data = TripQueryRequest(**params) except Exception as e: raise HTTPException(status_code=400, detail="Invalid trip selection parameters") rs: DialogServiceResult = await service.validate_trip_selection( id_selected=data.id_selected, data=data ) return DialogflowResponseBuilder().set_parameters(rs.parameters).build() @router.post("/available-seat") @inject async def fetch_available_seat( request: Request, service: TripService = Depends(Provide[Container.trip_service]) ): body = await request.json() body = DialogflowWebhookRequest(**body) params = body.get_parameters() try: logger.info(f"Received parameters: {params}") data = SeatQueryRequest(**params) except Exception as e: logger.error(f"Error parsing trip parameters {e}", exc_info=True) raise HTTPException(status_code=400, detail="Invalid trip query parameters") rs: DialogServiceResult = await service.get_available_seat(data.trip_data) return ( DialogflowResponseBuilder() .add_text(rs.text) .add_choice_chips(options=rs.options, key="chair") .set_parameters(rs.parameters) .build() ) @router.post("/validate-seat-selection") @inject async def validate_seat_selection( request: Request, service: TripService = Depends(Provide[Container.trip_service]) ): body = await request.json() body = DialogflowWebhookRequest(**body) params = body.get_parameters() try: data = SeatQueryRequest(**params) except Exception as e: logger.error("Error parsing trip parameters", exc_info=True) raise HTTPException(status_code=400, detail="Invalid trip query parameters") rs: DialogServiceResult = await service.validate_seat_selection( selected=data.seat, data=data.trip_data ) return ( DialogflowResponseBuilder() .add_text(rs.text) .set_parameters(rs.parameters) .build() ) @router.post("/pick-up") @inject async def pick_up_stop( request: Request, service: TripService = Depends(Provide[Container.trip_service]) ): try: body = await request.json() body = DialogflowWebhookRequest(**body) params = body.get_parameters() data = StopRequest(**params) except Exception as e: logger.error(f"Error parsing trip parameters {e}", exc_info=True) raise HTTPException(status_code=400, detail="Invalid trip query parameters") rs: DialogServiceResult = await service.get_pick_up_points( route_id=data.trip_data.route_id, way_id=data.trip_data.way_id ) return ( DialogflowResponseBuilder() .add_text(rs.text) .add_choice_chips(options=rs.options, key="name") .set_parameters(rs.parameters) .build() ) @router.post("/pick-up/validate-selection") @inject async def validate_pick_up_selection( request: Request, service: TripService = Depends(Provide[Container.trip_service]) ): body = await request.json() body = DialogflowWebhookRequest(**body) params = body.get_parameters() try: data = StopRequest(**params) except Exception as e: logger.error("Error parsing trip parameters", exc_info=True) raise HTTPException(status_code=400, detail="Invalid trip query parameters") selected = body.get_text() rs: DialogServiceResult = await service.validate_stop_selection( id_selected=data.id_selected, data=data.trip_data, role="pick-up" ) return ( DialogflowResponseBuilder() .add_text(rs.text) .add_choice_chips(options=rs.options) .set_parameters(rs.parameters) .build() ) @router.post("/drop-off") @inject async def drop_off_stop( request: Request, service: TripService = Depends(Provide[Container.trip_service]) ): body = await request.json() body = DialogflowWebhookRequest(**body) params = body.get_parameters() try: data = StopRequest(**params) except Exception as e: logger.error("Error parsing trip parameters", exc_info=True) raise HTTPException(status_code=400, detail="Invalid trip query parameters") rs: DialogServiceResult = await service.get_drop_off_points( route_id=data.trip_data.route_id, way_id=data.trip_data.way_id ) logger.info(f"Drop-off points: {rs.options}") return ( DialogflowResponseBuilder() .add_text(rs.text) .add_choice_chips(options=rs.options, key="name") .set_parameters(rs.parameters) .build() ) @router.post("/drop-off/validate-selection") @inject async def validate_drop_off_selection( request: Request, service: TripService = Depends(Provide[Container.trip_service]) ): body = await request.json() body = DialogflowWebhookRequest(**body) params = body.get_parameters() try: data = StopRequest(**params) except Exception as e: logger.error("Error parsing trip parameters", exc_info=True) raise HTTPException(status_code=400, detail="Invalid trip query parameters") rs: DialogServiceResult = await service.validate_stop_selection( id_selected=data.id_selected, data=data.trip_data, role="drop-off" ) return ( DialogflowResponseBuilder() .add_text(rs.text) .add_choice_chips(options=rs.options) .set_parameters(rs.parameters) .build() ) @router.post("/ticket") @inject async def show_ticket( request: Request, service: TripService = Depends(Provide[Container.trip_service]) ): body = await request.json() body = DialogflowWebhookRequest(**body) params = body.get_parameters() try: data = TicketRequest(**params) except Exception as e: logger.error("Error parsing trip parameters", exc_info=True) raise HTTPException(status_code=400, detail="Invalid trip query parameters") rs: DialogServiceResult = await service.make_ticket_summary(data) return ( DialogflowResponseBuilder() .add_text(rs.text) .set_parameters(rs.parameters) .build() )