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.conversation import conversation_repository from app.db.repositories.user import user_repository from app.db.session import get_db from app.models.user import User from app.schemas.conversation import Conversation, ConversationCreate, ConversationUpdate router = APIRouter(tags=["conversations"]) @router.post("/conversations", response_model=Conversation) def create_conversation( *, db: Session = Depends(get_db), conversation_in: ConversationCreate, current_user: User = Depends(get_current_active_user), ) -> Any: """ Create new conversation. """ # Check if direct conversation between these two users already exists if len(conversation_in.participant_ids) == 1 and not conversation_in.is_group: other_user_id = conversation_in.participant_ids[0] existing_conversation = conversation_repository.get_conversation_between_users( db, user_id_1=current_user.id, user_id_2=other_user_id ) if existing_conversation: return existing_conversation # Check if all participants exist for user_id in conversation_in.participant_ids: user = user_repository.get(db, id=user_id) if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"User with id {user_id} not found", ) conversation = conversation_repository.create_with_participants( db, obj_in=conversation_in, creator_id=current_user.id ) return conversation @router.get("/conversations", response_model=List[Conversation]) def read_conversations( skip: int = 0, limit: int = 100, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), ) -> Any: """ Retrieve conversations. """ conversations = conversation_repository.get_user_conversations( db, user_id=current_user.id, skip=skip, limit=limit ) return conversations @router.get("/conversations/{conversation_id}", response_model=Conversation) def read_conversation( conversation_id: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), ) -> Any: """ Get a specific conversation by id. """ 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", ) return conversation @router.put("/conversations/{conversation_id}", response_model=Conversation) def update_conversation( *, conversation_id: str, conversation_in: ConversationUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user), ) -> Any: """ Update a conversation. """ 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", ) conversation = conversation_repository.update( db, db_obj=conversation, obj_in=conversation_in ) return conversation