<?php

declare(strict_types=1);

namespace Drupal\flowdrop_trigger\EventSubscriber;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\flowdrop_trigger\Entity\FlowDropTriggerConfig;
use Drupal\flowdrop_trigger\Service\TriggerManagerInterface;
use Drupal\flowdrop_workflow\Event\WorkflowDuplicatedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Clones a workflow's trigger configs when the workflow is duplicated.
 *
 * The duplicate keeps the source's node IDs but gets a new workflow ID, so
 * without this its trigger nodes would compute a trigger_config_id
 * ({newWorkflowId}__{nodeId}) that has no backing entity — the copied triggers
 * would be silently unconfigured. We re-key each source config to the new
 * workflow, copying the configuration verbatim.
 *
 * @internal This class is not part of the public API and may change without notice.
 */
final class WorkflowDuplicateSubscriber implements EventSubscriberInterface {

  public function __construct(
    private readonly EntityTypeManagerInterface $entityTypeManager,
    private readonly TriggerManagerInterface $triggerManager,
  ) {}

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    return [
      WorkflowDuplicatedEvent::class => 'onWorkflowDuplicated',
    ];
  }

  /**
   * Clones trigger configs from the source workflow onto the new copy.
   */
  public function onWorkflowDuplicated(WorkflowDuplicatedEvent $event): void {
    $sourceConfigs = $this->triggerManager->getTriggersForWorkflow($event->sourceWorkflowId);
    if ($sourceConfigs === []) {
      return;
    }

    $newWorkflowId = (string) $event->newWorkflow->id();
    $storage = $this->entityTypeManager->getStorage("flowdrop_trigger_config");

    foreach ($sourceConfigs as $sourceConfig) {
      $nodeId = $sourceConfig->getNodeId();
      $newId = FlowDropTriggerConfig::generateId($newWorkflowId, $nodeId);

      // Idempotent: don't clobber an existing config (e.g. re-dispatch).
      if ($storage->load($newId) !== NULL) {
        continue;
      }

      $storage->create([
        "id" => $newId,
        "label" => $sourceConfig->label(),
        "description" => $sourceConfig->getDescription(),
        "workflow_id" => $newWorkflowId,
        "node_id" => $nodeId,
        "event_type" => $sourceConfig->getEventType(),
        "conditions" => $sourceConfig->getConditions(),
        "orchestrator_settings" => $sourceConfig->getOrchestratorSettings(),
        "initial_data_mapping" => $sourceConfig->getInitialDataMapping(),
        "status" => $sourceConfig->status(),
        "weight" => $sourceConfig->getWeight(),
      ])->save();
    }
  }

}
