<?php

declare(strict_types=1);

namespace Drupal\flowdrop_node_processor\Plugin\FlowDropNodeProcessor;

use Drupal\flowdrop\Attribute\FlowDropNodeProcessor;
use Drupal\flowdrop\Constants\ReservedName;
use Drupal\flowdrop\DTO\ParameterBagInterface;
use Drupal\flowdrop\DTO\ValidationResult;
use Drupal\flowdrop\Exception\InvalidNodeConfigurationException;
use Drupal\flowdrop\Plugin\FlowDropNodeProcessor\AbstractFlowDropNodeProcessor;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Executor for Switch Gateway.
 *
 * Switch provides conditional behavior based on expression matching.
 *
 * @internal This class is not part of the public API and may change without notice.
 */
#[FlowDropNodeProcessor(
  id: "switch_gateway",
  label: new \Drupal\Core\StringTranslation\TranslatableMarkup("Switch Gateway"),
  description: "A selection control flow mechanism that changes execution control based on the value of an expression.",
  version: "1.0.0"
)]
class SwitchGateway extends AbstractFlowDropNodeProcessor {

  /**
   * {@inheritdoc}
   */
  public static function create(
    ContainerInterface $container,
    array $configuration,
    $plugin_id,
    $plugin_definition,
  ): static {
    return new static($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public function validateParams(array $params): ValidationResult {
    // Switch nodes can accept any inputs or none.
    return ValidationResult::success();
  }

  /**
   * {@inheritdoc}
   */
  public function process(ParameterBagInterface $params): array {
    $expression = $params->get("expression");
    $defaultBranch = $params->get("default_branch");
    $branches = $params->get(ReservedName::BRANCHES);
    $activeBranch = NULL;

    foreach ($branches as $branch) {
      if ($branch["value"] === $expression) {
        $activeBranch = $branch["name"];
        break;
      }
    }

    if ($activeBranch === NULL) {
      $activeBranch = $defaultBranch;
    }

    if (empty($activeBranch)) {
      throw new InvalidNodeConfigurationException("No active branch found for expression: {$expression}");
    }

    return [
      ReservedName::ACTIVE_BRANCHES => $activeBranch,
      "input_value" => NULL,
      "execution_metadata" => [
        "timestamp" => time(),
        "gateway_type" => "branch",
        "flow_control" => TRUE,
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getParameterSchema(): array {
    return [
      "type" => "object",
      "properties" => [
        "expression" => [
          "type" => "string",
          "title" => "Expression",
          "description" => "The value to be evaluated",
          "required" => TRUE,
          "default" => "",
        ],
        "default_branch" => [
          "type" => "string",
          "title" => "Default Branch",
          "description" => "The value of the default branch",
          "default" => "default",
        ],
        ReservedName::BRANCHES => [
          "type" => "array",
          "items" => [
            "type" => "object",
            "properties" => [
              "name" => [
                "type" => "string",
                "description" => "The name of the branch",
              ],
              "value" => [
                "type" => "string",
                "description" => "The value of the branch",
              ],
            ],
          ],
          "default" => [
            [
              "name" => "Default",
              "value" => "default",
            ],
          ],
        ],
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getOutputSchema(): array {
    return [];
  }

}
