import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
  IsString,
  IsNotEmpty,
  IsOptional,
  MinLength,
  MaxLength,
} from 'class-validator';
import { IsNumberOrStringDto } from 'src/utils/common/numberOrStringDto';

/**
 * Commission Response Reason Update Data Transfer Object (DTO)
 *
 * This DTO is used for updating existing commission response reason records.
 * Commission response reasons are used to categorize and document responses
 * or explanations provided for commission calculations or queries.
 *
 * This DTO follows the same pattern as the generic UpdateDto, suggesting
 * a pattern of master data management with common fields (id, reason, active, modified_by_user).
 *
 * @example
 * // Updating a commission response reason:
 * {
 *   "id": 123,
 *   "reason": "Updated: Client adjustment process after review",
 *   "active": 1,
 *   "modified_by_user": 456
 * }
 *
 * @example
 * // Updating with string values:
 * {
 *   "id": "456",
 *   "reason": "Revised system calculation procedure",
 *   "active": "0",
 *   "modified_by_user": "789"
 * }
 *
 * @example
 * // Partial update without specifying modifier:
 * {
 *   "id": 789,
 *   "reason": "Updated standard adjustment documentation",
 *   "active": 1
 * }
 */
export class UpdateDto {
  /**
   * Identifier of the commission response reason to update.
   * Can be provided as either a number or numeric string.
   *
   * @type {number | string}
   * @required
   * @example 123 (number)
   * @example "456" (string)
   *
   * @isNotEmpty - Validation: Cannot be null, undefined, or empty
   *   Error message: "id should not be empty"
   *
   * @isNumberOrStringDto - Custom validation: Must be number or string
   *   First parameter (1): Default value if invalid (likely not used for ID)
   *   Second parameter ('Id'): Field name for error messages
   *   Validates and converts string numbers to actual numbers
   *
   * @note For IDs, the default value parameter (1) might not be appropriate.
   * Consider a custom validator that doesn't set defaults for IDs or validates
   * that ID is a positive integer.
   */
  @ApiProperty({
    description: 'ID of the commission response reason to update',
    example: 123,
    oneOf: [
      { type: 'number', example: 123 },
      { type: 'string', example: '456' },
    ],
  })
  @IsNotEmpty({ message: 'Commission response reason ID is required' })
  @IsNumberOrStringDto(1, 'Id')
  id: number | string;

  /**
   * Updated descriptive reason or explanation for the commission response.
   *
   * @type {string}
   * @required
   * @example "Updated: Client requested adjustment after review"
   * @example "Revised system calculation error procedure"
   *
   * @isNotEmpty - Validation: Cannot be empty string
   *   Error message: "reason should not be empty"
   *
   * @isString - Validation: Must be a string
   *   Error message: "reason must be a string"
   *
   * @apiProperty - Swagger documentation with example
   *
   * @note Consider adding length validation:
   *   @MinLength(3, { message: 'Reason must be at least 3 characters' })
   *   @MaxLength(500, { message: 'Reason cannot exceed 500 characters' })
   */
  @ApiProperty({
    description: 'Updated descriptive reason or explanation',
    example: 'Commission Response Reason is required',
    type: String,
    minLength: 3,
    maxLength: 500,
  })
  @IsNotEmpty({ message: 'Reason is required' })
  @IsString({ message: 'Reason must be a string' })
  @MinLength(3, { message: 'Reason must be at least 3 characters' })
  @MaxLength(500, { message: 'Reason cannot exceed 500 characters' })
  reason: string;

  /**
   * Updated activation status of the commission response reason.
   * Typically 1 for active, 0 for inactive. Supports both number and string input.
   *
   * @type {number | string}
   * @required
   * @example 1 (active)
   * @example 0 (inactive)
   * @example "1" (string representation)
   *
   * @isNotEmpty - Validation: Cannot be null, undefined, or empty
   *   Error message: "active should not be empty"
   *
   * @isNumberOrStringDto - Custom validation: Must be number or string
   *   First parameter (1): Default value if invalid
   *   Second parameter ('Status'): Field name for error messages
   *   Validates and converts string numbers to actual numbers
   */
  @ApiProperty({
    description: 'Updated activation status (1 = active, 0 = inactive)',
    example: 1,
    oneOf: [
      { type: 'number', example: 1 },
      { type: 'string', example: '1' },
    ],
    default: 1,
  })
  @IsNotEmpty({ message: 'Status is required' })
  @IsNumberOrStringDto(1, 'Status')
  active: number | string;

  /**
   * Optional user ID of the person modifying the commission response reason.
   * Used for audit trails to track who updated the record.
   *
   * @type {number | string}
   * @optional
   * @example 456
   * @example "789"
   *
   * @isOptional - Validation: Field is not required
   *
   * @isNumberOrStringDto - Custom validation: Must be number or string if provided
   *   First parameter (0): Default value if invalid
   *   Second parameter ('User ID'): Field name for error messages
   *
   * @apiPropertyOptional - Swagger documentation for optional field
   *
   * @note In practice, this is often populated from the authenticated user's session
   * rather than client input, for security and audit accuracy.
   */
  @ApiPropertyOptional({
    description:
      'ID of the user modifying the commission response reason (for audit trail)',
    example: 1,
    oneOf: [
      { type: 'number', example: 456 },
      { type: 'string', example: '789' },
    ],
  })
  @IsOptional()
  @IsNumberOrStringDto(0, 'User ID')
  modified_by_user?: number | string;
}
