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

/**
 * Commission Response Reason Create Data Transfer Object (DTO)
 *
 * This DTO is used for creating new 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 CreateDto, suggesting
 * a pattern of master data management with common fields (reason, active, by_user).
 *
 * @example
 * // Creating a new commission response reason:
 * {
 *   "reason": "Client requested adjustment after review",
 *   "active": 1,
 *   "by_user": 123
 * }
 *
 * @example
 * // Creating with string values:
 * {
 *   "reason": "System calculation error identified",
 *   "active": "1",
 *   "by_user": "456"
 * }
 *
 * @example
 * // Creating without specifying user:
 * {
 *   "reason": "Standard commission adjustment process",
 *   "active": 1
 * }
 */
export class CreateDto {
  /**
   * Descriptive reason or explanation for the commission response.
   * This is the primary human-readable content that explains why a
   * commission response was given or what it represents.
   *
   * @type {string}
   * @required
   * @example "Client requested adjustment after review"
   * @example "System calculation error identified"
   * @example "Standard commission adjustment process"
   *
   * @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:
      'Descriptive reason or explanation for the commission response',
    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;

  /**
   * 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
   *
   * @note The custom validator likely handles:
   *   - String "1" → number 1
   *   - String "0" → number 0
   *   - Number 1 → number 1
   *   - Invalid strings → default value (1)
   */
  @ApiProperty({
    description: '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 creator.
   * Used for audit trails to track who created the commission response reason.
   *
   * @type {number | string}
   * @optional
   * @example 123
   * @example "456"
   *
   * @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 creating the commission response reason (for audit trail)',
    example: 1,
    oneOf: [
      { type: 'number', example: 123 },
      { type: 'string', example: '456' },
    ],
  })
  @IsOptional()
  @IsNumberOrStringDto(0, 'User ID')
  by_user?: number | string;
}
