import { ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsArray, IsIn, IsInt, IsOptional, IsString, Min } from 'class-validator';
import { SessionKpiFilter } from 'src/common/enum/session-kpi.enum';
import { ANALYTICS_LIST_DEFAULTS } from '../constants/analytics.constants';

const ANALYTICS_GENERAL_ATTENDEE_SORT_KEYS = ['joinedAt', 'durationSeconds', 'dropoffCount', 'rejoinCount'] as const;

/** Same three outcome values `SessionAttendeeFiltersDto.attendanceOutcome` accepts — general attendees have no registration, but still have dropoffCount/rejoinCount/joinedAt, so this outcome check is just as meaningful for them. */
const ATTENDANCE_OUTCOME_VALUES = [SessionKpiFilter.DROPPED, SessionKpiFilter.REJOINED, SessionKpiFilter.JOINED_LATE];

/**
 * The clickable-tile values that mean something for a general (no-registration) row.
 * GENERAL/ALL are excluded — the endpoint's server-forced `generalOnly` scope already covers them
 * (see `ZoomAnalyticsFacadeService.getGeneralAttendeesV1`), so there's nothing extra to pick.
 */
const GENERAL_ATTENDEE_KPI_FILTER_VALUES = [
  SessionKpiFilter.JOINED,
  SessionKpiFilter.NOT_JOINED,
  SessionKpiFilter.DROPPED,
  SessionKpiFilter.REJOINED,
  SessionKpiFilter.JOINED_LATE,
  SessionKpiFilter.KNOWN,
  SessionKpiFilter.UNKNOWN,
];

/**
 * v1 `GET .../general-attendees` query — a slimmed-down `AnalyticsAttendeeQueryV1Dto`: no
 * kpiCategory (this endpoint's whole point is "only the General rows," forced server-side in
 * `ZoomAnalyticsFacadeService.getGeneralAttendeesV1`, never client-chosen) and no rmContact/
 * systemAttendance/rmAttendance/coordinatorAttendance/finalAttendance (meaningless for a row with
 * no registration — no RM owner, no manual marks, and isSystemAttended is always true by
 * construction). `kpiFilter` IS exposed — the same clickable-tile mechanic as the main attendees
 * screen, layered on top of (not instead of) the server-forced general-only scope; omitted means
 * no extra narrowing beyond "general rows only." `fullName` isn't a sort option here (always null
 * for these rows) — `joinedAt` is the default instead.
 */
export class AnalyticsGeneralAttendeeQueryV1Dto {
  @ApiPropertyOptional({ default: ANALYTICS_LIST_DEFAULTS.PAGE })
  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(1)
  page: number = ANALYTICS_LIST_DEFAULTS.PAGE;

  @ApiPropertyOptional({ default: ANALYTICS_LIST_DEFAULTS.LIMIT })
  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(1)
  limit: number = ANALYTICS_LIST_DEFAULTS.LIMIT;

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

  @ApiPropertyOptional({
    enum: ATTENDANCE_OUTCOME_VALUES,
    isArray: true,
    description: 'Checkbox multi-select (OR\'d together), e.g. ["dropped","rejoined"]',
  })
  @IsOptional()
  @IsArray()
  @IsIn(ATTENDANCE_OUTCOME_VALUES, { each: true })
  attendanceOutcome?: SessionKpiFilter[];

  @ApiPropertyOptional({
    enum: GENERAL_ATTENDEE_KPI_FILTER_VALUES,
    description: 'Clicking a KPI tile re-issues the query with its filter, narrowing the general-attendee rows to exactly the ones behind that count.',
  })
  @IsOptional()
  @IsIn(GENERAL_ATTENDEE_KPI_FILTER_VALUES)
  kpiFilter?: SessionKpiFilter;

  @ApiPropertyOptional({ enum: ANALYTICS_GENERAL_ATTENDEE_SORT_KEYS, default: 'joinedAt' })
  @IsOptional()
  @IsIn(ANALYTICS_GENERAL_ATTENDEE_SORT_KEYS)
  sortKey: (typeof ANALYTICS_GENERAL_ATTENDEE_SORT_KEYS)[number] = 'joinedAt';

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