from core.errors.errors import not_a_member_of_chat from core.models.message.db import MPProfile, MPMessage, MPChat from core.models.message.requests import SendMessageRequest, ListMessagesRequest from core.models.message.responses import MessageDetailResponse, ProfileResponse, ChatResponse from core.storage import message_storage, chat_storage from core.ws.handlers import connection_manager class Service: async def build_message_response(self, msg: MPMessage) -> MessageDetailResponse: """ Build a message response """ return MessageDetailResponse( id=msg.id, sender=ProfileResponse(id=msg.sender.id, external_id=msg.sender.external_id, created_at=msg.sender.created_at, modified_at=msg.sender.modified_at), content=msg.content, chat=ChatResponse(id=msg.chat.id, name=msg.chat.name, admin=ProfileResponse(id=msg.chat.admin.id, external_id=msg.chat.admin.external_id, created_at=msg.chat.admin.created_at, modified_at=msg.chat.admin.modified_at), users=None, created_at=msg.chat.created_at, modified_at=msg.chat.modified_at), created_at=msg.created_at, modified_at=msg.modified_at ) async def notify_users_in_chat(self, chat: MPChat, message: MPMessage): """ Notify all users in chat """ for user in chat.users: await connection_manager.send_personal_message_by_user_id((await self.build_message_response(message)).model_dump_json(), user.id) async def send_message(self, user: MPProfile, message: SendMessageRequest) -> MessageDetailResponse: """ Send message to chat """ # Check chat exists chat = await chat_storage.get_chat(message.chat_id) # Check user is in chat if user.id not in [x.id for x in chat.users]: not_a_member_of_chat() # Add message to Database msg = await message_storage.insert_message(user.id, message.chat_id, message.content) await self.notify_users_in_chat(chat, msg) return await self.build_message_response(msg) async def list_messages(self, user: MPProfile, query: ListMessagesRequest): """ List messages in chat """ # Check chat exists chat = await chat_storage.get_chat(query.chat_id) # Check user is in chat if user.id not in [x.id for x in chat.users]: not_a_member_of_chat() # Get messages from Database messages = await message_storage.list_messages(query.chat_id, query.from_date, query.to_date) return [await self.build_message_response(msg) for msg in messages]