<?php

declare(strict_types=1);

namespace Drupal\flowdrop_stategraph_test\Plugin\FlowDropNodeProcessor;

use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\flowdrop\Attribute\FlowDropNodeProcessor;
use Drupal\flowdrop\DTO\ParameterBagInterface;
use Drupal\flowdrop\DTO\ValidationResult;
use Drupal\flowdrop\Plugin\FlowDropNodeProcessor\AbstractFlowDropNodeProcessor;
use Drupal\flowdrop_orchestration\DTO\Snapshot\Message;
use Drupal\flowdrop_stategraph\Plugin\FlowDropNodeProcessor\StateAwareProcessorInterface;
use Drupal\flowdrop_stategraph\Plugin\FlowDropNodeProcessor\StateAwareProcessorTrait;

/**
 * Test processor that reports the graph state it was injected with.
 *
 * Exists to pin the StateAwareProcessorInterface contract: the StateGraph
 * orchestrator must call setGraphState() before process(), and state updates
 * returned by one node must be visible to the next state-aware node. The
 * appended message is a plain array on purpose — it covers the messages
 * channel normalization in GraphState::withUpdate().
 */
#[FlowDropNodeProcessor(
  id: "state_probe",
  label: new TranslatableMarkup("State Probe"),
  description: "Reports the injected graph state (test only)",
  version: "1.0.0"
)]
class StateProbe extends AbstractFlowDropNodeProcessor implements StateAwareProcessorInterface {

  use StateAwareProcessorTrait;

  /**
   * {@inheritdoc}
   */
  public function validateParams(array $params): ValidationResult {
    return ValidationResult::success();
  }

  /**
   * {@inheritdoc}
   */
  public function process(ParameterBagInterface $params): array {
    $state = $this->getGraphState();
    $messages = $state->messages ?? [];
    $lastMessage = end($messages);

    return [
      "has_state" => $state !== NULL,
      "thread_id" => $state->threadId ?? "",
      "message_count" => count($messages),
      "last_message" => $lastMessage instanceof Message ? $lastMessage->content : "",
      // Append as a plain array: processors that round-trip message data
      // through output serialization do exactly this.
      "state_update" => [
        "messages" => [["role" => "assistant", "content" => "probe saw " . count($messages) . " messages"]],
        "data" => ["probe_ran" => TRUE],
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getParameterSchema(): array {
    return [
      "type" => "object",
      "properties" => [
        "input" => [
          "type" => "string",
          "title" => "Input",
          "description" => "Optional upstream value, used only for wiring",
        ],
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getOutputSchema(): array {
    return [
      "type" => "object",
      "properties" => [
        "has_state" => [
          "type" => "boolean",
          "description" => "Whether a graph state was injected",
        ],
        "thread_id" => [
          "type" => "string",
          "description" => "The thread ID of the injected state",
        ],
        "message_count" => [
          "type" => "integer",
          "description" => "Number of messages in the injected state",
        ],
        "last_message" => [
          "type" => "string",
          "description" => "Content of the last message in the injected state",
        ],
      ],
    ];
  }

}
