// eslint-disable-next-line max-classes-per-file
import {
  IsEmail,
  IsEnum,
  IsNotEmpty,
  IsNumber,
  IsOptional,
  IsString,
  Max,
  Min,
  MinLength,
} from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { BooleanEnum } from 'src/utils/enums/enum';

/**
 * UpdateProfileDto - Data Transfer Object for comprehensive user profile updates
 *
 * This DTO handles updating user profile information with extensive optional fields
 * covering personal details, preferences, and account settings. All fields are optional
 * to allow partial updates without requiring all profile data.
 *
 * @example
 * // Update basic profile information
 * {
 *   "name": "John Doe Updated",
 *   "mobile": "+12345678901",
 *   "country": "United States"
 * }
 *
 * @example
 * // Update user preferences
 * {
 *   "home_styles": "modern,minimalist",
 *   "favourite_colors": "blue,green",
 *   "languages": "english,spanish"
 * }
 *
 * @example
 * // Deactivate account
 * {
 *   "is_active": 0
 * }
 *
 * @example
 * // Usage in controller
 * @Patch('profile')
 * updateProfile(
 *   @Body() updateProfileDto: UpdateProfileDto,
 *   @Request() req
 * ) {
 *   return this.userService.updateProfile(req.user.id, updateProfileDto);
 * }
 */
export class UpdateProfileDto {
  /**
   * User's display name
   *
   * The full name or display name for the user profile.
   * Should be validated for length and potentially sanitized.
   *
   * @optional Fields can be omitted in partial updates
   * @example "John Doe"
   */
  @IsString()
  @IsNotEmpty()
  @ApiProperty({
    description: 'User display name',
    example: 'John Doe',
    required: false,
  })
  name?: string;

  /**
   * Account activation status
   *
   * Controls whether the user account is active or deactivated.
   * Typically used for soft deletion or temporary deactivation.
   *
   * Values from BooleanEnum:
   * - 1: Active (enabled)
   * - 0: Inactive (disabled)
   *
   * @note Requires appropriate permissions to modify
   * @example 1
   */
  @IsEnum(BooleanEnum)
  @IsNotEmpty()
  @ApiProperty({
    description: 'Account activation status',
    enum: BooleanEnum,
    example: BooleanEnum.TRUE,
    required: false,
  })
  is_active?: BooleanEnum;

  /**
   * Profile avatar/photo URL
   *
   * URL or path to the user's profile picture.
   * Typically stored in cloud storage (S3, Cloudinary, etc.) or CDN.
   *
   * @note Consider adding validation for URL format or file type
   * @example "https://cdn.example.com/avatars/user123.jpg"
   * @example "/uploads/avatars/avatar_12345.jpg"
   */
  @IsOptional()
  @ApiProperty({
    description: 'Profile avatar URL or path',
    example: 'https://cdn.example.com/avatars/user123.jpg',
    required: false,
  })
  avatar?: string;

  /**
   * Mobile phone number
   *
   * User's contact phone number for SMS, 2FA, and notifications.
   * Should follow international format with country code.
   *
   * @note Consider adding specific phone number validation
   * @example "+12345678901"
   */
  @IsString()
  @IsOptional()
  @ApiProperty({
    description: 'Mobile phone number',
    example: '+12345678901',
    required: false,
  })
  mobile?: string;

  /**
   * Email address
   *
   * Primary contact email. If changed, typically requires verification.
   *
   * Security considerations:
   * - Should trigger email verification when changed
   * - Should check for uniqueness in database
   * - Consider rate limiting email changes
   *
   * @example "john.doe@example.com"
   */
  @IsEmail()
  @IsOptional()
  @ApiProperty({
    description: 'Email address (requires verification if changed)',
    example: 'john.doe@example.com',
    required: false,
  })
  email?: string;

  /**
   * Country of residence
   *
   * User's country for localization, content filtering, and compliance.
   *
   * @note Consider using ISO country codes for standardization
   * @example "United States"
   * @example "US"
   */
  @IsOptional()
  @ApiProperty({
    description: 'Country of residence',
    example: 'United States',
    required: false,
  })
  country?: string;

  /**
   * Physical address
   *
   * Street address for shipping, billing, or contact purposes.
   *
   * @note Consider breaking into components (street, city, state, zip)
   * @example "123 Main St, Anytown, CA 12345"
   */
  @IsOptional()
  @ApiProperty({
    description: 'Physical address',
    example: '123 Main St, Anytown, CA 12345',
    required: false,
  })
  address?: string;

  /**
   * Date of birth
   *
   * User's birth date for age verification, personalization, and compliance.
   *
   * Security considerations:
   * - Validate minimum age requirements
   * - Consider privacy regulations (GDPR, COPPA)
   * - Store as Date object in database
   *
   * @example "1990-01-15"
   */
  @IsOptional()
  @ApiProperty({
    description: 'Date of birth',
    example: '1990-01-15',
    required: false,
  })
  dob?: Date;

