import uuid from fastapi import APIRouter, Depends, HTTPException, status from sqlmodel import Session, select from app.database import get_session from app.models.user import User from app.models.friendship import Friendship from app.schemas.user import UserRead from app.auth.dependencies import get_current_user router = APIRouter(prefix="/friends", tags=["friends"]) @router.post("", status_code=status.HTTP_201_CREATED) def add_friend( username: str, current_user: User = Depends(get_current_user), session: Session = Depends(get_session), ): """Add a friend by username. Creates bidirectional friendship.""" friend = session.exec(select(User).where(User.username == username)).first() if not friend: raise HTTPException(status_code=404, detail="User not found") if friend.id == current_user.id: raise HTTPException(status_code=400, detail="Cannot add yourself") # Check if already friends existing = session.exec( select(Friendship).where( Friendship.user_id == current_user.id, Friendship.friend_id == friend.id, ) ).first() if existing: raise HTTPException(status_code=400, detail="Already friends") # Bidirectional session.add(Friendship(user_id=current_user.id, friend_id=friend.id)) session.add(Friendship(user_id=friend.id, friend_id=current_user.id)) session.commit() return {"detail": f"Now friends with {friend.username}"} @router.get("", response_model=list[UserRead]) def list_friends( current_user: User = Depends(get_current_user), session: Session = Depends(get_session), ): """List all friends of the current user.""" friend_ids = session.exec( select(Friendship.friend_id).where(Friendship.user_id == current_user.id) ).all() if not friend_ids: return [] friends = session.exec( select(User).where(User.id.in_(friend_ids)) # type: ignore[union-attr] ).all() return friends @router.delete("/{friend_id}", status_code=status.HTTP_204_NO_CONTENT) def remove_friend( friend_id: uuid.UUID, current_user: User = Depends(get_current_user), session: Session = Depends(get_session), ): """Remove a friend (bidirectional).""" f1 = session.exec( select(Friendship).where( Friendship.user_id == current_user.id, Friendship.friend_id == friend_id, ) ).first() f2 = session.exec( select(Friendship).where( Friendship.user_id == friend_id, Friendship.friend_id == current_user.id, ) ).first() if not f1: raise HTTPException(status_code=404, detail="Friendship not found") session.delete(f1) if f2: session.delete(f2) session.commit()