import { fileOriginNameFilter } from '@api/helpers/file-helper';
import {
  Body,
  Controller,
  Get,
  Param,
  Post,
  Query,
  UploadedFiles,
  UseGuards,
  UseInterceptors,
} from '@nestjs/common';
import { 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 {
  CreateBannerDto,
  DeleteBannerDto,
  GetBannerDto,
  GetBannerListResponseDto,
  GetCommonBannerListDto,
  UpdateBannerDto,
} from './banner.dto';
import { BannerService } from './banner.service';
import { RolesGuard } from '../auth/admin/roles.guard';
import { Roles } from '../auth/admin/roles.decorator';

@ApiTags('[관리자] 배너')
@UseGuards(AdminJwtAuthGuard, RolesGuard)
@Roles('admin')
@Controller('admin/banner')
export class AdminBannerController {
  constructor(private bannerService: BannerService) {}

  @ApiOperation({
    summary: `배너목록/검색`,
  })
  @Get()
  @ApiOkResponse({ type: GetBannerListResponseDto })
  async getBannerList(@Query() query: GetCommonBannerListDto) {
    const data = await this.bannerService.getBannerList(query, true);
    return plainToInstance(GetBannerListResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @Get(':bnnId')
  @ApiOperation({
    summary: '배너 상세조회',
  })
  @ApiOkResponse({ type: GetBannerDto })
  async getProduct(@Param('bnnId') bnnId: number) {
    const data = await this.bannerService.getDetail(bnnId);
    return plainToInstance(GetBannerDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @Post()
  @ApiOperation({
    summary: '배너 신규등록',
  })
  @ApiConsumes('multipart/form-data')
  @ApiExtraModels(CreateBannerDto)
  @ApiBody({
    description: '배너 등록 정보',
    schema: {
      type: 'object',
      properties: {
        bnnImg: { type: 'string', format: 'binary', nullable: false },
        bannerData: {
          allOf: [{ $ref: getSchemaPath(CreateBannerDto) }],
        },
      },
    },
  })
  @UseInterceptors(
    FileFieldsInterceptor([{ name: 'bnnImg', maxCount: 1 }], {
      fileFilter: fileOriginNameFilter,
    }),
  )
  async createProduct(
    @UploadedFiles()
    files: Express.Multer.File[],
    @Body('bannerData') bannerDataString: string,
  ) {
    await this.bannerService.createBanner(bannerDataString, files);
    return;
  }

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

  @Post('delete')
  @ApiOperation({
    summary: '배너 삭제',
  })
  async deleteBanner(@Body() body: DeleteBannerDto) {
    await this.bannerService.deleteBanner(body);
    return;
  }
}
