import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import {
  IsDateString,
  IsEnum,
  IsNotEmpty,
  IsString,
  Matches,
  MaxLength,
} from 'class-validator';

import { ProgressReportMeetingSlot } from '@/generated/prisma/client';

// Times may arrive as "09:00" or "09:00:00" because the meeting form sends
// hours and minutes only.
export const MEETING_TIME_PATTERN = /^([01]\d|2[0-3]):[0-5]\d(:[0-5]\d)?$/;

function trimText(value: unknown) {
  return typeof value === 'string' ? value.trim() : value;
}

function upperCaseText(value: unknown) {
  return typeof value === 'string' ? value.trim().toUpperCase() : value;
}

export class CreateProgressReportMeetingDto {
  @ApiProperty({
    enum: ProgressReportMeetingSlot,
    description: 'Which of the two meeting slots this meeting fills.',
  })
  @Transform(({ value }) => upperCaseText(value))
  @IsEnum(ProgressReportMeetingSlot)
  slot!: ProgressReportMeetingSlot;

  @ApiProperty({ example: 'Semester 2 | 2025' })
  @Transform(({ value }) => trimText(value))
  @IsString()
  @IsNotEmpty()
  @MaxLength(100)
  title!: string;

  @ApiProperty({ example: '<p>Meeting description</p>' })
  @Transform(({ value }) => trimText(value))
  @IsString()
  @IsNotEmpty()
  description!: string;

  @ApiProperty({
    example: '2025-06-07',
    description: 'Meeting date in YYYY-MM-DD format.',
  })
  @IsString()
  @Matches(/^\d{4}-\d{2}-\d{2}$/)
  @IsDateString()
  meetingDate!: string;

  @ApiProperty({
    example: '09:00:00',
    description: 'Start time in 24-hour HH:mm or HH:mm:ss format.',
  })
  @IsString()
  @Matches(MEETING_TIME_PATTERN)
  startTime!: string;

  @ApiProperty({
    example: '11:00:00',
    description: 'End time in 24-hour HH:mm or HH:mm:ss format.',
  })
  @IsString()
  @Matches(MEETING_TIME_PATTERN)
  endTime!: string;

  @ApiProperty({ example: 'CDC-GPSF Office' })
  @Transform(({ value }) => trimText(value))
  @IsString()
  @IsNotEmpty()
  @MaxLength(255)
  location!: string;
}
