import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
  IsString,
  IsNotEmpty,
  IsOptional,
  IsInt,
  IsEmail,
  IsEnum,
  IsIn,
  IsBoolean,
  IsArray,
  ArrayMinSize,
  ArrayUnique,
  ValidateNested,
  Min,
  Max,
  MaxLength,
} from 'class-validator';
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';
import { OnlineTypeEnum } from 'src/common/enum/online-type.enum';
import { SessionLinkModeEnum } from 'src/common/enum/session-link-mode.enum';

/** Recurrence rule for the shared webinar (optional — derived from session dates if omitted). */
export class SessionRecurrenceDto {
  @ApiProperty({ description: 'Recurrence frequency.', enum: ['daily', 'weekly', 'monthly'] })
  @IsIn(['daily', 'weekly', 'monthly'])
  frequency: 'daily' | 'weekly' | 'monthly';

  @ApiPropertyOptional({ description: 'Interval between recurrences (default 1).', example: 1 })
  @IsOptional()
  @IsInt()
  @Min(1)
  repeatInterval?: number;

  @ApiPropertyOptional({
    description: 'Weekly only: comma-separated Zoom weekdays (1=Sun … 7=Sat), e.g. "2,3,4" for Mon/Tue/Wed.',
    example: '2,3,4',
  })
  @IsOptional()
  @IsString()
  @MaxLength(20)
  weeklyDays?: string;

  // No end-times / end-date: the number of occurrences is always the number of
  // program sessions (each occurrence is pinned to a real session date/time).
}

/**
 * Provision ONE recurring webinar shared across several program sessions ("same
 * link"): one Zoom webinar, one join link per registrant valid for every session.
 */
export class CreateSharedOnlineSessionDto {
  @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`. Both support the shared model.',
    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 (one link per seeker, valid for all sessions). When false, a single shared link + passcode is used. Ignored for webinars. Defaults to true.',
    default: true,
  })
  @IsOptional()
  @IsBoolean()
  requireRegistration?: boolean;

  @ApiProperty({
    description:
      'Link type: `perSession` ("individual") provisions a distinct, non-recurring resource per session — each session gets its own join link. `shared` ("group") provisions ONE recurring resource across every session — every session shares the same join link.',
    enum: SessionLinkModeEnum,
  })
  @IsEnum(SessionLinkModeEnum)
  linkType: SessionLinkModeEnum;

  @ApiProperty({
    description: 'Program sessions to back with the one shared webinar/meeting (>= 1).',
    type: [Number],
    example: [101, 102, 103],
  })
  @IsArray()
  @ArrayMinSize(1)
  @ArrayUnique()
  @IsInt({ each: true })
  programSessionIds: number[];

  @ApiPropertyOptional({ description: 'Webinar title; defaults to the first session name.' })
  @IsOptional()
  @IsString()
  @IsNotEmpty()
  @MaxLength(500)
  title?: string;

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

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

  @ApiPropertyOptional({
    description: 'Where attendees launch from: `sdk` (default) or `zoomClient`.',
    enum: SessionLaunchMode,
    default: SessionLaunchMode.SDK,
  })
  @IsOptional()
  @IsEnum(SessionLaunchMode)
  launchMode?: SessionLaunchMode;

  @ApiPropertyOptional({ description: 'Initial lifecycle status. Defaults to draft.', enum: ZoomWebinarStatus })
  @IsOptional()
  @IsEnum(ZoomWebinarStatus)
  status?: ZoomWebinarStatus;

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

  @ApiPropertyOptional({ description: 'Minutes before start the host can start. Store-only.', minimum: 0, maximum: 1440 })
  @IsOptional()
  @IsInt()
  @Min(0)
  @Max(1440)
  hostStartOpensMinutesBefore?: number;

  @ApiPropertyOptional({ description: 'Recurrence rule; derived from session weekdays if omitted.', type: SessionRecurrenceDto })
  @IsOptional()
  @ValidateNested()
  @Type(() => SessionRecurrenceDto)
  recurrence?: SessionRecurrenceDto;

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