import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { UserRole, UserStatus } from 'common/enum/UserRole.enum';
import { UserEntity } from '../entity/users.entity';
import { RoleResponseDto } from 'modules/role-permission/roles/dto/role-response.dto';
import { IsArray, IsOptional } from 'class-validator';
import { EffectivePermissionDto } from 'modules/role-permission/roles/dto/effective-permission.dto';

export class UserResponseDto {
  @ApiProperty({
    example: 1,
    description: 'User ID',
  })
  id: number;

  @ApiProperty({
    example: 'John',
    description: 'User first name',
  })
  firstName: string;

  @ApiProperty({
    example: 'Doe',
    description: 'User last name',
  })
  lastName: string;

  @ApiProperty({
    example: 'user@example.com',
    description: 'User email',
  })
  email: string;

  @ApiProperty({
    example: true,
    description: 'Is email verified',
  })
  isEmailVerified: boolean;

  @ApiProperty({
    enum: UserRole,
    example: UserRole.USER,
    description: 'User role',
  })
  role: UserRole;

  @ApiProperty({ example: 'client-id', nullable: true })
  clientId?: string;

  @ApiProperty({ example: 'client-id', nullable: true })
  linkedClientId?: string;

  @ApiProperty({ enum: UserStatus })
  status: UserStatus;

  @ApiProperty({
    description: 'List of roles assigned to the user',
    type: [RoleResponseDto],
  })
  @IsArray()
  roles: RoleResponseDto[];

  @ApiPropertyOptional({
    description: 'List of effective permissions calculated for the user',
    type: [EffectivePermissionDto],
  })
  @IsArray()
  @IsOptional()
  effectivePermissions?: EffectivePermissionDto[];

  @ApiProperty({
    example: 'referral@example.com',
    description: 'Referral email (if applicable)',
    required: false,
  })
  referralMail?: string;

  @ApiProperty({
    example: 'https://cdn-icons-png.flaticon.com/512/149/149071.png',
    description: 'User profile picture',
    required: false,
  })
  picture?: string;

  @ApiProperty({
    example: 'googleId',
    description: 'Google ID',
    required: false,
  })
  googleId?: string;

  @ApiProperty({
    example: false,
    description: 'Is Google user',
    required: false,
  })
  isGoogleUser?: boolean;

  @ApiProperty({
    example: '2024-02-07T12:00:00Z',
    description: 'Creation timestamp',
  })
  createdAt: Date;

  @ApiProperty({
    example: '2024-02-07T12:00:00Z',
    description: 'Last update timestamp',
  })
  updatedAt: Date;
}

export function mapUserToResponseDto(user: UserEntity): UserResponseDto {
  if (!user) return null;

  const userResponseDto = new UserResponseDto();

  userResponseDto.id = user.id;
  userResponseDto.firstName = user.firstName;
  userResponseDto.lastName = user.lastName;
  userResponseDto.email = user.email;
  userResponseDto.isEmailVerified = user.isEmailVerified || false;
  userResponseDto.role = user.role;
  userResponseDto.clientId = user.clientId;
  userResponseDto.linkedClientId = user.linkedClientId;
  userResponseDto.status = user.status;
  userResponseDto.referralMail = user.referralMail;
  userResponseDto.picture = user.picture || 'https://cdn-icons-png.flaticon.com/512/149/149071.png';
  userResponseDto.googleId = user.googleId;
  userResponseDto.isGoogleUser = user.isGoogleUser || false;
  userResponseDto.createdAt = new Date(user.createdAt);
  userResponseDto.updatedAt = new Date(user.updatedAt);

  return userResponseDto;
}

export function mapUsersToResponseDtos(users: UserEntity[]): UserResponseDto[] {
  return users.map(user => mapUserToResponseDto(user));
}
