<?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\TimerInterruptMessage;
use Drupal\flowdrop_interrupt\Service\InterruptFactoryInterface;
use Drupal\flowdrop_interrupt\Service\InterruptMessageHandlerInterface;

/**
 * Persists a {@see TimerInterruptMessage} as a FlowDropInterrupt entity.
 *
 * Stamps the message's absolute fire-at timestamp onto `scheduled_at` and
 * deliberately sets NO expiry: `resolveInterrupt()` refuses to resolve an
 * expired interrupt, and a due timer is by definition past its fire time —
 * the sweep, not expiration, is a timer's lifecycle.
 *
 * @internal
 */
final class TimerInterruptMessageHandler implements InterruptMessageHandlerInterface {

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

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

  /**
   * {@inheritdoc}
   */
  public function handle(InterruptMessageInterface $message, ExecutionStamp $stamp): FlowDropInterruptInterface {
    assert($message instanceof TimerInterruptMessage);
    return $this->factory->create(new InterruptCreationData(
      type: $message->getType(),
      workflowId: $stamp->workflowId,
      nodeId: $stamp->nodeId,
      message: $message->getMessage(),
      context: $message->getContext(),
      pipelineId: $stamp->pipelineId,
      sessionId: $stamp->sessionId,
      scheduledAt: $message->fireAt,
      direction: InterruptDirection::Outward,
      jobId: $stamp->jobId,
    ));
  }

}
