<?php

declare(strict_types=1);

namespace Drupal\flowdrop_interrupt\Handler;

use Drupal\flowdrop_interrupt\DTO\ExecutionStamp;
use Drupal\flowdrop_interrupt\DTO\InterruptCreationData;
use Drupal\flowdrop_interrupt\Entity\FlowDropInterruptInterface;
use Drupal\flowdrop_interrupt\Enum\InterruptDirection;
use Drupal\flowdrop_interrupt\Message\InterruptMessageInterface;
use Drupal\flowdrop_interrupt\Message\InwardSignalMessage;
use Drupal\flowdrop_interrupt\Service\InterruptFactoryInterface;
use Drupal\flowdrop_interrupt\Service\InterruptMessageHandlerInterface;

/**
 * Persists an {@see InwardSignalMessage} and stamps signal-specific fields.
 *
 * The operator who initiated the signal is both assigned to and listed as
 * the initiator on the persisted entity. `targetPipelineId` is what the
 * poll subscriber reads to match a signal back to its pipeline.
 *
 * @internal
 */
final class InwardSignalMessageHandler implements InterruptMessageHandlerInterface {

  public function __construct(
    private readonly InterruptFactoryInterface $factory,
  ) {}

  /**
   * {@inheritdoc}
   */
  public static function supports(): string {
    return InwardSignalMessage::class;
  }

  /**
   * {@inheritdoc}
   */
  public function handle(InterruptMessageInterface $message, ExecutionStamp $stamp): FlowDropInterruptInterface {
    assert($message instanceof InwardSignalMessage);
    return $this->factory->create(new InterruptCreationData(
      type: $message->getType(),
      workflowId: $stamp->workflowId,
      nodeId: $stamp->nodeId,
      message: $message->getMessage(),
      assignedToUid: $message->initiatorUid,
      direction: InterruptDirection::Inward,
      targetPipelineId: $message->targetPipelineId,
      initiatorUid: $message->initiatorUid,
      reason: $message->reason,
    ));
  }

}
