import {
  Controller, Get, Post, Body, Patch, Param, Delete, Query, HttpStatus,
  UseInterceptors, ClassSerializerInterceptor, UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { {{pluralPascal name}}Service } from './{{pluralKebab name}}.service';
import { Create{{pascalCase name}}Dto } from './dto/create-{{kebabCase name}}.dto';
import { Update{{pascalCase name}}Dto } from './dto/update-{{kebabCase name}}.dto';
import { {{pascalCase name}}Resource } from './resources/{{kebabCase name}}.resource';
import { PaginationQueryDto } from 'src/common/dto/pagination-query.dto';
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
import { PermissionsGuard } from 'src/auth/guards/permissions.guard';
import { CheckPermission } from 'src/auth/decorators/permissions.decorator';

@ApiTags('{{pluralPascal name}}')
@Controller('{{pluralKebab name}}')
@UseInterceptors(ClassSerializerInterceptor)
export class {{pluralPascal name}}Controller {
  constructor(private readonly service: {{pluralPascal name}}Service) {}

  @Post()
  @ApiBearerAuth()
  @CheckPermission('{{lowerCase name}}.create')
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @ApiOperation({ summary: 'Create a new {{lowerCase name}}' })
  async create(@Body() dto: Create{{pascalCase name}}Dto) {
    const data = await this.service.create(dto);
    return {
      statusCode: HttpStatus.CREATED,
      message: '{{pascalCase name}} created successfully',
      data: new {{pascalCase name}}Resource(data),
    };
  }

  @Get()
  @ApiOperation({ summary: 'Get all {{lowerCase name}}s' })
  async findAll(@Query() query: PaginationQueryDto) {
    const result = await this.service.findAll(query);
    return {
      statusCode: HttpStatus.OK,
      message: '{{pluralPascal name}} retrieved successfully',
      data: result.data.map((item) => new {{pascalCase name}}Resource(item)),
      meta: result.meta,
    };
  }

  @Get(':id')
  @ApiOperation({ summary: 'Get {{lowerCase name}} by ID' })
  async findOne(@Param('id') id: string) {
    const data = await this.service.findOne(+id);
    return {
      statusCode: HttpStatus.OK,
      message: '{{pascalCase name}} retrieved successfully',
      data: new {{pascalCase name}}Resource(data),
    };
  }

  @Patch(':id')
  @ApiBearerAuth()
  @CheckPermission('{{lowerCase name}}.update')
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @ApiOperation({ summary: 'Update {{lowerCase name}} by ID' })
  async update(@Param('id') id: string, @Body() dto: Update{{pascalCase name}}Dto) {
    const data = await this.service.update(+id, dto);
    return {
      statusCode: HttpStatus.OK,
      message: '{{pascalCase name}} updated successfully',
      data: new {{pascalCase name}}Resource(data),
    };
  }

  @Delete(':id')
  @ApiBearerAuth()
  @CheckPermission('{{lowerCase name}}.delete')
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @ApiOperation({ summary: 'Delete {{lowerCase name}} by ID' })
  async remove(@Param('id') id: string) {
    await this.service.remove(+id);
    return {
      statusCode: HttpStatus.OK,
      message: '{{pascalCase name}} deleted successfully',
    };
  }
}