import { Controller, Get, Post, Patch, Body, Param, Query, UseGuards, HttpCode, HttpStatus, } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiQuery, ApiParam, } from '@nestjs/swagger'; import { SupportChatService } from './support-chat.service'; import { SendSupportMessageDto } from './dto'; import { JwtAuthGuard } from '../auth/guards'; import { CurrentUser } from '../auth/decorators'; import { Roles } from '../auth/decorators/roles.decorator'; import { UserRole, SupportChatStatus } from '@prisma/client'; @ApiTags('Support Chat') @Controller('support-chat') @UseGuards(JwtAuthGuard) @ApiBearerAuth('JWT-auth') export class SupportChatController { constructor(private readonly supportChatService: SupportChatService) {} // ========================================== // GET OR CREATE SUPPORT CHAT (User/Agent) // ========================================== @Post() @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Get or create a support chat for the current user' }) async getOrCreateChat(@CurrentUser('id') userId: string) { return this.supportChatService.getOrCreateChat(userId); } // ========================================== // GET MY SUPPORT CHAT (User/Agent) // ========================================== @Get('my') @ApiOperation({ summary: 'Get current user\'s open support chat' }) async getMyChat(@CurrentUser('id') userId: string) { return this.supportChatService.getOrCreateChat(userId); } // ========================================== // GET MESSAGES // ========================================== @Get(':id/messages') @ApiOperation({ summary: 'Get messages for a support chat' }) @ApiParam({ name: 'id', description: 'Support Chat ID' }) @ApiQuery({ name: 'page', required: false, type: Number }) @ApiQuery({ name: 'limit', required: false, type: Number }) async getMessages( @Param('id') chatId: string, @CurrentUser('id') userId: string, @CurrentUser('role') role: UserRole, @Query('page') page?: string, @Query('limit') limit?: string, ) { // Validate access const isAdmin = role === UserRole.ADMIN; await this.supportChatService.getChat(chatId, userId, isAdmin); return this.supportChatService.getMessages( chatId, page ? parseInt(page, 10) : 1, limit ? parseInt(limit, 10) : 50, ); } // ========================================== // SEND MESSAGE (REST fallback) // ========================================== @Post(':id/messages') @HttpCode(HttpStatus.CREATED) @ApiOperation({ summary: 'Send a message in a support chat' }) @ApiParam({ name: 'id', description: 'Support Chat ID' }) async sendMessage( @Param('id') chatId: string, @CurrentUser('id') userId: string, @CurrentUser('role') role: UserRole, @Body() dto: SendSupportMessageDto, ) { // Validate access const isAdmin = role === UserRole.ADMIN; await this.supportChatService.getChat(chatId, userId, isAdmin); const senderRole = role === UserRole.ADMIN ? 'ADMIN' : 'USER'; return this.supportChatService.sendMessage(chatId, userId, senderRole, dto.content); } // ========================================== // MARK AS READ // ========================================== @Patch(':id/read') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Mark support chat messages as read' }) @ApiParam({ name: 'id', description: 'Support Chat ID' }) async markAsRead( @Param('id') chatId: string, @CurrentUser('role') role: UserRole, ) { return this.supportChatService.markAsRead(chatId, role); } // ========================================== // ADMIN: GET ALL SUPPORT CHATS // ========================================== @Get('admin/all') @Roles(UserRole.ADMIN) @ApiOperation({ summary: 'Admin: Get all support chats' }) @ApiQuery({ name: 'status', required: false, enum: SupportChatStatus }) async getAllChats(@Query('status') status?: SupportChatStatus) { return this.supportChatService.getAllChats(status); } // ========================================== // ADMIN: CLOSE SUPPORT CHAT // ========================================== @Patch('admin/:id/close') @Roles(UserRole.ADMIN) @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Admin: Close a support chat' }) @ApiParam({ name: 'id', description: 'Support Chat ID' }) async closeChat(@Param('id') chatId: string) { return this.supportChatService.closeChat(chatId); } }