<?php

namespace Drupal\eb\Service;

/**
 * Interface for the consolidated discovery service.
 *
 * Provides discovery for field types, widgets, formatters, and entity types.
 */
interface DiscoveryServiceInterface {

  /**
   * Gets all available field types.
   *
   * @return array<string, array<string, mixed>>
   *   Array of field type definitions keyed by field type ID.
   */
  public function getAllFieldTypes(): array;

  /**
   * Gets a specific field type definition.
   *
   * @param string $fieldType
   *   The field type ID.
   *
   * @return array<string, mixed>|null
   *   The field type definition or NULL if not found.
   */
  public function getFieldTypeDefinition(string $fieldType): ?array;

  /**
   * Checks if a field type exists.
   *
   * @param string $fieldType
   *   The field type ID.
   *
   * @return bool
   *   TRUE if the field type exists.
   */
  public function fieldTypeExists(string $fieldType): bool;

  /**
   * Gets field types grouped by category.
   *
   * @return array<string, array<string, array<string, mixed>>>
   *   Field types grouped by category.
   */
  public function getFieldTypesByCategory(): array;

  /**
   * Gets the default widget for a field type.
   *
   * @param string $fieldType
   *   The field type ID.
   *
   * @return string|null
   *   The default widget ID or NULL if not defined.
   */
  public function getDefaultWidget(string $fieldType): ?string;

  /**
   * Gets the default formatter for a field type.
   *
   * @param string $fieldType
   *   The field type ID.
   *
   * @return string|null
   *   The default formatter ID or NULL if not defined.
   */
  public function getDefaultFormatter(string $fieldType): ?string;

  /**
   * Gets raw default settings for a field type from Drupal's field type class.
   *
   * Note: For UI form schemas, use eb_ui's FieldTypeFormSchemaBuilder instead.
   *
   * @param string $fieldType
   *   The field type ID.
   *
   * @return array<string, mixed>|null
   *   Array with 'storage' and 'config' raw default settings, or NULL.
   */
  public function getRawFieldTypeDefaults(string $fieldType): ?array;

  /**
   * Gets all available widgets.
   *
   * @return array<string, array<string, mixed>>
   *   Array of widget definitions keyed by widget ID.
   */
  public function getAllWidgets(): array;

  /**
   * Gets widgets compatible with a field type.
   *
   * @param string $fieldType
   *   The field type ID.
   *
   * @return array<string, array<string, mixed>>
   *   Compatible widget definitions.
   */
  public function getWidgetsForFieldType(string $fieldType): array;

  /**
   * Gets a specific widget definition.
   *
   * @param string $widget
   *   The widget ID.
   *
   * @return array<string, mixed>|null
   *   The widget definition or NULL if not found.
   */
  public function getWidgetDefinition(string $widget): ?array;

  /**
   * Checks if a widget exists.
   *
   * @param string $widget
   *   The widget ID.
   *
   * @return bool
   *   TRUE if the widget exists.
   */
  public function widgetExists(string $widget): bool;

  /**
   * Checks if a widget is compatible with a field type.
   *
   * @param string $widget
   *   The widget ID.
   * @param string $fieldType
   *   The field type ID.
   *
   * @return bool
   *   TRUE if compatible.
   */
  public function isWidgetCompatible(string $widget, string $fieldType): bool;

  /**
   * Gets all available formatters.
   *
   * @return array<string, array<string, mixed>>
   *   Array of formatter definitions keyed by formatter ID.
   */
  public function getAllFormatters(): array;

  /**
   * Gets formatters compatible with a field type.
   *
   * @param string $fieldType
   *   The field type ID.
   *
   * @return array<string, array<string, mixed>>
   *   Compatible formatter definitions.
   */
  public function getFormattersForFieldType(string $fieldType): array;

  /**
   * Gets a specific formatter definition.
   *
   * @param string $formatter
   *   The formatter ID.
   *
   * @return array<string, mixed>|null
   *   The formatter definition or NULL if not found.
   */
  public function getFormatterDefinition(string $formatter): ?array;

