<?php

declare(strict_types=1);

namespace Drupal\eb\PluginInterfaces;

use Drupal\Component\Plugin\PluginInspectionInterface;

/**
 * Interface for Entity Builder Extension plugins.
 *
 * Extensions integrate contrib modules (field_group, pathauto, etc.) with
 * Entity Builder's definition-centric workflow:
 *
 * 1. YAML/UI → EbDefinition (stores extension's definitions)
 * 2. On Apply → buildOperations() converts definitions → operations
 * 3. Operations → Validate → Execute
 *
 * Required method: buildOperations()
 * Optional methods: getOperationDependencies(), detectChanges(),
 *                   checkDependencies(), extractConfig()
 *
 * @see \Drupal\eb\Attribute\EbExtension
 * @see \Drupal\eb\PluginBase\EbExtensionBase
 */
interface EbExtensionInterface extends PluginInspectionInterface {

  /**
   * Builds operations from definition data.
   *
   * This is the PRIMARY method extensions must implement. It converts
   * definition data (from EbDefinition entity) into operation
   * arrays for validation and execution.
   *
   * @param array<string, mixed> $data
   *   Full definition data array containing all definition keys such as
   *   bundle_definitions, field_definitions, field_group_definitions, etc.
   *
   * @return array<int, array<string, mixed>>
   *   Array of operation data arrays for this extension's domain.
   *   Each operation must contain 'operation' key with operation ID.
   *   Return empty array if no operations to contribute.
   */
  public function buildOperations(array $data): array;

  /**
   * Gets dependencies for an operation.
   *
   * Override to declare what entities an operation depends on.
   * Dependencies determine operation execution order via topological sort.
   *
   * @param array $operation
   *   Operation data array with 'operation' key and operation-specific data.
   * @param array $context
   *   Context with 'all_operations' containing all operations for reference.
   *
   * @return array
   *   Dependency keys (e.g., ['bundle:node:article', 'field:...']).
   */
  public function getOperationDependencies(array $operation, array $context): array;

  /**
   * Detects whether operation should create, update, or skip.
   *
   * Override to implement change detection for sync mode. Compares operation
   * data against current Drupal state to determine appropriate action.
   *
   * @param array $operation
   *   Operation data array.
   * @param array $context
   *   Context with metadata.
   *
   * @return string|null
   *   One of:
   *   - 'create_*': Create operation (e.g., 'create_field_group').
   *   - 'update_*': Update operation (e.g., 'update_field_group').
   *   - 'skip': Already exists and unchanged.
   *   - NULL: Defer to core change detection.
   */
  public function detectChanges(array $operation, array $context): ?string;

  /**
   * Checks if custom dependency types exist in Drupal.
   *
   * Override to verify extension-specific entities exist during dependency
   * resolution. Only needed if extension declares custom dependency types.
   *
   * @param array $dependencyKeys
   *   Dependency keys to check (e.g., ['field_group:node:...:group_content']).
   *
   * @return array
   *   Keyed array: dependency_key => exists (bool).
   *   Return empty array for keys this extension doesn't handle.
   */
  public function checkDependencies(array $dependencyKeys): array;

  /**
   * Checks if this extension applies to an operation.
   *
   * Used to route operations to the correct extension for dependency
   * resolution and change detection.
   *
   * @param array $operation
   *   Operation data array with 'operation' key.
   *
   * @return bool
   *   TRUE if this extension handles this operation type.
   */
  public function appliesTo(array $operation): bool;

  /**
   * Gets the YAML definition keys this extension handles.
   *
   * These keys are stored in EbDefinition and passed to
   * buildOperations(). Defined in the plugin attribute.
   *
   * @return array
   *   Array of YAML keys (e.g., ['field_group_definitions']).
   */
  public function getYamlKeys(): array;

  /**
   * Gets the operation types this extension provides.
   *
   * Used by appliesTo() to match operations. Defined in the plugin attribute.
   *
   * @return array
   *   Array of operation IDs (e.g., ['create_field_group', '...']).
   */
  public function getOperations(): array;

  /**
   * Extracts configuration from an existing Drupal bundle.
   *
   * Used by export/generate features to extract extension-specific
   * configuration from Drupal into definition format.
   *
   * @param string $entityTypeId
   *   The entity type ID (e.g., 'node', 'taxonomy_term').
   * @param string $bundle
   *   The bundle machine name (e.g., 'article', 'tags').
   *
   * @return array<string, mixed>
   *   Configuration data keyed by definition type (e.g.,
   *   ['field_group_definitions' => [...]]).
   *   Return empty array if no configuration to extract.
   */
  public function extractConfig(string $entityTypeId, string $bundle): array;

}
