import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
  IsString,
  IsNotEmpty,
  IsOptional,
  IsInt,
  IsEmail,
  IsDateString,
  IsBoolean,
  IsIn,
  IsEnum,
  Min,
  Max,
  MaxLength,
} from 'class-validator';
import { OnlineTypeEnum } from 'src/common/enum/online-type.enum';
import { SessionProviderType } from 'src/common/enum/session-provider.enum';
import { SessionLaunchMode } from 'src/common/enum/session-launch-mode.enum';
import { ZoomWebinarStatus } from 'src/common/enum/zoom-webinar-status.enum';

/**
 * Provider-neutral create payload. `provider` selects which provider runs (Zoom
 * today); `onlineType` selects the session type within that provider.
 */
export class CreateOnlineSessionDto {
  @ApiPropertyOptional({
    description: 'Online session provider. Defaults to zoom.',
    enum: SessionProviderType,
    default: SessionProviderType.ZOOM,
  })
  @IsOptional()
  @IsEnum(SessionProviderType)
  provider?: SessionProviderType;

  @ApiPropertyOptional({
    description: 'Session type: `webinar` (default) or `meeting`.',
    enum: [OnlineTypeEnum.WEBINAR, OnlineTypeEnum.MEETING],
    default: OnlineTypeEnum.WEBINAR,
  })
  @IsOptional()
  @IsIn([OnlineTypeEnum.WEBINAR, OnlineTypeEnum.MEETING])
  onlineType?: OnlineTypeEnum.WEBINAR | OnlineTypeEnum.MEETING;

  @ApiPropertyOptional({
    description:
      'Meetings only. When true, attendees join via per-user registrant links. When false, a single shared link + passcode is used. Ignored for webinars. Defaults to true.',
    default: true,
  })
  @IsOptional()
  @IsBoolean()
  requireRegistration?: boolean;

  @ApiPropertyOptional({
    description: 'Session title/topic; defaults to the program session name',
    example: 'Monthly Satsang',
  })
  @IsOptional()
  @IsString()
  @IsNotEmpty()
  @MaxLength(500)
  title?: string;

  @ApiPropertyOptional({ description: 'Host email under which the session is created' })
  @IsOptional()
  @IsEmail()
  hostEmail?: string;

  @ApiProperty({ description: 'Session start time (ISO 8601)', example: '2026-07-01T10:00:00Z' })
  @IsDateString()
  startAt: string;

  @ApiProperty({ description: 'Duration in minutes', example: 60 })
  @IsInt()
  @Min(1)
  duration: number;

  @ApiPropertyOptional({ description: 'Optional session password' })
  @IsOptional()
  @IsString()
  @MaxLength(100)
  password?: string;

  @ApiProperty({ description: 'Program session this belongs to (program_session.id)' })
  @IsInt()
  programSessionId: number;

  @ApiPropertyOptional({
    description:
      'Where attendees launch the session from: `sdk` (embedded Zoom Web SDK) or `zoomClient` (Zoom client/web). Defaults to `sdk`.',
    enum: SessionLaunchMode,
    default: SessionLaunchMode.SDK,
  })
  @IsOptional()
  @IsEnum(SessionLaunchMode)
  launchMode?: SessionLaunchMode;

  @ApiPropertyOptional({
    description:
      'Initial lifecycle status. Defaults to `draft`. Set to `internalTesting` to provision for team testing, or `published` to go live immediately. Webhooks still drive automatic transitions afterwards.',
    enum: ZoomWebinarStatus,
    default: ZoomWebinarStatus.DRAFT,
  })
  @IsOptional()
  @IsEnum(ZoomWebinarStatus)
  status?: ZoomWebinarStatus;

  @ApiPropertyOptional({
    description:
      'Minutes before the session start that the join link opens for attendees. Defaults to 15.',
    example: 30,
    minimum: 0,
    maximum: 1440,
  })
  @IsOptional()
  @IsInt()
  @Min(0)
  @Max(1440)
  joinOpensMinutesBefore?: number;

  @ApiPropertyOptional({
    description:
      'Minutes before the session start that the host/admin can start the session. Store-only; the frontend enables the Start action from that time.',
    example: 30,
    minimum: 0,
    maximum: 1440,
  })
  @IsOptional()
  @IsInt()
  @Min(0)
  @Max(1440)
  hostStartOpensMinutesBefore?: number;

  @ApiPropertyOptional({ description: 'Registration window open time (ISO 8601)' })
  @IsOptional()
  @IsDateString()
  registrationStartsAt?: string;

  @ApiPropertyOptional({ description: 'Registration window close time (ISO 8601)' })
  @IsOptional()
  @IsDateString()
  registrationEndsAt?: string;

  // Audit — populated from the authenticated user in the controller.
  @ApiPropertyOptional({ description: 'Creator user id (set from auth context)' })
  @IsOptional()
  @IsInt()
  createdBy?: number;

  @ApiPropertyOptional({ description: 'Updater user id (set from auth context)' })
  @IsOptional()
  @IsInt()
  updatedBy?: number;
}
