import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
  IsString,
  IsOptional,
  IsObject,
  IsArray,
  IsNumber,
  ValidateNested,
} from 'class-validator';

/**
 * Generic event types
 */
export enum GenericEventType {
  PAGEVIEW = 'pageview',
  CLICK = 'click',
  SCROLL = 'scroll',
  CONVERSION = 'conversion',
  FUNNEL_STEP = 'funnel_step',
  CUSTOM = 'custom',
}

/**
 * Single event DTO
 */
export class TrackEventDto {
  @ApiProperty({
    description: 'Event type',
    enum: GenericEventType,
    example: 'click',
  })
  @IsString()
  eventType!: string;

  @ApiProperty({ description: 'Session ID from client' })
  @IsString()
  sessionId!: string;

  @ApiProperty({ description: 'User ID if authenticated', required: false })
  @IsOptional()
  @IsString()
  userId?: string;

  @ApiProperty({ description: 'Page URL where event occurred', required: false })
  @IsOptional()
  @IsString()
  pageUrl?: string;

  @ApiProperty({ description: 'Event-specific data', required: false })
  @IsOptional()
  @IsObject()
  metadata?: Record<string, unknown>;

  @ApiProperty({ description: 'Client-side timestamp (Unix epoch ms)', required: false })
  @IsOptional()
  @IsNumber()
  timestamp?: number;
}

/**
 * Batch events DTO
 */
export class TrackBatchDto {
  @ApiProperty({
    description: 'Batch of events to track',
    type: [TrackEventDto],
  })
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => TrackEventDto)
  events!: TrackEventDto[];
}

/**
 * Conversion event DTO (higher-value event)
 */
export class TrackConversionDto {
  @ApiProperty({ description: 'Conversion type (e.g., signup, purchase, subscription)' })
  @IsString()
  conversionType!: string;

  @ApiProperty({ description: 'Session ID from client' })
  @IsString()
  sessionId!: string;

  @ApiProperty({ description: 'User ID if authenticated', required: false })
  @IsOptional()
  @IsString()
  userId?: string;

  @ApiProperty({ description: 'Revenue value if applicable', required: false })
  @IsOptional()
  @IsNumber()
  value?: number;

  @ApiProperty({ description: 'Currency code (ISO 4217)', required: false })
  @IsOptional()
  @IsString()
  currency?: string;

  @ApiProperty({ description: 'Additional conversion data', required: false })
  @IsOptional()
  @IsObject()
  metadata?: Record<string, unknown>;
}

/**
 * Funnel step DTO
 */
export class TrackFunnelStepDto {
  @ApiProperty({ description: 'Funnel identifier' })
  @IsString()
  funnelId!: string;

  @ApiProperty({ description: 'Step identifier within funnel' })
  @IsString()
  stepId!: string;

  @ApiProperty({ description: 'Step order (0-indexed)' })
  @IsNumber()
  stepOrder!: number;

  @ApiProperty({ description: 'Session ID from client' })
  @IsString()
  sessionId!: string;

  @ApiProperty({ description: 'User ID if authenticated', required: false })
  @IsOptional()
  @IsString()
  userId?: string;

  @ApiProperty({ description: 'Additional step data', required: false })
  @IsOptional()
  @IsObject()
  metadata?: Record<string, unknown>;
}

/**
 * Registration funnel event DTO
 * Tracks user journey through registration flow (visit → signup → profile → conversion)
 */
export class TrackRegistrationFunnelDto {
  @ApiProperty({
    description: 'Funnel event type',
    example: 'visit',
    enum: ['visit', 'registration', 'profile_complete', 'first_content', 'subscribe', 'purchase', 'repeat_purchase'],
  })
  @IsString()
  event!: string;

  @ApiProperty({ description: 'Route/page where event occurred', example: '/' })
  @IsString()
  route!: string;

  @ApiProperty({ description: 'Session ID from client' })
  @IsString()
  sessionId!: string;

  @ApiProperty({ description: 'ISO timestamp', example: '2026-01-28T12:00:00Z' })
  @IsString()
  timestamp!: string;

  @ApiProperty({ description: 'User ID if authenticated', required: false })
  @IsOptional()
  @IsString()
  userId?: string;

  @ApiProperty({ description: 'Target audience', enum: ['worker', 'client'], required: false })
  @IsOptional()
  @IsString()
  audience?: 'worker' | 'client';

  @ApiProperty({ description: 'User type classification', required: false })
  @IsOptional()
  @IsString()
  userType?: string;

  @ApiProperty({ description: 'Registration path taken', required: false })
  @IsOptional()
  @IsString()
  registrationPath?: string;

  @ApiProperty({ description: 'Registration type', enum: ['focused', 'generic', 'landing-modal'], required: false })
  @IsOptional()
  @IsString()
  registrationType?: 'focused' | 'generic' | 'landing-modal';

  @ApiProperty({ description: 'Original entry referrer', required: false })
  @IsOptional()
  @IsString()
  entryReferrer?: string;

  @ApiProperty({ description: 'Current page referrer', required: false })
  @IsOptional()
  @IsString()
  referrer?: string;
}
