/**
 * Queue Bulk Email DTO
 *
 * Input to EmailQueueService.queueBulkEmail — a single logical batch of email
 * recipients that share a template, sender and subject. The service chunks the
 * recipients into one or more SQS messages (provider-side ZeptoMail /batch sends).
 */

import { IsArray, IsInt, IsObject, IsOptional, IsString, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';

class BulkEmailSender {
  @IsString()
  address: string;

  @IsString()
  name: string;
}

class BulkEmailRecipient {
  @IsString()
  emailAddress: string;

  @IsString()
  @IsOptional()
  name?: string;

  @IsObject()
  @IsOptional()
  templateData?: Record<string, any>;

  @IsInt()
  @IsOptional()
  registrationId?: number;
}

/**
 * A batch-level attachment: the same file goes to every recipient of the batch.
 *
 * S3-reference form only (`s3Key`), deliberately — a bulk message already carries up to
 * BULK_EMAIL_BATCH_SIZE recipients with their own merge data, so there is no room to also inline
 * file bytes under SQS's 256 KB limit. BulkEmailProcessor downloads each object just before the
 * provider call (see resolveQueuedAttachments).
 */
class BulkEmailAttachment {
  @IsString()
  name: string;

  @IsString()
  s3Key: string;

  @IsString()
  contentType: string;

  @IsString()
  @IsOptional()
  s3Bucket?: string;
}

export class QueueBulkEmailDto {
  @ValidateNested()
  @Type(() => BulkEmailSender)
  from: BulkEmailSender;

  @IsString()
  subject: string;

  @IsString()
  @IsOptional()
  templateKey?: string;

  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => BulkEmailRecipient)
  recipients: BulkEmailRecipient[];

  /**
   * Batch-level attachments, applied to every recipient. Repeated on each chunk message when the
   * batch is split, which stays cheap because these are references, not bytes.
   */
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => BulkEmailAttachment)
  @IsOptional()
  attachments?: BulkEmailAttachment[];

  /** hdb_communication_templates id recorded on each tracking row. */
  @IsInt()
  @IsOptional()
  templateId?: number | null;

  @IsInt()
  @IsOptional()
  createdBy?: number;

  @IsString()
  @IsOptional()
  correlationId?: string;

  @IsString()
  @IsOptional()
  userId?: string;

  @IsObject()
  @IsOptional()
  metadata?: Record<string, any>;
}
