import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import {
  IsArray,
  IsBoolean,
  IsEmail,
  IsEnum,
  IsNumber,
  IsOptional,
  IsString,
  IsUrl,
  Length,
  Max,
  Matches,
  Min,
} from 'class-validator';
import { ExperienceLevel } from '../../../common/enums/experience-level.enum';
import { MusicRole } from '../../../common/enums/music-role.enum';
import { toBoolean } from '../../../common/utils/query-transform.util';

export class CreateUserDto {
  @ApiProperty({ example: 'John Doe' })
  @IsString()
  @Length(2, 80)
  name!: string;

  @ApiProperty({ required: false, example: 'Artist One' })
  @IsOptional()
  @IsString()
  @Length(0, 80)
  stageName?: string;

  @ApiProperty({ example: 'john_doe' })
  @IsString()
  @Length(3, 30)
  @Matches(/^[a-zA-Z0-9_.]+$/, { message: 'username can contain letters, numbers, _ and .' })
  username!: string;

  @ApiProperty({ example: 'john@example.com' })
  @IsEmail()
  email!: string;

  @ApiProperty({ minLength: 8, example: 'StrongPass123!' })
  @IsString()
  @Length(8, 64)
  password!: string;

  @ApiProperty({ required: false, maxLength: 160 })
  @IsOptional()
  @IsString()
  @Length(0, 160)
  bio?: string;

  @ApiProperty({ required: false, example: 'https://cdn.example.com/avatar.jpg' })
  @IsOptional()
  @IsUrl({ require_tld: false })
  avatar?: string;

  @ApiProperty({ required: false, example: 'https://cdn.example.com/profile-cover.jpg' })
  @IsOptional()
  @IsUrl({ require_tld: false })
  coverImage?: string;

  @ApiProperty({ required: false, example: 'Riyadh, Saudi Arabia' })
  @IsOptional()
  @IsString()
  @Length(0, 120)
  location?: string;

  @ApiProperty({ required: false, example: 24.7136, minimum: -90, maximum: 90 })
  @IsOptional()
  @IsNumber()
  @Min(-90)
  @Max(90)
  latitude?: number;

  @ApiProperty({ required: false, example: 46.6753, minimum: -180, maximum: 180 })
  @IsOptional()
  @IsNumber()
  @Min(-180)
  @Max(180)
  longitude?: number;

  @ApiProperty({ required: false, default: false })
  @IsOptional()
  @Transform(toBoolean)
  @IsBoolean()
  isPrivate?: boolean;

  @ApiProperty({ required: false, default: false })
  @IsOptional()
  @Transform(toBoolean)
  @IsBoolean()
  isVerified?: boolean;

  @ApiProperty({ required: false, default: false })
  @IsOptional()
  @Transform(toBoolean)
  @IsBoolean()
  isEmailVerified?: boolean;

  @ApiProperty({ required: false, enum: MusicRole, isArray: true })
  @IsOptional()
  @IsArray()
  @IsEnum(MusicRole, { each: true })
  musicRoles?: MusicRole[];

  @ApiProperty({ required: false, enum: ExperienceLevel, example: ExperienceLevel.BEGINNER })
  @IsOptional()
  @IsEnum(ExperienceLevel)
  experienceLevel?: ExperienceLevel;

  @ApiProperty({ required: false, type: [String], example: ['Tarab', 'Pop'] })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  musicGenres?: string[];

  @ApiProperty({ required: false, type: [String], example: ['Oud', 'Piano'] })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  favoriteInstruments?: string[];

  @ApiProperty({ required: false, type: [String], example: ['Bayati', 'Rast'] })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  favoriteMaqamat?: string[];

  @ApiProperty({ required: false, example: 'طربي', maxLength: 80 })
  @IsOptional()
  @IsString()
  @Length(0, 80)
  preferredMood?: string;
}
