<?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 Chat Output nodes.
 *
 * @internal This class is not part of the public API and may change without notice.
 */
#[FlowDropNodeProcessor(
  id: "chat_output",
  label: new \Drupal\Core\StringTranslation\TranslatableMarkup("Chat Output"),
  description: "Output chat messages in various formats",
  version: "1.0.0"
)]
class ChatOutput 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 {
    // Chat output can accept any inputs or none.
    return ValidationResult::success();
  }

  /**
   * {@inheritdoc}
   */
  public function process(ParameterBagInterface $params): array {
    // Get message content - check multiple sources.
    $message = $params->get("message", "");

    // If message is empty, try to get from first input port.
    if (empty($message)) {
      $inputData = $params->get("data");
      if (is_string($inputData)) {
        $message = $inputData;
      }
      elseif (is_array($inputData) && isset($inputData["message"])) {
        $message = $inputData["message"];
      }
      elseif (is_array($inputData) && !empty($inputData)) {
        // Use first non-empty value.
        $message = (string) reset($inputData);
      }
    }

    // Get format configuration.
    $format = $params->get("format", "text");
    if (!in_array($format, ["text", "markdown", "html"], TRUE)) {
      $format = "text";
    }

    // Get timestamp option.
    $timestamp = $params->get("showTimestamp", FALSE) ? time() : NULL;

    // Build output with consistent structure.
    $output = [
      "message" => $message,
      "format" => $format,
    ];

    // Include timestamp if enabled.
    if ($timestamp !== NULL) {
      $output["timestamp"] = $timestamp;
    }

    // Include metadata for message linking
    // (if available from execution context).
    $metadata = [];
    $nodeId = $params->get("__node_id__");
    if ($nodeId !== NULL) {
      $metadata["node_id"] = $nodeId;
    }

    $executionId = $params->get("__execution_id__");
    if ($executionId !== NULL) {
      $metadata["execution_id"] = $executionId;
    }

    if (!empty($metadata)) {
      $output["metadata"] = $metadata;
    }

    return $output;
  }

  /**
   * {@inheritdoc}
   */
  public function getParameterSchema(): array {
    return [
      "type" => "object",
      "properties" => [
        "message" => [
          "type" => "string",
          "title" => "Message",
          "description" => "Default chat message",
          "default" => "",
        ],
        "format" => [
          "type" => "string",
          "title" => "Format",
          "description" => "Message format (text, markdown, html)",
          "default" => "text",
        ],
        "showTimestamp" => [
          "type" => "boolean",
          "title" => "Show Timestamp",
          "description" => "Whether to include timestamp",
          "default" => FALSE,
        ],
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getOutputSchema(): array {
    return [
      "type" => "object",
      "properties" => [
        "message" => [
          "type" => "string",
          "description" => "The chat message content",
        ],
        "format" => [
          "type" => "string",
          "description" => "The message format (text, markdown, html)",
          "enum" => ["text", "markdown", "html"],
        ],
        "timestamp" => [
          "type" => "integer",
          "description" => "The message timestamp (if showTimestamp is enabled)",
        ],
        "metadata" => [
          "type" => "object",
          "description" => "Additional metadata for message linking",
          "properties" => [
            "node_id" => [
              "type" => "string",
              "description" => "The node ID that generated this message",
            ],
            "execution_id" => [
              "type" => "string",
              "description" => "The workflow execution ID",
            ],
          ],
        ],
      ],
    ];
  }

}
