import { Response } from "express"; import { SendMessageDTO, CreateEventDTO, UpdateEventDTO, EventAction, GetMessagesOptions, RecurringDeleteMode, } from "@calchat/shared"; import { ChatService } from "../services"; import { createLogger } from "../logging"; import { AuthenticatedRequest } from "./AuthMiddleware"; const log = createLogger("ChatController"); export class ChatController { constructor(private chatService: ChatService) {} async sendMessage(req: AuthenticatedRequest, res: Response): Promise { try { const userId = req.user!.userId; const data: SendMessageDTO = req.body; const response = await this.chatService.processMessage(userId, data); res.json(response); } catch (error) { log.error( { error, userId: req.user?.userId }, "Error processing message", ); res.status(500).json({ error: "Failed to process message" }); } } async confirmEvent(req: AuthenticatedRequest, res: Response): Promise { try { const userId = req.user!.userId; const { conversationId, messageId } = req.params; const { proposalId, action, event, eventId, updates, deleteMode, occurrenceDate, } = req.body as { proposalId: string; action: EventAction; event?: CreateEventDTO; eventId?: string; updates?: UpdateEventDTO; deleteMode?: RecurringDeleteMode; occurrenceDate?: string; }; const response = await this.chatService.confirmEvent( userId, conversationId, messageId, proposalId, action, event, eventId, updates, deleteMode, occurrenceDate, ); res.json(response); } catch (error) { log.error( { error, conversationId: req.params.conversationId }, "Error confirming event", ); res.status(500).json({ error: "Failed to confirm event" }); } } async rejectEvent(req: AuthenticatedRequest, res: Response): Promise { try { const userId = req.user!.userId; const { conversationId, messageId } = req.params; const { proposalId } = req.body as { proposalId: string }; const response = await this.chatService.rejectEvent( userId, conversationId, messageId, proposalId, ); res.json(response); } catch (error) { log.error( { error, conversationId: req.params.conversationId }, "Error rejecting event", ); res.status(500).json({ error: "Failed to reject event" }); } } async getConversations( req: AuthenticatedRequest, res: Response, ): Promise { try { const userId = req.user!.userId; const conversations = await this.chatService.getConversations(userId); res.json(conversations); } catch (error) { log.error( { error, userId: req.user?.userId }, "Error getting conversations", ); res.status(500).json({ error: "Failed to get conversations" }); } } async getConversation( req: AuthenticatedRequest, res: Response, ): Promise { try { const userId = req.user!.userId; const { id } = req.params; const { before, limit } = req.query as { before?: string; limit?: string; }; const options: GetMessagesOptions = {}; if (before) options.before = before; if (limit) options.limit = parseInt(limit, 10); const messages = await this.chatService.getConversation( userId, id, options, ); res.json(messages); } catch (error) { if ((error as Error).message === "Conversation not found") { res.status(404).json({ error: "Conversation not found" }); } else { log.error( { error, conversationId: req.params.id }, "Error getting conversation", ); res.status(500).json({ error: "Failed to get conversation" }); } } } }