<?php

declare(strict_types=1);

namespace Drupal\flowdrop_node_processor\Plugin\FlowDropNodeProcessor;

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

/**
 * Executor for If/Else Logic nodes.
 *
 * If/Else nodes provide simple conditional logic with text input,
 * match text, and operator fields for basic string comparisons.
 */
#[FlowDropNodeProcessor(
  id: "if_else",
  label: new \Drupal\Core\StringTranslation\TranslatableMarkup("If/Else"),
  description: "Simple boolean gateway with text input, match text, and operator",
  version: "1.0.0"
)]
class IfElse 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 {
    // If/Else nodes can accept any inputs or none.
    return ValidationResult::success();
  }

  /**
   * {@inheritdoc}
   */
  public function process(ParameterBagInterface $params): array {
    $matchText = $params->get("matchText", "");
    $operator = $params->get("operator", "equals");
    $caseSensitive = $params->get("caseSensitive", FALSE);
    $textInput = $params->get("data", "");

    $conditionResult = $this->evaluateCondition($textInput, $operator, $matchText, $caseSensitive);
    $activeBranch = $conditionResult ? "true" : "false";

    return [
      "active_branches" => $activeBranch,
      "input_value" => $textInput,
      "execution_metadata" => [
        "timestamp" => time(),
        "gateway_type" => "branch",
        "flow_control" => TRUE,
      ],
    ];
  }

  /**
   * Evaluate a condition.
   *
   * @param string $textInput
   *   The text input to evaluate.
   * @param string $operator
   *   The comparison operator.
   * @param string $matchText
   *   The text to match against.
   * @param bool $caseSensitive
   *   Whether the comparison is case sensitive.
   *
   * @return bool
   *   Whether the condition is met.
   */
  protected function evaluateCondition(string $textInput, string $operator, string $matchText, bool $caseSensitive): bool {
    $inputStr = $textInput;
    $matchStr = $matchText;

    if (!$caseSensitive) {
      $inputStr = strtolower($inputStr);
      $matchStr = strtolower($matchStr);
    }

    switch ($operator) {
      case "equals":
        return $inputStr === $matchStr;

      case "not_equals":
        return $inputStr !== $matchStr;

      case "contains":
        return strpos($inputStr, $matchStr) !== FALSE;

      case "starts_with":
        return strpos($inputStr, $matchStr) === 0;

      case "ends_with":
        return strpos($inputStr, $matchStr) === (strlen($inputStr) - strlen($matchStr));

      case "regex":
        return preg_match($matchStr, $inputStr) === 1;

      default:
        throw new \Exception("Unknown operator: {$operator}");
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getParameterSchema(): array {
    return [
      "type" => "object",
      "properties" => [
        "data" => [
          "type" => "mixed",
          "title" => "Input Data",
          "description" => "Data to be evaluated",
          "required" => FALSE,
        ],
        "matchText" => [
          "type" => "string",
          "title" => "Match Text",
          "description" => "The text to match against",
          "default" => "",
        ],
        "operator" => [
          "type" => "string",
          "title" => "Operator",
          "description" => "The comparison operator to use",
          "default" => "equals",
          "enum" => [
            "equals",
            "not_equals",
            "contains",
            "starts_with",
            "ends_with",
            "regex",
          ],
        ],
        "caseSensitive" => [
          "type" => "boolean",
          "title" => "Case Sensitive",
          "description" => "Whether string comparisons are case sensitive",
          "default" => FALSE,
        ],
        "branches" => [
          "type" => "array",
          "description" => "The active branches",
          "default" => [
            [
              "name" => "True",
              "value" => TRUE,
            ],
            [
              "name" => "False",
              "value" => FALSE,
            ],
          ],
          "items" => [
            "type" => "object",
            "properties" => [
              "name" => [
                "type" => "string",
                "description" => "The name of the branch",
              ],
              "value" => [
                "type" => "boolean",
                "description" => "The value of the branch",
              ],
            ],
            "description" => "The active branch",
          ],
        ],
      ],
    ];
  }

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

}
