import { fileOriginNameFilter } from '@api/helpers/file-helper';
import {
  Body,
  Controller,
  Get,
  Param,
  Post,
  Query,
  UploadedFiles,
  UseGuards,
  UseInterceptors,
} from '@nestjs/common';
import {
  AnyFilesInterceptor,
  FileFieldsInterceptor,
} from '@nestjs/platform-express';
import {
  ApiBody,
  ApiConsumes,
  ApiExtraModels,
  ApiOkResponse,
  ApiOperation,
  ApiTags,
  getSchemaPath,
} from '@nestjs/swagger';
import { plainToInstance } from 'class-transformer';
import { AdminJwtAuthGuard } from '../auth/admin/jwt.guard';
import {
  CreatePopupDto,
  DeletePopupDto,
  GetAdminPopupListDto,
  GetImageS3KeyPopupDto,
  GetPopupDto,
  GetPopupListResponseDto,
  UpdatePopupDto,
} from './popup.dto';
import { PopupService } from './popup.service';
import { RolesGuard } from '../auth/admin/roles.guard';
import { Roles } from '../auth/admin/roles.decorator';

@ApiTags('[관리자] 팝업')
@UseGuards(AdminJwtAuthGuard, RolesGuard)
@Roles('admin')
@Controller('admin/popup')
export class AdminPopupController {
  constructor(private popupService: PopupService) {}

  @ApiOperation({
    summary: `팝업목록/검색`,
  })
  @Get()
  @ApiOkResponse({ type: GetPopupListResponseDto })
  async getPopupList(@Query() query: GetAdminPopupListDto) {
    const data = await this.popupService.getPopupList(query, true);
    return plainToInstance(GetPopupListResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @Get(':popId')
  @ApiOperation({
    summary: '팝업 상세조회',
  })
  @ApiOkResponse({ type: GetPopupDto })
  async getProduct(@Param('popId') popId: number) {
    const data = await this.popupService.getDetail(popId);
    return plainToInstance(GetPopupDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @Post()
  @ApiOperation({
    summary: '팝업 신규등록',
  })
  @ApiConsumes('multipart/form-data')
  @ApiExtraModels(CreatePopupDto)
  @ApiBody({
    description: '팝업 등록 정보',
    schema: {
      type: 'object',
      properties: {
        popImg: { type: 'string', format: 'binary', nullable: false },
        popupData: {
          allOf: [{ $ref: getSchemaPath(CreatePopupDto) }],
        },
      },
    },
  })
  @UseInterceptors(
    FileFieldsInterceptor([{ name: 'popImg', maxCount: 1 }], {
      fileFilter: fileOriginNameFilter,
    }),
  )
  async createProduct(
    @UploadedFiles()
    files: Express.Multer.File[],
    @Body('popupData') popupDataString: string,
  ) {
    await this.popupService.createPopup(popupDataString, files);
    return;
  }

  @Post('edit/:popId')
  @ApiOperation({
    summary: `팝업 수정 
     *기존 업로드 된 이미지는 popupData 이미지url입력
      이미지url 예시) popup/images/f5353a2745f6a7036e9fe344db1804d9.png 
      새로 업로드되는 이미지는 '파일선택'으로 업로드`,
  })
  @ApiConsumes('multipart/form-data')
  @ApiExtraModels(UpdatePopupDto)
  @ApiBody({
    description: '팝업 등록 정보',
    schema: {
      type: 'object',
      properties: {
        popImg: { type: 'string', format: 'binary', nullable: false },
        popupData: {
          allOf: [{ $ref: getSchemaPath(UpdatePopupDto) }],
        },
      },
    },
  })
  @UseInterceptors(
    FileFieldsInterceptor([{ name: 'popImg', maxCount: 1 }], {
      fileFilter: fileOriginNameFilter,
    }),
  )
  async updatePopup(
    @UploadedFiles()
    files: Express.Multer.File[],
    @Param('popId') popId: number,
    @Body('popupData') popupDataString: string,
  ) {
    await this.popupService.updatePopup(popId, popupDataString, files);
    return;
  }

  //* editor 이미지 업로드
  @Post('image-upload')
  @ApiOperation({
    summary: '공지사항 editor 이미지 업로드',
  })
  @ApiConsumes('multipart/form-data')
  @ApiBody({
    description: '파일',
    schema: {
      type: 'object',
      properties: {
        file: { type: 'string', format: 'binary', nullable: true },
      },
    },
  })
  @UseInterceptors(AnyFilesInterceptor({ fileFilter: fileOriginNameFilter }))
  @ApiExtraModels(GetImageS3KeyPopupDto)
  async imageUpload(@UploadedFiles() file: Express.Multer.File[]) {
    const data = await this.popupService.editorImageUpload(file);
    return plainToInstance(GetImageS3KeyPopupDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @Post('delete')
  @ApiOperation({
    summary: '팝업 삭제',
  })
  async deletePopup(@Body() body: DeletePopupDto) {
    await this.popupService.deletePopup(body);
    return;
  }
}
