<?php

declare(strict_types=1);

namespace Drupal\Tests\flowdrop_workflow_executor\Unit\Plugin\FlowDropNodeProcessor;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\flowdrop\Plugin\FlowDropNodeProcessor\ConfigEditProviderInterface;
use Drupal\flowdrop_workflow\Service\WorkflowSchemaResolverInterface;
use Drupal\flowdrop_workflow_executor\Plugin\FlowDropNodeProcessor\WorkflowNode;
use Drupal\flowdrop_workflow_executor\Service\WorkflowExecutionServiceInterface;
use Drupal\Tests\UnitTestCase;
use Prophecy\PhpUnit\ProphecyTrait;

/**
 * Tests WorkflowNode's "Edit Workflow" external edit link.
 *
 * Each `flowdrop_workflow:<id>` derivative targets a fixed sub-workflow baked
 * into the plugin definition. getConfigEdit() must surface a link that opens
 * that exact workflow in the editor in a new tab.
 *
 * @coversDefaultClass \Drupal\flowdrop_workflow_executor\Plugin\FlowDropNodeProcessor\WorkflowNode
 * @group flowdrop_workflow_executor
 */
class WorkflowNodeConfigEditTest extends UnitTestCase {

  use ProphecyTrait;

  /**
   * Builds a WorkflowNode with the given plugin definition.
   *
   * @param array<string, mixed> $definition
   *   The derivative plugin definition.
   */
  private function makeNode(array $definition): WorkflowNode {
    return new WorkflowNode(
      [],
      'flowdrop_workflow:foo',
      $definition,
      $this->prophesize(EntityTypeManagerInterface::class)->reveal(),
      $this->prophesize(WorkflowExecutionServiceInterface::class)->reveal(),
      $this->prophesize(WorkflowSchemaResolverInterface::class)->reveal(),
    );
  }

  /**
   * The node opts into the config-edit provider contract.
   */
  public function testImplementsConfigEditProviderInterface(): void {
    $node = $this->makeNode(['workflow_id' => 'my_flow']);
    $this->assertInstanceOf(ConfigEditProviderInterface::class, $node);
  }

  /**
   * The link resolves to the target workflow's editor route, opening anew.
   */
  public function testEmitsEditWorkflowLinkForTargetWorkflow(): void {
    $configEdit = $this->makeNode(['workflow_id' => 'my_flow'])->getConfigEdit();

    $this->assertTrue($configEdit->hasExternalEditLink());
    $link = $configEdit->externalEditLink;
    $this->assertNotNull($link);
    $this->assertSame('/admin/flowdrop/workflows/my_flow/editor', $link->url);
    $this->assertSame('Edit Workflow', $link->label);
    $this->assertTrue($link->openInNewTab);
    // The target is fixed per derivative, so no runtime parameter mapping.
    $this->assertSame([], $link->parameterMapping);
  }

  /**
   * With no resolvable target the link is omitted rather than broken.
   */
  public function testOmitsLinkWhenWorkflowIdMissing(): void {
    $this->assertFalse($this->makeNode([])->getConfigEdit()->hasExternalEditLink());
    $this->assertFalse(
      $this->makeNode(['workflow_id' => ''])->getConfigEdit()->hasExternalEditLink()
    );
  }

}