  /**
   * Personal biography/about section
   *
   * User's self-description for profiles, introductions, and networking.
   *
   * @note Consider adding length limits and content moderation
   * @example "Software engineer with 10 years of experience..."
   */
  @IsOptional()
  @ApiProperty({
    description: 'Personal biography or about section',
    example: 'Software engineer with 10 years of experience...',
    required: false,
  })
  about?: string;

  /**
   * Profession/job title
   *
   * User's occupation or job role for networking and personalization.
   *
   * @example "Senior Software Engineer"
   */
  @IsOptional()
  @ApiProperty({
    description: 'Profession or job title',
    example: 'Senior Software Engineer',
    required: false,
  })
  job?: string;

  /**
   * Education background
   *
   * User's educational history, degrees, or institutions.
   *
   * @note Consider structured format or array of education entries
   * @example "BS Computer Science, University of Example"
   */
  @IsOptional()
  @ApiProperty({
    description: 'Education background',
    example: 'BS Computer Science, University of Example',
    required: false,
  })
  education?: string;

  /**
   * Spoken languages
   *
   * Languages the user speaks, typically comma-separated or array.
   *
   * @note Consider using ISO language codes for standardization
   * @example "english,spanish,french"
   */
  @IsOptional()
  @ApiProperty({
    description: 'Spoken languages',
    example: 'english,spanish,french',
    required: false,
  })
  languages?: string;

  /**
   * Home/style preferences
   *
   * User's preferences for home decor or style interests.
   * Application-specific field for personalization.
   *
   * @example "modern,minimalist,scandinavian"
   */
  @IsOptional()
  @ApiProperty({
    description: 'Home decor or style preferences',
    example: 'modern,minimalist,scandinavian',
    required: false,
  })
  home_styles?: string;

  /**
   * Favorite colors
   *
   * Color preferences for UI personalization or recommendations.
   *
   * @example "blue,green,navy"
   */
  @IsOptional()
  @ApiProperty({
    description: 'Favorite colors',
    example: 'blue,green,navy',
    required: false,
  })
  favourite_colors?: string;

  /**
   * Gender identity
   *
   * User's gender, typically represented as numeric code.
   *
   * @note Consider using string identifiers or enums for clarity
   * Common values: 1 (Male), 2 (Female), 3 (Non-binary), 4 (Prefer not to say)
   * @example 1
   */
  @IsOptional()
  @ApiProperty({
    description: 'Gender identity (numeric code)',
    example: 1,
    required: false,
  })
  gender?: number;

  /**
   * User role identifier
   *
   * Numeric role identifier determining permissions and access levels.
   *
   * Security considerations:
   * - Typically restricted to administrators only
   * - Should validate user has permission to change roles
   * - Audit role changes for security monitoring
   *
   * @note Range 2-14 suggests specific role hierarchy
   * @example 2 (Standard User), 10 (Admin), 14 (Super Admin)
   */
  @IsNumber()
  @IsOptional()
  @Min(2)
  @Max(14)
  @ApiProperty({
    description: 'User role identifier (2-14)',
    example: 2,
    minimum: 2,
    maximum: 14,
    required: false,
  })
  role?: number;
}

/**
 * UpdateAvatarDto - Specialized DTO for avatar/profile picture updates
 *
 * Simplified DTO focused specifically on updating user avatar and
 * optionally updating name and mobile in the same operation.
 *
 * @example
 * {
 *   "name": "John Doe Updated",
 *   "mobile": "+12345678901",
 *   "avatar": "https://cdn.example.com/new-avatar.jpg"
 * }
 */
export class UpdateAvatarDto {
  /**
   * User display name
   *
   * Optional name update alongside avatar change.
   *
   * @example "John Doe"
   */
  @IsString()
  @IsOptional()
  @ApiProperty({
    description: 'User display name',
    example: 'John Doe',
    required: false,
  })
  name?: string;

  /**
   * Mobile phone number
   *
   * Optional mobile update alongside avatar change.
   * Minimum length validation ensures basic phone number format.
   *
   * @note 10 characters may not be sufficient for all international numbers
   * @example "+12345678901"
   */
  @IsString()
  @IsOptional()
  @MinLength(10)
  @ApiProperty({
    description: 'Mobile phone number',
    example: '+12345678901',
    minLength: 10,
    required: false,
  })
  mobile?: string;

  /**
   * Avatar URL or path
   *
   * Required avatar field - the main purpose of this DTO.
   *
   * @example "https://cdn.example.com/avatars/user123.jpg"
   */
  @IsString()
  @IsNotEmpty()
  @ApiProperty({
    description: 'Avatar URL or path',
    example: 'https://cdn.example.com/avatars/user123.jpg',
    required: true,
  })
  avatar: string;
}
