<?php

declare(strict_types=1);

namespace Drupal\flowdrop_interrupt\DTO;

use Drupal\flowdrop_interrupt\Enum\InterruptDirection;
use Drupal\flowdrop_interrupt\Enum\InterruptType;

/**
 * Internal union DTO carrying everything `InterruptManager::create()` needs.
 *
 * Holds three different concerns mashed together for storage-layer use:
 *  - Node-supplied payload: type, message, schema, options, context,
 *    defaultValue, linkedInterruptId.
 *  - Orchestrator-stamped identity: workflowId, nodeId, pipelineId,
 *    sessionId, jobId, direction.
 *  - Behavioral hints: expiresIn, assignedToUid.
 *  - Inward-signal fields (only set by the InwardSignal handler):
 *    targetPipelineId, initiatorUid, reason.
 *
 * Application code should not construct this directly — use the
 * {@see \Drupal\flowdrop_interrupt\Service\InterruptMessageBusInterface}
 * with a concrete
 * {@see \Drupal\flowdrop_interrupt\Message\InterruptMessageInterface}
 * and an {@see ExecutionStamp} instead. The bus's per-shape handlers
 * know which fields belong to which concern and assemble this
 * DTO internally.
 *
 * @internal The shape and field set may change without notice.
 */
final class InterruptCreationData {

  /**
   * Constructs a new InterruptCreationData.
   *
   * @param \Drupal\flowdrop_interrupt\Enum\InterruptType $type
   *   The interrupt type.
   * @param string $workflowId
   *   The owning workflow identifier.
   * @param string $nodeId
   *   The node identifier within the workflow.
   * @param string $message
   *   Human-readable description of the interrupt.
   * @param array<string, mixed> $schema
   *   FlowDrop / JSON Schema for the expected response.
   * @param array<int, array{value: string, label: string, description?: string}> $options
   *   Options for choice-style HITL interrupts.
   * @param array<string, mixed> $context
   *   Opaque payload — never used as a lookup key.
   * @param mixed $defaultValue
   *   Optional pre-filled default value.
   * @param string|null $pipelineId
   *   Owning pipeline identifier, if any.
   * @param int|null $sessionId
   *   Owning session identifier, if any.
   * @param int|null $expiresIn
   *   Optional TTL in seconds.
   * @param int|null $scheduledAt
   *   Absolute timestamp at which a scheduled interrupt (e.g. Timer)
   *   becomes due for automatic resolution by the cron sweep.
   * @param int|null $assignedToUid
   *   Optional explicit assignee.
   * @param \Drupal\flowdrop_interrupt\Enum\InterruptDirection|null $direction
   *   The interrupt direction.
   * @param int|null $jobId
   *   Owning job identifier, if any.
   * @param string|null $linkedInterruptId
   *   UUID of an interrupt this one is gated on.
   * @param string|null $targetPipelineId
   *   The pipeline this signal targets (inward signals only).
   * @param int|null $initiatorUid
   *   The user who initiated this signal (inward signals only).
   * @param string|null $reason
   *   Optional human-readable reason (inward signals only).
   */
  public function __construct(
    public readonly InterruptType $type,
    public readonly string $workflowId,
    public readonly string $nodeId,
    public readonly string $message,
    public readonly array $schema = [],
    public readonly array $options = [],
    public readonly array $context = [],
    public readonly mixed $defaultValue = NULL,
    public readonly ?string $pipelineId = NULL,
    public readonly ?int $sessionId = NULL,
    public readonly ?int $expiresIn = NULL,
    public readonly ?int $scheduledAt = NULL,
    public readonly ?int $assignedToUid = NULL,
    public readonly ?InterruptDirection $direction = NULL,
    public readonly ?int $jobId = NULL,
    public readonly ?string $linkedInterruptId = NULL,
    public readonly ?string $targetPipelineId = NULL,
    public readonly ?int $initiatorUid = NULL,
    public readonly ?string $reason = NULL,
  ) {}

}
