import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsNotEmpty, IsOptional, IsString, IsEnum } from 'class-validator';

/**
 * Enumeration of supported login methods
 *
 * Defines the different ways a student can authenticate.
 * Uses string values ('1', '2', '3') for compatibility with legacy systems
 * or database enum representations.
 *
 * @enum
 * @example LoginBy.MOBILE // Login using mobile number (value: '1')
 * @example LoginBy.EMAIL  // Login using email address (value: '2')
 * @example LoginBy.UID    // Login using unique identifier (value: '3')
 */
export enum LoginBy {
  /** Login using mobile number with country code */
  MOBILE = '1',

  /** Login using email address */
  EMAIL = '2',

  /** Login using unique system identifier */
  UID = '3',
}

/**
 * StudentLoginDto - Data Transfer Object for student authentication
 *
 * This DTO handles student login requests with support for multiple
 * authentication methods. The required fields change based on the
 * selected login_by method, following a conditional validation pattern.
 *
 * Features:
 * - Multiple login methods (mobile, email, UID)
 * - Conditional field requirements based on login method
 * - Comprehensive validation with clear error messages
 * - OpenAPI/Swagger documentation
 * - ISO country code support for mobile login
 *
 * @example
 * // Login with mobile number
 * {
 *   "login_by": "1",
 *   "country_iso3_code": "IND",
 *   "mobile": "9876543210",
 *   "password": "Pass@123"
 * }
 *
 * @example
 * // Login with email
 * {
 *   "login_by": "2",
 *   "email": "student@example.com",
 *   "password": "Pass@123"
 * }
 *
 * @example
 * // Login with UID
 * {
 *   "login_by": "3",
 *   "uid": "UID12345",
 *   "password": "Pass@123"
 * }
 */
export class StudentLoginDto {
  /**
   * Login method identifier
   *
   * Determines which authentication method to use and which
   * additional fields are required.
   *
   * Values from LoginBy enum:
   * - '1': Mobile number login (requires country_iso3_code and mobile)
   * - '2': Email address login (requires email)
   * - '3': Unique ID login (requires uid)
   *
   * @required Always required
   * @example "1"
   * @example "2"
   * @example "3"
   */
  @ApiProperty({
    description: 'Login method: 1 = Mobile, 2 = Email, 3 = UID',
    enum: LoginBy,
    example: '1',
    required: true,
  })
  @IsEnum(LoginBy, {
    message: 'login_by must be 1 (Mobile), 2 (Email), or 3 (UID)',
  })
  login_by: LoginBy;

  /**
   * ISO 3-letter country code
   *
   * Required only when login_by is '1' (Mobile login).
   * Should follow ISO 3166-1 alpha-3 standard (3 letters).
   *
   * Common examples:
   * - 'IND': India
   * - 'USA': United States
   * - 'GBR': United Kingdom
   * - 'AUS': Australia
   *
   * @optional Required only for mobile login (login_by: '1')
   * @example "IND"
   * @example "USA"
   */
  @ApiPropertyOptional({
    description: 'ISO 3-letter country code (required if login_by is 1)',
    example: 'IND',
    required: false,
  })
  @IsOptional()
  @IsString()
  country_iso3_code?: string;

  /**
   * Mobile phone number
   *
   * Required only when login_by is '1' (Mobile login).
   * Should be the local phone number without country code.
   *
   * Format considerations:
   * - Typically 10 digits for many countries
   * - Should match the expected format for the country
   * - Consider adding pattern validation for specific countries
   *
   * @optional Required only for mobile login (login_by: '1')
   * @example "9876543210"
   * @example "5551234567"
   */
  @ApiPropertyOptional({
    description: 'Mobile number (required if login_by is 1)',
    example: '9876543210',
    required: false,
  })
  @IsOptional()
  @IsString()
  mobile?: string;

  /**
   * Email address
   *
   * Required only when login_by is '2' (Email login).
   * Should be a valid email format.
   *
   * Security considerations:
   * - Validate email format
   * - Consider case-insensitive comparison
   * - Never reveal if email exists in error messages
   *
   * @optional Required only for email login (login_by: '2')
   * @example "student@example.com"
   * @example "john.doe@university.edu"
   */
  @ApiPropertyOptional({
    description: 'Email address (required if login_by is 2)',
    example: 'student@example.com',
    required: false,
  })
  @IsOptional()
  @IsString()
  email?: string;

  /**
   * Unique identifier
   *
   * Required only when login_by is '3' (UID login).
   * Typically a system-generated identifier like student ID,
   * enrollment number, or custom unique identifier.
   *
   * @optional Required only for UID login (login_by: '3')
   * @example "UID12345"
   * @example "STU2024001"
   * @example "ENR2024ABC123"
   */
  @ApiPropertyOptional({
    description: 'UID (required if login_by is 3)',
    example: 'UID12345',
    required: false,
  })
  @IsOptional()
  @IsString()
  uid?: string;

  /**
   * Account password
   *
   * Required for all login methods.
   * Should be validated against securely hashed password in database.
   *
   * Security best practices:
   * - Minimum length validation (consider @MinLength(8))
   * - Complexity requirements
   * - Use constant-time comparison to prevent timing attacks
   * - Implement account lockout after multiple failed attempts
   *
   * @required Always required
   * @example "Pass@123"
   * @example "SecurePassword456!"
   */
  @ApiProperty({
    description: 'Password (required for all login types)',
    example: 'Pass@123',
    required: true,
  })
  @IsNotEmpty({ message: 'Password is required' })
  @IsString()
  password: string;
}
