import {
  ArrayMaxSize,
  IsArray,
  IsBoolean,
  IsEnum,
  IsHexColor,
  IsInt,
  IsMongoId,
  IsNotEmpty,
  IsOptional,
  IsString,
  Matches,
  Max,
  MaxLength,
  Min,
} from 'class-validator'
import type { EventTypeAssignment, LocationType } from '../../../schemas/event-type.schema.js'

const SLUG = /^[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?$/
const LOCATIONS: LocationType[] = ['jitsi', 'phone', 'in_person', 'custom']
const ASSIGNMENTS: EventTypeAssignment[] = ['single', 'round_robin']

export class CreateEventTypeDto {
  @IsString()
  @Matches(SLUG, { message: 'slug must be lowercase, 2-40 chars, hyphen-separated' })
  slug!: string

  @IsString()
  @IsNotEmpty({ message: 'title is required' })
  @MaxLength(140)
  title!: string

  @IsOptional()
  @IsString()
  @MaxLength(2000)
  description?: string

  @IsInt()
  @Min(1)
  @Max(1440)
  durationMinutes!: number

  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(240)
  slotIntervalMinutes?: number

  @IsOptional()
  @IsInt()
  @Min(0)
  @Max(720)
  bufferBeforeMinutes?: number

  @IsOptional()
  @IsInt()
  @Min(0)
  @Max(720)
  bufferAfterMinutes?: number

  @IsOptional()
  @IsInt()
  @Min(0)
  minimumNoticeMinutes?: number

  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(730)
  maximumDaysInFuture?: number

  @IsMongoId()
  availabilityScheduleId!: string

  @IsOptional()
  @IsEnum(LOCATIONS)
  locationType?: LocationType

  @IsOptional()
  @IsString()
  @MaxLength(500)
  locationDetails?: string

  @IsOptional()
  @IsHexColor()
  color?: string

  @IsOptional()
  @IsBoolean()
  ignoreAllDayEvents?: boolean

  @IsOptional()
  @IsEnum(ASSIGNMENTS)
  assignment?: EventTypeAssignment

  // Round-robin pool of host ids. Validated as mongo ids; capped to keep the
  // union free/busy fan-out bounded.
  @IsOptional()
  @IsArray()
  @ArrayMaxSize(50)
  @IsMongoId({ each: true })
  hostPool?: string[]
}

// All fields optional for PATCH. (Avoids a mapped-types dependency.)
export class UpdateEventTypeDto {
  @IsOptional() @IsString() @MaxLength(140) title?: string
  @IsOptional() @IsString() @MaxLength(2000) description?: string
  @IsOptional() @IsInt() @Min(1) @Max(1440) durationMinutes?: number
  @IsOptional() @IsInt() @Min(1) @Max(240) slotIntervalMinutes?: number
  @IsOptional() @IsInt() @Min(0) @Max(720) bufferBeforeMinutes?: number
  @IsOptional() @IsInt() @Min(0) @Max(720) bufferAfterMinutes?: number
  @IsOptional() @IsInt() @Min(0) minimumNoticeMinutes?: number
  @IsOptional() @IsInt() @Min(1) @Max(730) maximumDaysInFuture?: number
  @IsOptional() @IsMongoId() availabilityScheduleId?: string
  @IsOptional() @IsEnum(LOCATIONS) locationType?: LocationType
  @IsOptional() @IsString() @MaxLength(500) locationDetails?: string
  @IsOptional() @IsHexColor() color?: string
  @IsOptional() @IsBoolean() ignoreAllDayEvents?: boolean
  @IsOptional() @IsEnum(ASSIGNMENTS) assignment?: EventTypeAssignment
  @IsOptional() @IsArray() @ArrayMaxSize(50) @IsMongoId({ each: true }) hostPool?: string[]
}
