import { typeParser } from '@lib/utils/type-parser';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Expose, Transform } from 'class-transformer';
import {
  IsEnum,
  IsIn,
  IsInt,
  IsOptional,
  IsString,
  MaxLength,
  ValidateIf,
} from 'class-validator';

export enum MemberType {
  일반FC = 'MEM001',
  기업FC = 'MEM002',
}

export class Member {
  @Expose()
  @ApiProperty({ description: 'FC id' })
  @Transform(({ value }) => typeParser.int(value))
  @IsInt()
  memId!: number;

  @Expose()
  @ApiProperty({
    description: `FC타입(일반:MEM001 | 기업:MEM002)`,
    enum: MemberType,
  })
  @Transform(({ value }) => value?.toUpperCase())
  @IsEnum(MemberType)
  memType!: MemberType;

  @Expose()
  @ApiProperty({ description: 'FC이름' })
  @IsString()
  memName!: string;

  @Expose()
  @ApiProperty({ description: 'FC로그인아이디' })
  @IsString()
  memLoginId!: string;

  @Expose()
  @ApiProperty({ description: 'FC비밀번호' })
  @IsString()
  memPassword!: string;

  @Expose()
  @ApiPropertyOptional({ description: 'FC이메일' })
  @IsString()
  @IsOptional()
  memEmail?: string;

  @Expose()
  @ApiProperty({ description: 'FC연락처' })
  @IsString()
  memPhone!: string;

  /**
   * 소속기업 자유입력(deprecated).
   * task-688에 따라 신규 등록/수정에서는 무시되며, 표시는 [[orgName]] 사용.
   */
  @Expose()
  @ApiPropertyOptional({ description: '소속기업(deprecated, 표시용 잔존)' })
  @IsString()
  @IsOptional()
  memAgency?: string;

  //* 기업조직(task-688): 소속 조직 ID(ULID 26자). 일반/기업 회원 공통 옵셔널.
  //* 수정 요청에서 null은 소속 해제 의도로 허용 → ValidateIf로 null 통과.
  @Expose()
  @ApiPropertyOptional({ description: '소속 조직 ID(ULID 26자)', nullable: true })
  @ValidateIf((_, value) => value !== null && value !== undefined)
  @IsString()
  @MaxLength(26)
  @IsOptional()
  orgId?: string | null;

  //* 소속 조직명(표시용, org 조인 결과) — 조직권한 화면 현재 소속 표시
  @Expose()
  @ApiPropertyOptional({ description: '소속 조직명(표시용)', nullable: true })
  @IsString()
  @IsOptional()
  orgName?: string | null;

  //* 소속 조직 전체 경로(표시용, 서비스에서 배치 병합) — 예: "대구 > 개발팀"
  @Expose()
  @ApiPropertyOptional({
    description: '소속 조직 전체 경로(예: 대구 > 개발팀)',
    nullable: true,
  })
  @IsString()
  @IsOptional()
  orgFullPath?: string | null;

  //* 조직관리자 자격(조직권한): 1=조직관리자, 0=일반
  @Expose()
  @ApiPropertyOptional({ description: '조직관리자 자격(1=조직관리자)' })
  @Transform(({ value }) => typeParser.int(value))
  @IsInt()
  @IsOptional()
  memIsOrgManager?: number;

  @Expose()
  @ApiPropertyOptional({ description: '포인트' })
  @Transform(({ value }) => typeParser.int(value))
  @IsInt()
  @IsOptional()
  memMoney?: number;

  @Expose()
  @ApiPropertyOptional({ description: '구매 포인트' })
  @Transform(({ value }) => typeParser.int(value))
  @IsInt()
  @IsOptional()
  memPurchaseMoney?: number;

  @Expose()
  @ApiPropertyOptional({ description: '기업 머니' })
  @Transform(({ value }) => typeParser.int(value))
  @IsInt()
  @IsOptional()
  memAgencyMoney?: number;

  @Expose()
  @ApiProperty({ description: '탈퇴여부(탈퇴:1|가입:0)' })
  @Transform(({ value }) => typeParser.int(value))
  @IsIn([0, 1])
  memIsResigned!: number;

  @Expose()
  @ApiPropertyOptional({ description: '탈퇴일시시' })
  @IsString()
  @IsOptional()
  memResignedAt?: string;

  @Expose()
  @ApiPropertyOptional({ description: '최종로그인일시' })
  @IsString()
  @IsOptional()
  memLastLoginAt?: string;

  @Expose()
  @ApiPropertyOptional({ description: 'FC수정일시' })
  @IsString()
  @IsOptional()
  memUpdatedAt?: string;

  @Expose()
  @ApiProperty({ description: 'FC생성일시' })
  @IsString()
  memCreatedAt!: string;

  @Expose()
  @ApiPropertyOptional({ description: '내 추천인코드' })
  @IsString()
  @IsOptional()
  memMyReferralCode?: string;

  @Expose()
  @ApiPropertyOptional({ description: '사용한 추천인코드' })
  @IsString()
  @IsOptional()
  memReferralCode?: string;
}
