<?php

declare(strict_types=1);

namespace Drupal\flowdrop_node_processor\Plugin\FlowDropNodeProcessor;

use Drupal\Component\Serialization\Json;
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;

/**
 * Converts JSON string to structured data.
 *
 * Takes a JSON string as input and outputs a decoded PHP array/object.
 */
#[FlowDropNodeProcessor(
  id: "json_to_data",
  label: new \Drupal\Core\StringTranslation\TranslatableMarkup("JSON to Data"),
  description: "Convert JSON string to structured data (array/object)",
  version: "1.0.0"
)]
class JsonToData 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 {
    // Accept any input.
    return ValidationResult::success();
  }

  /**
   * {@inheritdoc}
   */
  public function process(ParameterBagInterface $params): array {
    $input = $params->get("json");
    $result = $this->convertToData($input);

    return [
      "data" => $result,
      "success" => $result !== NULL,
    ];
  }

  /**
   * Convert JSON string to structured data.
   *
   * @param mixed $input
   *   The input (JSON string or already-decoded data).
   *
   * @return mixed
   *   The decoded data.
   */
  private function convertToData(mixed $input): mixed {
    // If already an array/object, return as-is.
    if (is_array($input) || is_object($input)) {
      return $input;
    }

    // If not a string, return empty array.
    if (!is_string($input)) {
      return [];
    }

    // Decode JSON string.
    $result = JSON::decode($input, TRUE);

    if ($result === NULL && json_last_error() !== JSON_ERROR_NONE) {
      return [];
    }

    return $result;
  }

  /**
   * {@inheritdoc}
   */
  public function getParameterSchema(): array {
    return [
      "type" => "object",
      "properties" => [
        "json" => [
          "type" => "string",
          "title" => "JSON String",
          "description" => "The JSON string to decode into structured data",
          "default" => "",
        ],
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getOutputSchema(): array {
    return [
      "type" => "object",
      "properties" => [
        "data" => [
          "type" => "mixed",
          "description" => "The decoded structured data (array/object)",
        ],
        "success" => [
          "type" => "boolean",
          "description" => "Whether the conversion was successful",
        ],
      ],
    ];
  }

}
