import { AdminJwtAuthGuard } from '@api/modules/auth/admin/jwt.guard';
import {
  Body,
  Controller,
  Get,
  Header,
  Param,
  Post,
  Query,
  Res,
  UploadedFile,
  UseGuards,
  UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import {
  ApiBody,
  ApiConsumes,
  ApiOkResponse,
  ApiOperation,
  ApiTags,
} from '@nestjs/swagger';
import { plainToInstance } from 'class-transformer';
import { Response } from 'express';
import {
  CreateCompareBasicDto,
  DeleteCompareBasicDto,
  GetCompareBasicDto,
  GetCompareBasicListDto,
  GetCompareBasicListResponseDto,
  UpdateCompareBasicDto,
} from './compare-basic.dto';
import { CompareBasicService } from './compare-basic.service';
import { Roles } from '@api/modules/auth/admin/roles.decorator';
import { RolesGuard } from '@api/modules/auth/admin/roles.guard';

@ApiTags('[관리자] 대조데이터 기본')
@UseGuards(AdminJwtAuthGuard, RolesGuard)
@Roles('admin')
@Controller('admin/compare/basic')
export class CompareBasicController {
  constructor(private compareBasicService: CompareBasicService) {}

  @ApiOperation({
    summary: `대조기본 목록/검색`,
    description: `대조데이터 중 기본에 해당하는 데이터의 목록을 조회 및 검색을 합니다.
                  COM001 : 11(6)대 중대질병
                  COM005 : 주의사항
                  COM006 : 숨은보험진단
                  COM007 : 숨은보험치아
                  COM010 : 치아(틀니)
                  COM011 : 치아(1년)
                  COM012 : 치아(5년)
                  `,
  })
  @Get()
  @ApiOkResponse({ type: GetCompareBasicListResponseDto })
  async getCompareBasicList(@Query() query: GetCompareBasicListDto) {
    const data = await this.compareBasicService.getCompareBasicList(query);
    return plainToInstance(GetCompareBasicListResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @Get('download')
  @ApiOperation({
    summary: '엑셀다운로드',
    description: '해당 기본데이터의 목록을 다운로드합니다.',
  })
  @Header(
    'Content-Type',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  )
  @Header(
    'Content-Disposition',
    `attachment;filename*=utf-8''${encodeURIComponent('기본데이터목록')}.xlsx`,
  )
  async downloadCompareBasicList(
    @Query() query: GetCompareBasicListDto,
    @Res({ passthrough: true }) res: Response,
  ) {
    await this.compareBasicService.downloadCompareBasicList(query, res);
    return;
  }

  @Get('upload-form/download')
  @ApiOperation({
    summary: '기본대조데이터 양식 다운로드',
  })
  @Header(
    'Content-Type',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  )
  @Header(
    'Content-Disposition',
    `attachment;filename*=utf-8''${encodeURIComponent('양식_기본대조데이터')}.xlsx`,
  )
  async downloadUploadForm(@Res({ passthrough: true }) res: Response) {
    await this.compareBasicService.downloadUploadForm(res);
    return;
  }

  @Post('upload/:cpbType')
  @ApiOperation({
    summary: '기본대조데이터 업로드',
    description:
      '엑셀 양식으로 기본대조데이터를 업로드합니다.(데이터 전체교체)',
  })
  @ApiConsumes('multipart/form-data')
  @ApiBody({
    description: '기본대조데이터 업로드',
    required: true,
    schema: {
      type: 'object',
      properties: {
        file: {
          type: 'string',
          format: 'binary',
        },
      },
    },
  })
  @UseInterceptors(FileInterceptor('file'))
  async uploadCompareBasic(
    @Param('cpbType') cpbType: string,
    @UploadedFile() file: Express.Multer.File,
  ) {
    return this.compareBasicService.uploadCompareBasic(cpbType, file);
  }

  @Get(':cpbId')
  @ApiOperation({
    summary: '대조기본 상세조회',
  })
  @ApiOkResponse({ type: GetCompareBasicDto })
  async getCompareBasic(@Param('cpbId') cpbId: number) {
    const data = await this.compareBasicService.getDetail(cpbId);
    return plainToInstance(GetCompareBasicDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @Post()
  @ApiOperation({
    summary: '대조기본 신규등록',
  })
  async createCompareBasic(@Body() body: CreateCompareBasicDto) {
    await this.compareBasicService.createCompareBasic(body);
    return;
  }

  @Post('edit/:cpbId')
  @ApiOperation({
    summary: '대조기본 수정',
  })
  async updateCompareBasic(
    @Param('cpbId') cpbId: number,
    @Body() body: UpdateCompareBasicDto,
  ) {
    await this.compareBasicService.updateCompareBasic(cpbId, body);
    return;
  }

  @Post('recovery/:cpbType')
  @ApiOperation({
    summary: '대조기본 직전 데이터 복구',
  })
  async recoveryCompareBasic(@Param('cpbType') cpbType: string) {
    await this.compareBasicService.recoveryCompareBasic(cpbType);
    return;
  }

  @Post('delete')
  @ApiOperation({
    summary: '대조기본 삭제',
  })
  async deleteCompareBasic(@Body() body: DeleteCompareBasicDto) {
    await this.compareBasicService.deleteCompareBasic(body);
    return;
  }
}
