import {
  Controller,
  Get,
  Header,
  Query,
  Req,
  Res,
  UseGuards,
} from '@nestjs/common';
import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
import { plainToInstance } from 'class-transformer';
import { Response } from 'express';
import { AdminJwtAuthGuard } from '../auth/admin/jwt.guard';
import { GetCommonUserListDto, GetUserListResponseDto } from './user.dto';
import { UserService } from './user.service';
import { Roles } from '../auth/admin/roles.decorator';
import { RolesGuard } from '../auth/admin/roles.guard';
import { CorpReadonlyGuard } from '../auth/admin/corp-readonly.guard';
import { maskString } from '@api/helpers/mask.helper';

@ApiTags('[관리자] 고객')
@UseGuards(AdminJwtAuthGuard, RolesGuard, CorpReadonlyGuard)
@Controller('admin/user')
@Roles('admin', 'sales', 'corp')
export class AdminUserController {
  constructor(private userService: UserService) {}

  @ApiOperation({
    summary: `고객 목록/검색`,
  })
  @Get()
  @ApiOkResponse({ type: GetUserListResponseDto })
  async getUserList(@Query() query: GetCommonUserListDto, @Req() req: Request) {
    const { role, sagId, agcId, corpScope, orgPath } = req['admin'];

    //* 영업대리점(관리자)가 접근시
    if (role === 'sales') {
      query.sagId = sagId;
    }

    //* 기업관리자가 접근시 - 자신의 기업(agcId)으로 필터링
    if (role === 'corp') {
      query.agcId = agcId;
      //* 조직관리자(ORG)는 자기 org 부분트리만(다른 목록 API와 동일 스코프)
      if (corpScope === 'ORG') query.orgPath = orgPath;
    }

    const data = await this.userService.getUserList(query);

    //* 영업대리점 로그인일 경우 리턴 데이터 마스킹 처리
    data.list =
      role === 'sales'
        ? data.list.map((e) => ({
            ...e,
            user: {
              usrId: e.user.usrId,
              usrName: e.user.usrName ? maskString('name', e.user.usrName) : '',
              usrPhone: e.user.usrPhone
                ? maskString('phone', e.user.usrPhone)
                : '',
              usrBirth: e.user.usrBirth
                ? maskString('birth', e.user.usrBirth)
                : '',
              usrCreatedAt: e.user.usrCreatedAt,
            },
            member: e.member
              ? {
                  memId: e.member.memId,
                  memLoginId: e.member.memLoginId,
                  memName: e.member.memName
                    ? maskString('name', e.member.memName)
                    : '',
                  memAgency: e.member.memAgency ?? '',
                  memType: e.member.memType ?? '',
                }
              : null,
          }))
        : data.list;

    return plainToInstance(GetUserListResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @Get('download')
  @ApiOperation({
    summary: '엑셀다운로드',
    description: '모든 FC 목록을 다운로드합니다.',
  })
  @Header(
    'Content-Type',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  )
  @Header(
    'Content-Disposition',
    `attachment;filename*=utf-8''${encodeURIComponent('고객목록')}.xlsx`,
  )
  async downloadUserList(
    @Query() query: GetCommonUserListDto,
    @Res({ passthrough: true }) res: Response,
    @Req() req: Request,
  ) {
    const { role, sagId, agcId, corpScope, orgPath } = req['admin'];

    //* 영업대리점(관리자)가 접근시
    if (role === 'sales') {
      query.sagId = sagId;
    }

    //* 기업관리자: 자기 기업만 + 조직관리자(ORG)는 부분트리만 (목록 조회와 동일 스코프)
    if (role === 'corp') {
      query.agcId = agcId;
      if (corpScope === 'ORG') query.orgPath = orgPath;
    }

    await this.userService.downloadUserList(query, res, role);
    return;
  }
}
