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

export class CreateIssueGovernmentAgencyDto {
  @ApiProperty({ example: 1 })
  @Type(() => Number)
  @IsInt()
  @Min(1)
  stakeholderId!: number;

  @ApiProperty({
    example: 1,
    description: '1 = primary agency, 2 = second agency, etc.',
  })
  @Type(() => Number)
  @IsInt()
  @Min(1)
  agencyOrder!: number;
}

// In multipart/form-data the agencies arrive as a JSON string. We parse it and
// turn each item into a real CreateIssueGovernmentAgencyDto instance. Returning
// plain objects here would shadow @Type, so with the global whitelist enabled
// the nested fields would be rejected as "should not exist".
function parseGovernmentAgencies(value: unknown) {
  if (typeof value !== 'string') {
    return value;
  }

  try {
    const parsed: unknown = JSON.parse(value);

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

    return plainToInstance(CreateIssueGovernmentAgencyDto, parsed);
  } catch {
    return value;
  }
}

export class CreateWorkingGroupIssueDto {
  @ApiProperty({ example: 'Climate issue' })
  @IsString()
  @MinLength(1)
  @MaxLength(100)
  title!: string;

  @ApiProperty({
    example:
      'The private sector reported unclear weather forecast information.',
  })
  @IsString()
  @MinLength(1)
  description!: string;

  @ApiProperty({
    example:
      'The government should improve weather forecast information sharing.',
  })
  @IsString()
  @MinLength(1)
  recommendation!: string;

  @ApiProperty({ example: 1 })
  @Type(() => Number)
  @IsInt()
  @Min(1)
  issueStatusId!: number;

  @ApiPropertyOptional({
    example: 1,
    description: 'Optional. If empty, backend uses the default issue category.',
  })
  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(1)
  categoryId?: number;

  @ApiPropertyOptional({
    example: 1,
    description: 'Optional meeting request that this issue came from.',
  })
  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(1)
  meetingRequestId?: number;

  @ApiPropertyOptional({
    example: '/uploads/issues/example.pdf',
    description:
      'Optional existing attachment URL. Use attachmentFile for upload.',
  })
  @IsOptional()
  @IsString()
  @MaxLength(255)
  attachment?: string;

  @ApiProperty({
    type: [CreateIssueGovernmentAgencyDto],
    example: [
      { stakeholderId: 1, agencyOrder: 1 },
      { stakeholderId: 3, agencyOrder: 2 },
    ],
  })
  @Transform(({ value }) => parseGovernmentAgencies(value))
  @IsArray()
  @ArrayMinSize(1)
  @ValidateNested({ each: true })
  @Type(() => CreateIssueGovernmentAgencyDto)
  governmentAgencies!: CreateIssueGovernmentAgencyDto[];

  @ApiPropertyOptional({
    type: 'string',
    format: 'binary',
    description: 'Optional issue attachment file.',
  })
  @IsOptional()
  attachmentFile?: unknown;
}
