import { Type } from 'class-transformer'
import {
  IsArray,
  IsBoolean,
  IsInt,
  IsOptional,
  IsString,
  Matches,
  Max,
  MaxLength,
  Min,
  ValidateNested,
} from 'class-validator'

const TZ = /^[A-Za-z]+\/[A-Za-z0-9_+-]+(\/[A-Za-z0-9_+-]+)?$/

export class MinuteIntervalDto {
  @IsInt() @Min(0) @Max(1440) startMinute!: number
  @IsInt() @Min(0) @Max(1440) endMinute!: number
}

export class WeeklyRuleDto {
  @IsInt() @Min(0) @Max(6) dayOfWeek!: number

  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => MinuteIntervalDto)
  intervals!: MinuteIntervalDto[]
}

export class DateOverrideDto {
  @Matches(/^\d{4}-\d{2}-\d{2}$/, { message: 'date must be YYYY-MM-DD' })
  date!: string

  @IsBoolean()
  isUnavailable!: boolean

  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => MinuteIntervalDto)
  intervals!: MinuteIntervalDto[]
}

export class CreateAvailabilityDto {
  @IsString()
  @MaxLength(120)
  name!: string

  @IsString()
  @MaxLength(64)
  @Matches(TZ, { message: 'timezone must be an IANA zone like Europe/Copenhagen' })
  timezone!: string

  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => WeeklyRuleDto)
  weeklyRules!: WeeklyRuleDto[]

  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => DateOverrideDto)
  dateOverrides?: DateOverrideDto[]
}

export class UpdateAvailabilityDto {
  @IsOptional() @IsString() @MaxLength(120) name?: string

  @IsOptional()
  @IsString()
  @MaxLength(64)
  @Matches(TZ, { message: 'timezone must be an IANA zone like Europe/Copenhagen' })
  timezone?: string

  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => WeeklyRuleDto)
  weeklyRules?: WeeklyRuleDto[]

  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => DateOverrideDto)
  dateOverrides?: DateOverrideDto[]
}
