import {
  BadRequestException,
  Body,
  Controller,
  Get,
  Param,
  Patch,
  Post,
  Query,
} from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { TicketPriority, TicketStatus } from '@prisma/client';
import { TicketsService } from './tickets.service';
import {
  AddTicketMessageDto,
  AssignTicketDto,
  CreateTicketDto,
  UpdateTicketStatusDto,
} from './dto/ticket.dto';
import { CurrentUser, AuthenticatedUser } from '../../common/decorators/current-user.decorator';

@ApiTags('tickets')
@ApiBearerAuth()
@Controller('tickets')
export class TicketsController {
  constructor(private readonly service: TicketsService) {}

  @Post()
  create(@CurrentUser() user: AuthenticatedUser, @Body() dto: CreateTicketDto) {
    return this.service.create(user, dto);
  }

  @Get()
  list(
    @CurrentUser() user: AuthenticatedUser,
    @Query('status') status?: string,
    @Query('complexId') complexId?: string,
    @Query('assignedToMe') assignedToMe?: string,
    @Query('mine') mine?: string,
    @Query('priority') priority?: string,
  ) {
    // Validate enum query params at the controller boundary so bad input
    // surfaces as 400 (not 500 from a Prisma enum cast deeper down).
    if (status && !Object.values(TicketStatus).includes(status as TicketStatus)) {
      throw new BadRequestException(
        `Invalid status: must be one of ${Object.values(TicketStatus).join(', ')}`,
      );
    }
    if (priority && !Object.values(TicketPriority).includes(priority as TicketPriority)) {
      throw new BadRequestException(
        `Invalid priority: must be one of ${Object.values(TicketPriority).join(', ')}`,
      );
    }
    return this.service.list(user, {
      status: status as TicketStatus | undefined,
      complexId,
      assignedToMe: assignedToMe === 'true',
      mine: mine === 'true',
      priority: priority as TicketPriority | undefined,
    });
  }

  @Get(':id')
  findOne(@CurrentUser() user: AuthenticatedUser, @Param('id') id: string) {
    return this.service.findOne(user, id);
  }

  @Post(':id/messages')
  addMessage(
    @CurrentUser() user: AuthenticatedUser,
    @Param('id') id: string,
    @Body() dto: AddTicketMessageDto,
  ) {
    return this.service.addMessage(user, id, dto);
  }

  @Patch(':id/assign')
  assign(
    @CurrentUser() user: AuthenticatedUser,
    @Param('id') id: string,
    @Body() dto: AssignTicketDto,
  ) {
    return this.service.assign(user, id, dto);
  }

  @Patch(':id/status')
  updateStatus(
    @CurrentUser() user: AuthenticatedUser,
    @Param('id') id: string,
    @Body() dto: UpdateTicketStatusDto,
  ) {
    return this.service.updateStatus(user, id, dto);
  }
}
