<?php

declare(strict_types=1);

namespace Drupal\flowdrop_trigger\Plugin;

use Drupal\Component\Plugin\PluginBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\flowdrop_trigger\Enum\EventCategory;
use Drupal\flowdrop_trigger\Enum\TriggerExecutionMode;
use Drupal\flowdrop_trigger\FlowDropEventTypeInterface;

/**
 * Base class for FlowDrop Event Type plugins.
 *
 * Provides default implementations for common functionality.
 * Concrete event type plugins should extend this class.
 *
 * @internal This class is not part of the public API and may change without notice.
 */
abstract class FlowDropEventTypeBase extends PluginBase implements FlowDropEventTypeInterface {

  /**
   * {@inheritdoc}
   */
  public function getEventId(): string {
    return $this->getPluginId();
  }

  /**
   * {@inheritdoc}
   */
  public function getLabel(): string {
    $definition = $this->getPluginDefinition();
    $label = $definition["label"] ?? $this->getPluginId();
    return (string) $label;
  }

  /**
   * {@inheritdoc}
   */
  public function getDescription(): string {
    $definition = $this->getPluginDefinition();
    $description = $definition["description"] ?? "";
    return (string) $description;
  }

  /**
   * {@inheritdoc}
   */
  public function getCategory(): EventCategory {
    $definition = $this->getPluginDefinition();
    $category = $definition["category"] ?? "entity";
    if ($category instanceof EventCategory) {
      return $category;
    }
    return EventCategory::from($category);
  }

  /**
   * {@inheritdoc}
   */
  public function getDefaultOrchestrator(): string {
    $definition = $this->getPluginDefinition();
    return $definition["defaultOrchestrator"] ?? "flowdrop_runtime:asynchronous";
  }

  /**
   * {@inheritdoc}
   */
  public function getDefaultExecutionMode(): TriggerExecutionMode {
    $definition = $this->getPluginDefinition();
    $mode = $definition["defaultExecutionMode"] ?? "async";
    if ($mode instanceof TriggerExecutionMode) {
      return $mode;
    }
    return TriggerExecutionMode::from($mode);
  }

  /**
   * {@inheritdoc}
   */
  public function getSupportedEntityTypes(): array {
    $definition = $this->getPluginDefinition();
    return $definition["supportedEntityTypes"] ?? [];
  }

  /**
   * {@inheritdoc}
   */
  public function supportsEntityType(string $entityType): bool {
    $supportedTypes = $this->getSupportedEntityTypes();

    // Empty array means all entity types are supported.
    if (empty($supportedTypes)) {
      return TRUE;
    }

    return in_array($entityType, $supportedTypes, TRUE);
  }

  /**
   * {@inheritdoc}
   */
  public function getParameterSchema(): array {
    return [
      "type" => "object",
      "properties" => [
        "entity_types" => [
          "type" => "array",
          "title" => "Entity Types",
          "description" => "Entity types to trigger on (empty = all)",
          "items" => ["type" => "string"],
          "default" => [],
        ],
        "bundles" => [
          "type" => "array",
          "title" => "Bundles",
          "description" => "Bundles to trigger on (empty = all)",
          "items" => ["type" => "string"],
          "default" => [],
        ],
      ],
    ];
  }

  /**
   * Get base trigger data common to all event types.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity involved in the event.
   *
   * @return array
   *   Base trigger data.
   */
  protected function getBaseTriggerData(EntityInterface $entity): array {
    return [
      "event_type" => $this->getEventId(),
      "entity_type" => $entity->getEntityTypeId(),
      "entity_id" => $entity->id(),
      "bundle" => $entity->bundle(),
      "label" => $entity->label(),
      "uuid" => $entity->uuid(),
      "langcode" => $entity->language()->getId(),
      "timestamp" => time(),
    ];
  }

}
