import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsIn, IsInt, IsOptional, IsString, Min } from 'class-validator';

/**
 * Whitelisted sort keys for GET /online-session/eligible-registrations — kept in
 * sync with the repository's SORT_COLUMNS map and with `sortable` in
 * PROGRAM_ELIGIBLE_REGISTRATIONS_TABLE_HEADERS. `paymentStatus` is deliberately
 * excluded: it's a derived/formatted value (from a correlated subquery over the
 * latest payment record), not a plain sortable column.
 */
export const PROGRAM_ELIGIBLE_REGISTRATIONS_SORT_KEYS = [
  'registrationSeqNumber',
  'fullName',
  'gender',
  'mobile',
  'email',
  'activationStatus',
  'rmContact',
  'city',
] as const;

/** Query for a program's seat-allocated registrant list (no session context). */
export class ListProgramEligibleRegistrationsDto {
  @ApiProperty({ description: 'Program whose seat-allocated registrants to list.', minimum: 1 })
  @Type(() => Number)
  @IsInt()
  @Min(1)
  programId: number;

  @ApiPropertyOptional({ description: 'Offset for pagination.', default: 0, minimum: 0 })
  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(0)
  offset = 0;

  @ApiPropertyOptional({ default: 20 })
  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(1)
  limit = 20;

  @ApiPropertyOptional({ description: 'Filter by name / email / mobile' })
  @IsOptional()
  @IsString()
  search?: string;

  @ApiPropertyOptional({
    description: 'Field to sort by.',
    enum: PROGRAM_ELIGIBLE_REGISTRATIONS_SORT_KEYS,
    default: 'registrationSeqNumber',
  })
  @IsOptional()
  @IsIn(PROGRAM_ELIGIBLE_REGISTRATIONS_SORT_KEYS)
  sortKey: (typeof PROGRAM_ELIGIBLE_REGISTRATIONS_SORT_KEYS)[number] = 'registrationSeqNumber';

  @ApiPropertyOptional({ enum: ['ASC', 'DESC'], default: 'DESC' })
  @IsOptional()
  @IsIn(['ASC', 'DESC'])
  sortOrder: 'ASC' | 'DESC' = 'DESC';

  @ApiPropertyOptional({
    description:
      'JSON-encoded filter object, e.g. {"gender":"female","registrationMode":"self","age":"21-30","activationStatus":"active","paymentMode":"online","paymentStatus":"payment_completed","rmContact":"1234","userType":["Org"],"kpiCategory":"eligibility","kpiFilter":"active"}. Keys/values match the `filters` array in the response (gender: male|female; registrationMode: self|other; age: 0-20|21-30|31-50|51-65|>65; paymentMode/paymentStatus: online|offline, payment_completed|payment_pending|failed|no_payment; rmContact: the RM user\'s id, from the `filters` array\'s rmContact options — not their name; userType: the registrant\'s own account type — "Org" and/or "Seeker", OR\'d together; "Seeker" also includes registrations made on someone else\'s behalf, which have no user account of their own). `kpiCategory`/`kpiFilter` are the clickable-tile pair from the response\'s own `kpis` array (see `ProgramEligibleKpiTile`) — clicking a tile re-sends its own `kpiCategory`/`kpiFilter` here to narrow the table to the rows behind that count; must be passed together, or omitted entirely for no narrowing.',
    type: String,
  })
  @IsOptional()
  @IsString()
  filters?: string;
}
