<?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 structured data to JSON string.
 *
 * Takes structured data (array/object) as input and outputs a JSON string.
 *
 * @internal This class is not part of the public API and may change without notice.
 */
#[FlowDropNodeProcessor(
  id: "data_to_json",
  label: new \Drupal\Core\StringTranslation\TranslatableMarkup("Data to JSON"),
  description: "Convert structured data (array/object) to JSON string",
  version: "1.0.0"
)]
class DataToJson 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("data");
    $result = $this->convertToString($input);

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

  /**
   * Convert input to JSON string.
   *
   * @param mixed $input
   *   The input data.
   *
   * @return string
   *   The JSON string.
   */
  private function convertToString(mixed $input): string {
    $result = Json::encode($input);
    if (json_last_error()) {
      // JSON encoding failed - return empty object.
      return "{}";
    }

    return $result;
  }

  /**
   * {@inheritdoc}
   */
  public function getParameterSchema(): array {
    return [
      "type" => "object",
      "properties" => [
        "data" => [
          "type" => "mixed",
          "title" => "Data",
          "description" => "The data to convert to JSON",
          "required" => TRUE,
        ],
      ],
    ];
  }

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

}