  /**
   * Checks if a formatter exists.
   *
   * @param string $formatter
   *   The formatter ID.
   *
   * @return bool
   *   TRUE if the formatter exists.
   */
  public function formatterExists(string $formatter): bool;

  /**
   * Checks if a formatter is compatible with a field type.
   *
   * @param string $formatter
   *   The formatter ID.
   * @param string $fieldType
   *   The field type ID.
   *
   * @return bool
   *   TRUE if compatible.
   */
  public function isFormatterCompatible(string $formatter, string $fieldType): bool;

  /**
   * Gets all entity types.
   *
   * @return array<string, array<string, mixed>>
   *   Array of entity type definitions keyed by entity type ID.
   */
  public function getAllEntityTypes(): array;

  /**
   * Gets fieldable entity types.
   *
   * @return array<string, array<string, mixed>>
   *   Fieldable entity type definitions.
   */
  public function getFieldableEntityTypes(): array;

  /**
   * Gets supported entity types based on configuration.
   *
   * Returns fieldable entity types filtered by the configured allowlist.
   * If no allowlist is configured, returns all fieldable entity types.
   *
   * @return array<string, array<string, mixed>>
   *   Supported entity type definitions.
   */
  public function getSupportedEntityTypes(): array;

  /**
   * Gets bundleable entity types.
   *
   * @return array<string, array<string, mixed>>
   *   Bundleable entity type definitions.
   */
  public function getBundleableEntityTypes(): array;

  /**
   * Gets bundles for an entity type.
   *
   * @param string $entityType
   *   The entity type ID.
   *
   * @return array<string, array<string, mixed>>
   *   Bundle definitions keyed by bundle ID.
   */
  public function getBundlesForEntityType(string $entityType): array;

  /**
   * Checks if an entity type exists.
   *
   * @param string $entityType
   *   The entity type ID.
   *
   * @return bool
   *   TRUE if the entity type exists.
   */
  public function entityTypeExists(string $entityType): bool;

  /**
   * Checks if a bundle exists for an entity type.
   *
   * @param string $entityType
   *   The entity type ID.
   * @param string $bundle
   *   The bundle ID.
   *
   * @return bool
   *   TRUE if the bundle exists.
   */
  public function bundleExists(string $entityType, string $bundle): bool;

  /**
   * Checks if an entity type is fieldable.
   *
   * @param string $entityType
   *   The entity type ID.
   *
   * @return bool
   *   TRUE if the entity type is fieldable.
   */
  public function isFieldable(string $entityType): bool;

  /**
   * Checks if an entity type is bundleable.
   *
   * @param string $entityType
   *   The entity type ID.
   *
   * @return bool
   *   TRUE if the entity type supports bundles.
   */
  public function isBundleable(string $entityType): bool;

  /**
   * Validates a field configuration.
   *
   * @param string $fieldType
   *   The field type ID.
   * @param string|null $widget
   *   Optional widget ID.
   * @param string|null $formatter
   *   Optional formatter ID.
   *
   * @return array<string, mixed>
   *   Validation result with 'valid', 'errors', 'warnings', 'suggestions'.
   */
  public function validateFieldConfiguration(
    string $fieldType,
    ?string $widget = NULL,
    ?string $formatter = NULL,
  ): array;

  /**
   * Gets complete field configuration with defaults.
   *
   * @param string $fieldType
   *   The field type ID.
   * @param string|null $widget
   *   Optional widget ID.
   * @param string|null $formatter
   *   Optional formatter ID.
   *
   * @return array<string, mixed>|null
   *   Configuration array or NULL if field type doesn't exist.
   */
  public function getCompleteFieldConfiguration(
    string $fieldType,
    ?string $widget = NULL,
    ?string $formatter = NULL,
  ): ?array;

  /**
   * Validates an entity bundle.
   *
   * @param string $entityType
   *   The entity type ID.
   * @param string $bundle
   *   The bundle ID.
   *
   * @return array<string, mixed>
   *   Validation result with 'valid' and 'errors'.
   */
  public function validateEntityBundle(string $entityType, string $bundle): array;

  /**
   * Clears all discovery caches.
   */
  public function clearCache(): void;

}
