import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { plainToInstance, Transform, Type } from 'class-transformer';
import {
  IsArray,
  IsIn,
  IsInt,
  IsOptional,
  IsString,
  MaxLength,
  Min,
  ValidateNested,
} from 'class-validator';

import { IssueResolveInputDto } from './issue-resolve-input.dto';
import { CREATE_MEETING_SUMMARY_STATUS_CODES } from './meeting-summary-status-code';
import type { CreateMeetingSummaryStatusCode } from './meeting-summary-status-code';
import { toIssueResolveArray } from './meeting-summary-transformers';

export function toIssueResolveDtoArray(
  value: unknown,
): IssueResolveInputDto[] | undefined {
  const parsed = toIssueResolveArray(value);

  if (!parsed || !Array.isArray(parsed)) {
    return undefined;
  }

  return plainToInstance(IssueResolveInputDto, parsed, {
    enableImplicitConversion: true,
  });
}

/**
 * Payload for creating (saving a draft of) a meeting summary. The summary is
 * always created from a meeting; the linked meeting request is derived from
 * that meeting on the server. The summary PDF is uploaded as the multipart
 * field `documentReference`.
 */
export class CreateMeetingSummaryDto {
  @ApiProperty({
    example: 1,
    description: 'ID of the meeting this summary belongs to.',
  })
  @Type(() => Number)
  @IsInt()
  @Min(1)
  meetingId!: number;

  @ApiPropertyOptional({
    example: 'summary.pdf',
    description: 'Summary document reference. An uploaded file overrides this.',
  })
  @IsOptional()
  @IsString()
  @MaxLength(255)
  documentReference?: string;

  @ApiPropertyOptional({ description: 'PSWG meeting reporter name.' })
  @IsOptional()
  @IsString()
  @MaxLength(255)
  pswgReporter?: string;

  @ApiPropertyOptional({ description: 'PSWG meeting reporter position.' })
  @IsOptional()
  @IsString()
  @MaxLength(255)
  pswgReporterPosition?: string;

  @ApiPropertyOptional({ description: 'PSWG representative name.' })
  @IsOptional()
  @IsString()
  @MaxLength(255)
  pswgRepresentative?: string;

  @ApiPropertyOptional({ description: 'PSWG representative position.' })
  @IsOptional()
  @IsString()
  @MaxLength(255)
  pswgRepresentativePosition?: string;

  @ApiPropertyOptional({ description: 'Ministry meeting reporter name.' })
  @IsOptional()
  @IsString()
  @MaxLength(255)
  ministryReporter?: string;

  @ApiPropertyOptional({ description: 'Ministry meeting reporter position.' })
  @IsOptional()
  @IsString()
  @MaxLength(255)
  ministryReporterPosition?: string;

  @ApiPropertyOptional({ description: 'Ministry representative name.' })
  @IsOptional()
  @IsString()
  @MaxLength(255)
  ministryRepresentative?: string;

  @ApiPropertyOptional({ description: 'Ministry representative position.' })
  @IsOptional()
  @IsString()
  @MaxLength(255)
  ministryRepresentativePosition?: string;

  @ApiPropertyOptional({
    enum: CREATE_MEETING_SUMMARY_STATUS_CODES,
    default: 'DRAFT',
    description: 'Save as DRAFT or send as SUBMITTED.',
  })
  @IsOptional()
  @IsIn(CREATE_MEETING_SUMMARY_STATUS_CODES)
  status?: CreateMeetingSummaryStatusCode;

  @ApiPropertyOptional({
    type: [IssueResolveInputDto],
    description: 'Per-issue resolutions for the meeting-request issues.',
  })
  @IsOptional()
  @Transform(({ value }) => toIssueResolveDtoArray(value))
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => IssueResolveInputDto)
  issueResolves?: IssueResolveInputDto[];
}
