from typing import Any, List from fastapi import APIRouter, Depends, HTTPException, 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.message import Message, MessageCreate from app.crud import message, match as match_crud router = APIRouter() @router.post("/", response_model=Message) def create_message( *, db: Session = Depends(get_db), message_in: MessageCreate, current_user: User = Depends(get_current_active_user), ) -> Any: """ Create new message """ # Check if the match exists match_obj = match_crud.get(db, id=message_in.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 send messages 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 send messages in this match", ) # Only matched users can message each other if match_obj.status != MatchStatusEnum.accepted: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Can only send messages in accepted matches", ) # Determine the receiver based on the sender if current_user.id == match_obj.sender_id: receiver_id = match_obj.receiver_id else: receiver_id = match_obj.sender_id # Create message with sender and receiver information message_data = message_in.dict() message_data["sender_id"] = current_user.id message_data["receiver_id"] = receiver_id return message.create(db, obj_in=MessageCreate(**message_data)) @router.get("/match/{match_id}", response_model=List[Message]) def read_messages_by_match( *, db: Session = Depends(get_db), match_id: int, current_user: User = Depends(get_current_active_user), skip: int = 0, limit: int = 100, ) -> Any: """ Get messages for a specific match """ # Check if the match exists match_obj = match_crud.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 read messages 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 messages in this match", ) # Mark messages as read if match_obj.sender_id == current_user.id or match_obj.receiver_id == current_user.id: message.mark_as_read(db, user_id=current_user.id, match_id=match_id) # Get messages messages = message.get_by_match(db, match_id=match_id, skip=skip, limit=limit) return messages @router.get("/", response_model=List[Message]) def read_user_messages( *, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), skip: int = 0, limit: int = 100, ) -> Any: """ Get all messages for the current user """ messages = message.get_user_messages(db, user_id=current_user.id, skip=skip, limit=limit) return messages @router.put("/{message_id}/read", response_model=Message) def mark_message_read( *, db: Session = Depends(get_db), message_id: int, current_user: User = Depends(get_current_active_user), ) -> Any: """ Mark a message as read """ msg = message.get(db, id=message_id) if not msg: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Message not found", ) # Only the receiver can mark a message as read if msg.receiver_id != current_user.id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not allowed to mark this message as read", ) # Update the message updated_message = message.update(db, db_obj=msg, obj_in={"is_read": True}) return updated_message