import { IsIn, IsInt, IsNotEmpty } from 'class-validator';
import { Type } from 'class-transformer';
import { AssociationType, ByUserType } from 'src/utils/enums/enum';
import { ApiProperty } from '@nestjs/swagger';

/**
 * FetchByUsersDto - Data Transfer Object for filtering commission data by user involvement
 *
 * This DTO is used for filtering commission-related records based on which users
 * created or modified them, combined with the association type. It provides a
 * comprehensive filtering mechanism for audit trails and user-specific views.
 *
 * Business Context: Commission Audit & User Filtering
 * - Used to track which users created or updated commission records
 * - Essential for audit trails and accountability
 * - Combines user filtering with association type filtering
 * - Used in reporting and administrative views
 *
 * Validation Features:
 * - Validates both user type and association type enums
 * - Ensures proper data types and transformations
 * - Prevents invalid combinations of filter parameters
 * - Provides comprehensive API documentation
 */
export class FetchByUsersDto {
  /**
   * User Filter Type
   *
   * Specifies whether to filter by users who created or updated the commission records.
   * This determines which user relationship to query in the database.
   *
   * Business Significance:
   * - 'created_by': Filters records by the user who created them
   * - 'updated_by': Filters records by the user who last modified them
   *
   * Use Cases:
   * - Audit trails: Track who created or modified commission records
   * - User-specific views: Show only records created/updated by a specific user
   * - Performance metrics: Measure user activity in commission management
   *
   * Enum Values (from ByUserType):
   * - 'created_by': Filter by user who created the record
   * - 'updated_by': Filter by user who last updated the record
   *
   * @example ByUserType.CREATED_BY ('created_by')
   * @example ByUserType.UPDATED_BY ('updated_by')
   */
  @ApiProperty({
    enum: ByUserType,
    description: 'Filter by users who created or updated the records',
    example: ByUserType.CREATED_BY,
    enumName: 'ByUserType',
    examples: {
      'Created By': ByUserType.CREATED_BY,
      'Updated By': ByUserType.UPDATED_BY,
    },
  })
  @IsNotEmpty({ message: 'User filter type is required' })
  @IsIn(Object.values(ByUserType), {
    message: 'User filter type must be a valid enum value',
  })
  by: ByUserType;

  /**
   * Association Type
   *
   * The type of association/relationship for which user-filtered data should be retrieved.
   * This combines user filtering with association type filtering for precise data retrieval.
   *
   * Business Significance:
   * - Filters within specific commission workflows
   * - Ensures data security by limiting to appropriate association types
   * - Provides context-specific user activity views
   *
   * Combined Filtering Example:
   * - by: 'created_by', type: 1 → Users who created institute commission enquiries
   * - by: 'updated_by', type: 2 → Users who updated master agent commission enquiries
   * - by: 'created_by', type: 3 → Users who created sub-agent commission details
   *
   * Enum Values (from AssociationType):
   * - 1: INSTITUTE - Institute-based commission records
   * - 2: MASTER_AGENT - Master agent-based commission records
   * - 3: SUB_AGENT - Sub-agent-based commission records
   *
   * @example AssociationType.INSTITUTE (1)
   * @example AssociationType.MASTER_AGENT (2)
   */
  @ApiProperty({
    enum: AssociationType,
    example: AssociationType.INSTITUTE,
    description: 'Association type for filtering commission data',
    enumName: 'AssociationType',
    examples: {
      Institute: AssociationType.INSTITUTE,
      'Master Agent': AssociationType.MASTER_AGENT,
      'Sub Agent': AssociationType.SUB_AGENT,
    },
  })
  @IsNotEmpty({ message: 'Association type is required' })
  @Type(() => Number) // Transform to number if received as string
  @IsInt({ message: 'Association type must be an integer' })
  @IsIn(Object.values(AssociationType).filter((v) => typeof v === 'number'), {
    message: 'Association type must be a valid enum value',
  })
  type: AssociationType;
}
