import { Agency } from '@api/modules/agency/agency/agency.entity';
import {
  ApiExtraModels,
  ApiPropertyOptional,
  IntersectionType,
  OmitType,
  PartialType,
  PickType,
} from '@nestjs/swagger';
import { Expose, Transform, Type } from 'class-transformer';
import {
  IsArray,
  IsInt,
  IsObject,
  IsOptional,
  IsString,
  ValidateNested,
} from 'class-validator';
import {
  CountDto,
  DateSearchDto,
  PaginationDto,
  SearchDto,
} from '../common/common.dto';
import { Member } from '../fc/fc.entity';
import { User } from './user.entity';
import { SalesAgency } from '../sales-agency/sales-agency.entity';
import { SalesAgencyChannel } from '../sales-agency/channel/sales-agency-channel.entity';
import { typeParser } from '@lib/utils/type-parser';

export class GetCommonUserListDto extends IntersectionType(
  PaginationDto,
  DateSearchDto,
  SearchDto,
  PartialType(PickType(Member, ['memId', 'memType'])),
  PartialType(PickType(Agency, ['agcId'])),
  PartialType(PickType(SalesAgency, ['sagId'])),
  PartialType(PickType(SalesAgencyChannel, ['sacCode'])),
) {
  @ApiPropertyOptional({
    description: '검색날짜 타입 (default: usrCreatedAt)',
    enum: ['usrCreatedAt'],
  })
  dateType = 'usrCreatedAt';

  @ApiPropertyOptional({
    description: '검색조건 (default: usrName)',
    enum: [
      'usrName',
      'usrPhone',
      'memLoginId',
      'memName',
      'memAgency',
      'agcCorporateName',
    ],
  })
  searchKey = 'usrName';

  @ApiPropertyOptional({
    description: '정렬조건 (default: usrCreatedAt)',
    enum: ['usrName', 'usrCreatedAt'],
  })
  sortKey = 'usrCreatedAt';

  //* 조직관리자 부분트리 스코프(서버 내부 주입, 클라 미노출) — org_path LIKE prefix
  @IsString()
  @IsOptional()
  orgPath?: string;
}

export class GetAdminUserListDto extends OmitType(GetCommonUserListDto, [
  'memId',
]) {}

export class GetUserListDto extends GetCommonUserListDto {
  @ApiPropertyOptional({
    description: '검색조건 (default: usrName)',
    enum: ['usrName', 'usrPhone'],
  })
  searchKey = 'usrName';
}
export class EnrollDto extends IntersectionType(
  PickType(User, ['usrName', 'usrBirth', 'usrPhone']),
  PickType(Member, ['memId']),
) {}

//--------------------- ResponseDto ---------------------//

class UserDto extends OmitType(User, ['usrUpdatedAt']) {}
class MemberUserDto extends PickType(Member, [
  'memId',
  'memName',
  'memLoginId',
  'memAgency',
  'memType',
]) {}
class AgencyUserDto extends PickType(Agency, ['agcCorporateName']) {}

class SalesAgencyDto extends PickType(SalesAgency, ['sagName']) {}

class SalesAgencyChannelDto extends PickType(SalesAgencyChannel, [
  'sacName',
  'sacCode',
]) {}

@ApiExtraModels(
  AgencyUserDto,
  MemberUserDto,
  UserDto,
  SalesAgencyDto,
  SalesAgencyChannelDto,
)
export class GetUserDto {
  @Expose()
  @ApiPropertyOptional({ type: AgencyUserDto, description: '기업 정보' })
  @ValidateNested({ each: true })
  @Type(() => AgencyUserDto)
  @IsObject()
  agency!: AgencyUserDto;

  @Expose()
  @ApiPropertyOptional({ type: MemberUserDto, description: 'FC 정보' })
  @ValidateNested({ each: true })
  @Type(() => MemberUserDto)
  @IsObject()
  member!: MemberUserDto;

  @Expose()
  @ApiPropertyOptional({ type: UserDto, description: '고객 정보' })
  @ValidateNested({ each: true })
  @Type(() => UserDto)
  @IsObject()
  user!: UserDto;

  @Expose()
  @ApiPropertyOptional({ type: SalesAgencyDto, description: '영업대리점 정보' })
  @ValidateNested({ each: true })
  @Type(() => SalesAgencyDto)
  @IsObject()
  salesAgency!: SalesAgencyDto;

  @Expose()
  @ApiPropertyOptional({
    type: SalesAgencyChannelDto,
    description: '영업대리점 채널 정보',
  })
  @ValidateNested({ each: true })
  @Type(() => SalesAgencyChannelDto)
  @IsObject()
  salesAgencyChannel!: SalesAgencyChannelDto;
}

@ApiExtraModels(GetUserDto, CountDto)
export class GetUserListResponseDto extends IntersectionType(CountDto) {
  @Expose()
  @ApiPropertyOptional({ type: [GetUserDto], description: '목록' })
  @Type(() => GetUserDto)
  @IsArray()
  @IsOptional()
  list?: GetUserDto[];
}
