from fastapi import APIRouter, Depends, status from sqlalchemy.ext.asyncio import AsyncSession from app.auth.service import get_current_user from app.database.session import get_db from app.messages.schemas import MessageCreateRequest, MessageForwardRequest, MessageRead, MessageStatusUpdateRequest, MessageUpdateRequest from app.messages.service import ( create_chat_message, delete_message, delete_message_for_all, forward_message, get_messages, search_messages, update_message, ) from app.realtime.schemas import MessageStatusPayload from app.realtime.service import realtime_gateway from app.users.models import User router = APIRouter(prefix="/messages", tags=["messages"]) @router.post("", response_model=MessageRead, status_code=status.HTTP_201_CREATED) async def create_message( payload: MessageCreateRequest, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ) -> MessageRead: message = await create_chat_message(db, sender_id=current_user.id, payload=payload) await realtime_gateway.publish_message_created( message=message, sender_id=current_user.id, client_message_id=payload.client_message_id, ) return message @router.get("/search", response_model=list[MessageRead]) async def search_messages_endpoint( query: str, chat_id: int | None = None, limit: int = 50, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ) -> list[MessageRead]: return await search_messages(db, user_id=current_user.id, query=query, chat_id=chat_id, limit=limit) @router.get("/{chat_id}", response_model=list[MessageRead]) async def list_messages( chat_id: int, limit: int = 50, before_id: int | None = None, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ) -> list[MessageRead]: return await get_messages(db, chat_id=chat_id, user_id=current_user.id, limit=limit, before_id=before_id) @router.put("/{message_id}", response_model=MessageRead) async def edit_message( message_id: int, payload: MessageUpdateRequest, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ) -> MessageRead: return await update_message(db, message_id=message_id, user_id=current_user.id, payload=payload) @router.delete("/{message_id}", status_code=status.HTTP_204_NO_CONTENT) async def remove_message( message_id: int, for_all: bool = False, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ) -> None: if for_all: await delete_message_for_all(db, message_id=message_id, user_id=current_user.id) return await delete_message(db, message_id=message_id, user_id=current_user.id) @router.post("/status") async def update_status( payload: MessageStatusUpdateRequest, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ) -> dict[str, int]: return await realtime_gateway.handle_message_status( db, user_id=current_user.id, payload=MessageStatusPayload(chat_id=payload.chat_id, message_id=payload.message_id), event=payload.status, ) @router.post("/{message_id}/forward", response_model=MessageRead, status_code=status.HTTP_201_CREATED) async def forward_message_endpoint( message_id: int, payload: MessageForwardRequest, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ) -> MessageRead: message = await forward_message(db, source_message_id=message_id, sender_id=current_user.id, payload=payload) await realtime_gateway.publish_message_created(message=message, sender_id=current_user.id) return message