import { IsString, MinLength, IsNotEmpty } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { MatchPassword } from '../../decorators/match-password.decorator';

/**
 * ChangePasswordRequestDto - Data Transfer Object for password change requests
 *
 * This DTO defines the structure and validation rules for password change requests.
 * It ensures that password change requests include the old password for verification,
 * a new password that meets security requirements, and confirmation of the new password.
 *
 * Features:
 * - Validates old password is provided
 * - Ensures new password meets minimum security requirements
 * - Confirms new password matches confirmation field
 * - Provides Swagger/OpenAPI documentation
 *
 * @example
 * // Valid request body
 * {
 *   "old_password": "CurrentPass123!",
 *   "password": "NewSecurePass456!",
 *   "confirm_password": "NewSecurePass456!"
 * }
 *
 * @example
 * // Usage in controller
 * @Post('change-password')
 * changePassword(@Body() changePasswordDto: ChangePasswordRequestDto) {
 *   return this.authService.changePassword(changePasswordDto);
 * }
 */
export class ChangePasswordRequestDto {
  /**
   * Current/old password for verification
   *
   * This field is required to ensure the user knows their current password
   * before allowing a password change, providing an additional security layer.
   *
   * Validation rules:
   * - Must be a string
   * - Minimum length of 8 characters
   * - Cannot be empty/null/undefined
   *
   * Security considerations:
   * - Should be hashed and compared against stored hash
   * - Should be checked for password reuse policies
   * - Should trigger re-authentication if multiple failed attempts
   *
   * @example "CurrentPass123!"
   */
  @IsString()
  @MinLength(8)
  @IsNotEmpty()
  @ApiProperty({
    description: 'Current/old password for verification',
    example: 'CurrentPass123!',
    minLength: 8,
    required: true,
  })
  old_password: string;

  /**
   * New password to set
   *
   * The password that will replace the old password if all validations pass.
   * Should meet security best practices including minimum length and complexity.
   *
   * Validation rules:
   * - Must be a string
   * - Minimum length of 8 characters (consider increasing to 12 for better security)
   * - Cannot be empty/null/undefined
   *
   * Security best practices:
   * - Consider adding complexity requirements (uppercase, lowercase, numbers, symbols)
   * - Check against password breach databases
   * - Enforce password history (can't reuse last N passwords)
   * - Implement rate limiting for password change attempts
   *
   * @example "NewSecurePass456!"
   */
  @IsString()
  @MinLength(8)
  @IsNotEmpty()
  @ApiProperty({
    description: 'New password to set (minimum 8 characters)',
    example: 'NewSecurePass456!',
    minLength: 8,
    required: true,
  })
  password: string;

  /**
   * Password confirmation field
   *
   * Confirms that the user correctly typed their new password twice,
   * reducing the chance of typos locking them out of their account.
   *
   * Validation rules:
   * - Must be a string
   * - Must match the value of the 'password' field exactly
   * - Cannot be empty/null/undefined
   *
   * The @MatchPassword decorator performs the equality check between
   * this field and the 'password' field, ensuring consistency.
   *
   * @example "NewSecurePass456!"
   */
  @IsString()
  @MatchPassword('password', {
    message: 'Confirm password must match password',
  })
  @IsNotEmpty()
  @ApiProperty({
    description: 'Confirmation of new password (must match password field)',
    example: 'NewSecurePass456!',
    required: true,
  })
  confirm_password: string;
}
