from typing import Any, List, Optional from fastapi import APIRouter, Depends, HTTPException, Query, status from sqlalchemy.orm import Session from app.api.deps import get_current_active_user from app.db.session import get_db from app.models.user import User from app.models.match import MatchStatusEnum from app.schemas.match import Match, MatchCreate, MatchUpdate from app.crud import match, user as user_crud router = APIRouter() @router.post("/", response_model=Match) def create_match( *, db: Session = Depends(get_db), match_in: MatchCreate, current_user: User = Depends(get_current_active_user), ) -> Any: """ Create new match request """ # Check if the receiver exists receiver = user_crud.get(db, id=match_in.receiver_id) if not receiver: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Receiver not found", ) # Check if receiver is the same as sender (self-match) if current_user.id == match_in.receiver_id: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Cannot match with yourself", ) # Check if match already exists existing_match = match.get_by_users( db, user1_id=current_user.id, user2_id=match_in.receiver_id ) if existing_match: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Match already exists", ) # Create match with current user as sender match_data = match_in.dict() match_data["sender_id"] = current_user.id match_data["status"] = MatchStatusEnum.pending return match.create(db, obj_in=MatchCreate(**match_data)) @router.put("/{match_id}", response_model=Match) def update_match( *, db: Session = Depends(get_db), match_id: int, match_in: MatchUpdate, current_user: User = Depends(get_current_active_user), ) -> Any: """ Update match status (accept/reject) """ match_obj = match.get(db, id=match_id) if not match_obj: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Match not found", ) # Only the receiver can update the match status if match_obj.receiver_id != current_user.id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not allowed to update this match", ) # Only pending matches can be updated if match_obj.status != MatchStatusEnum.pending: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Match is already {match_obj.status}", ) updated_match = match.update(db, db_obj=match_obj, obj_in=match_in) return updated_match @router.get("/", response_model=List[Match]) def read_matches( *, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), status: Optional[MatchStatusEnum] = Query(None, description="Filter by status"), skip: int = 0, limit: int = 100, ) -> Any: """ Retrieve matches for current user """ matches = match.get_user_matches( db, user_id=current_user.id, status=status, skip=skip, limit=limit ) return matches @router.get("/{match_id}", response_model=Match) def read_match( *, db: Session = Depends(get_db), match_id: int, current_user: User = Depends(get_current_active_user), ) -> Any: """ Get match by ID """ match_obj = match.get(db, id=match_id) if not match_obj: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Match not found", ) # Only users involved in the match can see it if match_obj.sender_id != current_user.id and match_obj.receiver_id != current_user.id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not allowed to access this match", ) return match_obj