import { NOT_FOUND_MEMBER_ID } from '@api/constants/api.constant';
import { hashWithSHA256 } from '@api/helpers/format.helper';
import {
  Body,
  Controller,
  Delete,
  Get,
  NotFoundException,
  Param,
  ParseIntPipe,
  Patch,
  Post,
  Query,
  Req,
  UseGuards,
} from '@nestjs/common';
import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
import { plainToInstance } from 'class-transformer';
import { Request } from 'express';
import { JwtAuthGuard } from '../auth/user/jwt.guard';
import { tokenMemId } from '../auth/user/token-member';
import { GetUserListDto, GetUserListResponseDto } from '../user/user.dto';
import {
  CheckPasswordDto,
  EncryptFcDto,
  GetFcDto,
  GetPushSettingsResponseDto,
  UpdateFcDto,
  UpdatePushSettingsDto,
} from './fc.dto';
import { FcService } from './fc.service';

@ApiTags('FC')
@UseGuards(JwtAuthGuard)
@Controller('fc')
export class FcController {
  constructor(private fcService: FcService) {}

  @ApiOperation({ summary: `FC고객목록조회` })
  @Get('user')
  @ApiOkResponse({ type: GetUserListResponseDto })
  async getFcUserList(@Query() query: GetUserListDto, @Req() req: Request) {
    //* mut:k8-getFcUserList begin
    tokenMemId(req, query.memId);
    //* mut:k8-getFcUserList end
    if (!query.memId) throw new NotFoundException(NOT_FOUND_MEMBER_ID);
    const data = await this.fcService.getFcUserList(query);
    return plainToInstance(GetUserListResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({ summary: 'FC상세조회' })
  @Get(':memId')
  async getFc(
    @Param('memId', ParseIntPipe) memId: number,
    @Req() req: Request,
  ) {
    //* mut:k8-getFc begin
    tokenMemId(req, memId);
    //* mut:k8-getFc end
    const data = await this.fcService.getDetail(memId);
    return plainToInstance(GetFcDto, data, { excludeExtraneousValues: true });
  }

  @ApiOperation({
    summary: `FC memId 암호화`,
    description: `toss 카드등록시 암호화`,
  })
  @Post('encrypt')
  encryptCode(@Body() body: EncryptFcDto, @Req() req: Request) {
    //* mut:k8-encryptCode begin
    tokenMemId(req, body.memId);
    //* mut:k8-encryptCode end
    const customerKey: string = hashWithSHA256(body.memId.toString());
    return { customerKey };
  }

  @ApiOperation({ summary: `회원정보수정` })
  @Patch(':memId')
  async update(
    @Param('memId', ParseIntPipe) memId: number,
    @Body() body: UpdateFcDto,
    @Req() req: Request,
  ) {
    //* mut:k8-update begin
    tokenMemId(req, memId);
    //* mut:k8-update end
    await this.fcService.update(memId, body);
    return;
  }

  @ApiOperation({ summary: '비밀번호확인' })
  @Post('check-password')
  async checkPassword(@Body() dto: CheckPasswordDto, @Req() req: Request) {
    const memId = tokenMemId(req);
    await this.fcService.checkPassword(memId, dto);
    return;
  }

  @ApiOperation({ summary: '회원탈퇴' })
  @Delete(':fcId')
  async withdraw(
    @Param('fcId', ParseIntPipe) fcId: number,
    @Req() req: Request,
  ) {
    //* mut:k8-withdraw begin
    tokenMemId(req, fcId);
    //* mut:k8-withdraw end
    await this.fcService.withdraw(fcId);
    return;
  }

  @ApiOperation({ summary: '푸시알림 설정 조회' })
  @Get(':memId/push-settings')
  @ApiOkResponse({ type: GetPushSettingsResponseDto })
  async getPushSettings(
    @Param('memId', ParseIntPipe) memId: number,
    @Req() req: Request,
  ) {
    //* mut:k8-pushGet begin
    tokenMemId(req, memId);
    //* mut:k8-pushGet end
    const data = await this.fcService.getPushSettings(memId);
    return plainToInstance(GetPushSettingsResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({ summary: '푸시알림 설정 수정' })
  @Patch(':memId/push-settings')
  async updatePushSettings(
    @Param('memId', ParseIntPipe) memId: number,
    @Body() body: UpdatePushSettingsDto,
    @Req() req: Request,
  ) {
    //* mut:k8-pushPatch begin
    tokenMemId(req, memId);
    //* mut:k8-pushPatch end
    await this.fcService.updatePushSettings(memId, body);
    return;
  }

  @ApiOperation({
    summary: '이벤트 팝업 [다음에] — 96시간 스누즈(계정별, 웹/앱 공유)',
  })
  @Post(':memId/push-event-snooze')
  async snoozeEventPopup(
    @Param('memId', ParseIntPipe) memId: number,
    @Req() req: Request,
  ) {
    //* mut:k8-snooze begin
    tokenMemId(req, memId);
    //* mut:k8-snooze end
    await this.fcService.snoozeEventPopup(memId);
    return;
  }
}
