import {
  Body,
  Controller,
  Delete,
  Get,
  HttpCode,
  HttpStatus,
  Param,
  ParseIntPipe,
  Patch,
  Post,
  UseGuards,
} from '@nestjs/common';
import {
  ApiBearerAuth,
  ApiOperation,
  ApiParam,
  ApiResponse,
  ApiTags,
} from '@nestjs/swagger';

import { Action } from '@/casl/action.enum';
import { AppAbility } from '@/casl/casl-ability.factory';
import { CheckPolicies } from '@/casl/check-policies.decorator';
import { PoliciesGuard } from '@/casl/policies.guard';
import { JwtAuthGuard } from '@/modules/auth/jwt-auth.guard';

import { CreateMeetingSummaryStatusDto } from './dto/create-meeting-summary-status.dto';
import { UpdateMeetingSummaryStatusDto } from './dto/update-meeting-summary-status.dto';
import { MeetingSummaryStatusService } from './meeting-summary-status.service';

// CASL subject guarding every route in this controller.
const SUBJECT = 'MeetingSummaryStatus';

@ApiTags('meeting-summary-statuses')
@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard, PoliciesGuard)
@Controller('meeting-summary-statuses')
export class MeetingSummaryStatusController {
  constructor(private readonly service: MeetingSummaryStatusService) {}

  @Post()
  @HttpCode(HttpStatus.CREATED)
  @CheckPolicies((ability: AppAbility) => ability.can(Action.Create, SUBJECT))
  @ApiOperation({ summary: 'Create a meeting summary status' })
  @ApiResponse({ status: 201, description: 'Status created.' })
  @ApiResponse({ status: 409, description: 'Status code already exists.' })
  create(@Body() dto: CreateMeetingSummaryStatusDto) {
    return this.service.create(dto);
  }

  @Get()
  @HttpCode(HttpStatus.OK)
  @CheckPolicies((ability: AppAbility) => ability.can(Action.Read, SUBJECT))
  @ApiOperation({ summary: 'List meeting summary statuses' })
  @ApiResponse({ status: 200, description: 'All statuses.' })
  findAll() {
    return this.service.findAll();
  }

  @Get(':id')
  @HttpCode(HttpStatus.OK)
  @CheckPolicies((ability: AppAbility) => ability.can(Action.Read, SUBJECT))
  @ApiParam({ name: 'id', type: Number, description: 'Status ID.' })
  @ApiOperation({ summary: 'Get one meeting summary status' })
  @ApiResponse({ status: 200, description: 'Status detail.' })
  @ApiResponse({ status: 404, description: 'Status not found.' })
  findOne(@Param('id', ParseIntPipe) id: number) {
    return this.service.findOne(id);
  }

  @Patch(':id')
  @HttpCode(HttpStatus.OK)
  @CheckPolicies((ability: AppAbility) => ability.can(Action.Update, SUBJECT))
  @ApiParam({ name: 'id', type: Number, description: 'Status ID.' })
  @ApiOperation({ summary: 'Update a meeting summary status' })
  @ApiResponse({ status: 200, description: 'Status updated.' })
  @ApiResponse({ status: 404, description: 'Status not found.' })
  @ApiResponse({ status: 409, description: 'Status code already exists.' })
  update(
    @Param('id', ParseIntPipe) id: number,
    @Body() dto: UpdateMeetingSummaryStatusDto,
  ) {
    return this.service.update(id, dto);
  }

  @Delete(':id')
  @HttpCode(HttpStatus.OK)
  @CheckPolicies((ability: AppAbility) => ability.can(Action.Delete, SUBJECT))
  @ApiParam({ name: 'id', type: Number, description: 'Status ID.' })
  @ApiOperation({ summary: 'Soft delete a meeting summary status' })
  @ApiResponse({ status: 200, description: 'Status deleted.' })
  @ApiResponse({ status: 404, description: 'Status not found.' })
  remove(@Param('id', ParseIntPipe) id: number) {
    return this.service.remove(id);
  }
}
