<?php

declare(strict_types=1);

namespace Drupal\flowdrop_trigger\Plugin\FlowDropNodeProcessor;

use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\flowdrop\Attribute\FlowDropNodeProcessor;
use Drupal\flowdrop\DTO\ConfigEdit\ConfigEdit;
use Drupal\flowdrop\DTO\ConfigEdit\ConfigEditApiEndpoints;
use Drupal\flowdrop\DTO\ConfigEdit\DynamicSchemaEndpoint;
use Drupal\flowdrop\DTO\ConfigEdit\ExternalEditLink;
use Drupal\flowdrop\Plugin\FlowDropNodeProcessor\ConfigEditProviderInterface;

/**
 * Entity trigger node processor for entity lifecycle events.
 *
 * This processor is specifically designed for entity-related events such as
 * entity insert, update, delete, and presave operations. It provides a
 * dedicated trigger type in the workflow editor for entity lifecycle events.
 *
 * When an entity trigger node is dropped in the editor, a FlowDropTriggerConfig
 * entity is created via the API. The node stores only a reference to the
 * entity via trigger_config_id.
 *
 * Actual trigger configuration (event type, entity type, bundle conditions,
 * orchestrator settings) is loaded dynamically from the entity via the
 * trigger config API.
 *
 * Entity ID format: {workflow_id}__{node_id}
 *
 * Implements ConfigEditProviderInterface to provide dynamic configuration
 * editing capabilities via REST API and admin forms.
 *
 * @see \Drupal\flowdrop_trigger\Entity\FlowDropTriggerConfig
 * @see \Drupal\flowdrop_trigger\Controller\TriggerConfigApiController
 * @see \Drupal\flowdrop\Plugin\FlowDropNodeProcessor\ConfigEditProviderInterface
 */
#[FlowDropNodeProcessor(
  id: "entity_trigger",
  label: new TranslatableMarkup("Entity Trigger"),
  description: "Trigger workflow on entity events (insert, update, delete, presave)",
  version: "1.0.0"
)]
class EntityTrigger extends AbstractTrigger implements ConfigEditProviderInterface {

  /**
   * {@inheritdoc}
   *
   * Minimal schema - trigger config is managed via the configure endpoint
   * which accepts workflow and node IDs. No need to store trigger_config_id
   * in the node as it's derived from workflow_id and node_id.
   */
  public function getParameterSchema(): array {
    $baseSchema = parent::getParameterSchema();

    // Terminal node variant - triggers are always "start" nodes.
    $baseSchema["properties"]["variant"] = [
      "type" => "string",
      "title" => "Variant",
      "description" => "Terminal node variant (start for triggers)",
      "enum" => ["start"],
      "default" => "start",
      "format" => "hidden",
    ];
    return $baseSchema;
  }

  /**
   * {@inheritdoc}
   */
  public function getConfigEdit(): ConfigEdit {
    return new ConfigEdit(
      // Dynamic schema from REST endpoint.
      // Schema endpoint returns JSON Schema for trigger configuration.
      // For entity triggers, we filter event types by entity category.
      dynamicSchema: new DynamicSchemaEndpoint(
        url: "/api/flowdrop/triggers/schema",
        method: "GET",
        // Map URL variables to node data.
        parameterMapping: [
          "event_type" => "config.event_type",
        ],
        // Don't cache - schema varies by event_type.
        cacheSchema: FALSE,
        timeout: 10000,
      ),
      // External edit link - opens admin form in new tab.
      // Uses a single configure endpoint that redirects to add or edit form
      // based on whether the trigger config exists.
      externalEditLink: new ExternalEditLink(
        url: "/admin/flowdrop/triggers/configure?workflow={workflowId}&node={nodeId}&category=entity",
        label: "Configure Entity Trigger",
        icon: "mdi:database",
        description: "Open entity trigger configuration form in admin interface",
        // Map URL variables to node data.
        parameterMapping: [
          "workflowId" => "workflowId",
          "nodeId" => "id",
        ],
        openInNewTab: TRUE,
      ),
      // API endpoints for CRUD operations.
      api: new ConfigEditApiEndpoints(
        create: "/api/flowdrop/triggers",
        read: "/api/flowdrop/triggers/{trigger_config_id}",
        update: "/api/flowdrop/triggers/{trigger_config_id}",
        delete: "/api/flowdrop/triggers/{trigger_config_id}",
        custom: [
          "eventTypes" => "/api/flowdrop/triggers/event-types?category=entity",
        ],
      ),
      // Behavior options.
      // Prefer external link until JS library fully supports dynamic schema
      // forms.
      preferDynamicSchema: FALSE,
      showRefreshButton: TRUE,
      loadingMessage: "Loading entity trigger configuration...",
      errorMessage: "Failed to load entity trigger configuration",
    );
  }

  /**
   * {@inheritdoc}
   *
   * Defines the output schema for entity trigger data passed to downstream
   * nodes.
   */
  public function getOutputSchema(): array {
    return [
      "type" => "object",
      "title" => "Entity Trigger Data",
      "description" => "Entity event data from the trigger",
      "properties" => [
        "data" => [
          "type" => "object",
          "title" => "Output",
          "description" => "Complete trigger output containing entity event data",
          "properties" => [
            "event_type" => [
              "type" => "string",
              "description" => "The entity event that triggered this workflow (e.g., entity.insert, entity.update)",
            ],
            "entity_type" => [
              "type" => "string",
              "description" => "The entity type ID (e.g., node, taxonomy_term, media)",
            ],
            "entity_id" => [
              "type" => "string",
              "description" => "The entity ID",
            ],
            "bundle" => [
              "type" => "string",
              "description" => "The entity bundle (e.g., article, page, tags)",
            ],
            "entity" => [
              "type" => "object",
              "description" => "Complete serialized entity data including all fields",
            ],
            "original_entity" => [
              "type" => ["object", "null"],
              "description" => "Original entity state before update (for update/presave events)",
            ],
            "is_new" => [
              "type" => "boolean",
              "description" => "Whether the entity is new",
            ],
            "timestamp" => [
              "type" => "integer",
              "description" => "Unix timestamp when the event occurred",
            ],
            "trigger_config_id" => [
              "type" => "string",
              "description" => "The ID of the trigger configuration that fired",
            ],
            "trigger_node_id" => [
              "type" => "string",
              "description" => "The node ID of the trigger in the workflow",
            ],
          ],
        ],
      ],
    ];
  }

}
