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

// Coerce "true"/"false" strings into real booleans so the field works
// when the caller uses multipart/form-data (where every value arrives
// as a string). JSON bodies still pass through unchanged.
const toBoolean = ({ value }: { value: unknown }) => {
  if (typeof value === 'string') {
    if (value === 'true') return true;
    if (value === 'false') return false;
  }
  return value;
};

// Convert an optional numeric form field into a number. Multipart forms send
// empty selects as "", so we turn that into undefined for @IsOptional().
const toOptionalNumber = ({ value }: { value: unknown }) => {
  if (value === '' || value === undefined) return undefined;
  if (value === null) return null;
  return Number(value);
};

export class CreateStakeholderDto {
  @ApiProperty({ example: 'Example Stakeholder' })
  @IsString()
  @MinLength(1)
  @MaxLength(255)
  name!: string;

  @ApiProperty({
    example: 1,
    description: 'ID from the stakeholder_types table',
  })
  @Type(() => Number)
  @IsInt()
  @Min(1)
  stakeholderTypeId!: number;

  @ApiPropertyOptional({
    type: 'string',
    format: 'binary',
    description: 'Logo image file (multipart upload). Max 5 MB, images only.',
  })
  // Note: the file itself is read via @UploadedFile() in the controller.
  // This property exists only so Swagger renders a file picker in the
  // multipart/form-data form.
  logoFile?: unknown;

  @ApiPropertyOptional({
    example: 'Short stakeholder description.',
  })
  @IsOptional()
  @IsString()
  @MaxLength(5000)
  description?: string;

  @ApiPropertyOptional({
    example: 1,
    description: 'Optional ID of another stakeholder related to this row.',
  })
  @IsOptional()
  @Transform(toOptionalNumber)
  @IsInt()
  @Min(1)
  relatedStakeholderId?: number | null;

  @ApiPropertyOptional({ example: true, default: true })
  @IsOptional()
  @Transform(toBoolean)
  @IsBoolean()
  active?: boolean;
}
