from typing import Any, List from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.api.dependencies.auth import get_current_active_user from app.db.repositories.message import message_repository from app.db.repositories.conversation import conversation_repository from app.db.session import get_db from app.models.user import User from app.schemas.message import Message, MessageCreate router = APIRouter(tags=["messages"]) @router.post("/conversations/{conversation_id}/messages", response_model=Message) def create_message( *, conversation_id: str, message_in: MessageCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), ) -> Any: """ Create new message in a conversation. """ # Check if conversation exists and user is a participant conversation = conversation_repository.get(db, id=conversation_id) if not conversation: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Conversation not found", ) # Check if user is a participant in this conversation if current_user not in conversation.participants: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not a participant of this conversation", ) # Add conversation_id to message if not already provided if not message_in.conversation_id: message_in.conversation_id = conversation_id message = message_repository.create_with_sender( db, obj_in=message_in, sender_id=current_user.id ) return message @router.get("/conversations/{conversation_id}/messages", response_model=List[Message]) def read_messages( conversation_id: str, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), ) -> Any: """ Retrieve messages from a conversation. """ # Check if conversation exists and user is a participant conversation = conversation_repository.get(db, id=conversation_id) if not conversation: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Conversation not found", ) # Check if user is a participant in this conversation if current_user not in conversation.participants: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not a participant of this conversation", ) messages = message_repository.get_conversation_messages( db, conversation_id=conversation_id, skip=skip, limit=limit ) return messages @router.put("/messages/{message_id}/read", response_model=Message) def mark_message_as_read( message_id: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), ) -> Any: """ Mark a message as read. """ message = message_repository.mark_as_read( db, message_id=message_id, user_id=current_user.id ) if not message: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Message not found or you're not the recipient", ) return message @router.get("/messages/unread/count") def get_unread_count( db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), ) -> Any: """ Get count of unread messages for the current user. """ count = message_repository.get_unread_count(db, user_id=current_user.id) return {"count": count}