import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
  ArrayMinSize,
  ArrayUnique,
  IsArray,
  IsISO8601,
  IsInt,
  IsOptional,
  IsString,
  Min,
  ValidateNested,
} from 'class-validator';
import { CreateSurgeryDeviceDto } from './create-surgery-device.dto.js';
import { SurgeryMaterialDto } from './surgery-material.dto.js';

/**
 * 患者手术 DTO：支持首术与二次手术录入。
 */
export class CreatePatientSurgeryDto {
  @ApiProperty({
    description: '手术日期',
    example: '2026-03-19T08:00:00.000Z',
  })
  @IsISO8601({}, { message: 'surgeryDate 必须是合法 ISO 日期' })
  surgeryDate!: string;

  @ApiProperty({
    description: '手术名称',
    example: '脑室腹腔分流术',
  })
  @IsString({ message: 'surgeryName 必须是字符串' })
  surgeryName!: string;

  @ApiPropertyOptional({
    description: '术前测压，可为空',
    example: 22,
  })
  @IsOptional()
  @Type(() => Number)
  @IsInt({ message: 'preOpPressure 必须是整数' })
  preOpPressure?: number;

  @ApiProperty({
    description: '原发病',
    example: '梗阻性脑积水',
  })
  @IsString({ message: 'primaryDisease 必须是字符串' })
  primaryDisease!: string;

  @ApiProperty({
    description: '脑积水类型，多选',
    type: [String],
    example: ['交通性', '高压性'],
  })
  @IsArray({ message: 'hydrocephalusTypes 必须是数组' })
  @ArrayMinSize(1, { message: 'hydrocephalusTypes 至少选择 1 项' })
  @IsString({ each: true, message: 'hydrocephalusTypes 必须为字符串数组' })
  hydrocephalusTypes!: string[];

  @ApiPropertyOptional({
    description: '上次分流手术时间，可为空',
    example: '2024-08-01T00:00:00.000Z',
  })
  @IsOptional()
  @IsISO8601({}, { message: 'previousShuntSurgeryDate 必须是合法 ISO 日期' })
  previousShuntSurgeryDate?: string;

  @ApiPropertyOptional({
    description: '手术备注',
    example: '二次手术，弃用原右侧分流装置',
  })
  @IsOptional()
  @IsString({ message: 'notes 必须是字符串' })
  notes?: string;

  @ApiPropertyOptional({
    description: '术前 CT 影像/资料',
    type: [SurgeryMaterialDto],
  })
  @IsOptional()
  @IsArray({ message: 'preOpMaterials 必须是数组' })
  @ValidateNested({ each: true })
  @Type(() => SurgeryMaterialDto)
  preOpMaterials?: SurgeryMaterialDto[];

  @ApiProperty({
    description: '本次手术植入设备列表',
    type: [CreateSurgeryDeviceDto],
  })
  @IsArray({ message: 'devices 必须是数组' })
  @ArrayMinSize(1, { message: 'devices 至少录入 1 个设备' })
  @ValidateNested({ each: true })
  @Type(() => CreateSurgeryDeviceDto)
  devices!: CreateSurgeryDeviceDto[];

  @ApiPropertyOptional({
    description: '本次手术后需弃用的历史设备编号列表',
    type: [Number],
    example: [1],
  })
  @IsOptional()
  @IsArray({ message: 'abandonedDeviceIds 必须是数组' })
  @ArrayUnique({ message: 'abandonedDeviceIds 不能重复' })
  @Type(() => Number)
  @IsInt({ each: true, message: 'abandonedDeviceIds 必须为整数数组' })
  @Min(1, { each: true, message: 'abandonedDeviceIds 必须大于 0' })
  abandonedDeviceIds?: number[];
}
