<?php

namespace Drupal\eb\Service;

use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\FieldConfigInterface;
use Drupal\field\FieldStorageConfigInterface;
use Psr\Log\LoggerInterface;

/**
 * Service for managing field storage and field configuration.
 *
 * Provides an abstraction layer over FieldStorageConfig and FieldConfig
 * to improve testability and follow the Dependency Inversion Principle (DIP).
 */
class FieldManagementService implements FieldManagementServiceInterface {

  /**
   * Constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
   *   The entity field manager.
   * @param \Psr\Log\LoggerInterface $logger
   *   The logger.
   */
  public function __construct(
    protected EntityTypeManagerInterface $entityTypeManager,
    protected EntityFieldManagerInterface $entityFieldManager,
    protected LoggerInterface $logger,
  ) {}

  /**
   * {@inheritdoc}
   */
  public function loadFieldStorage(string $entityType, string $fieldName): ?FieldStorageConfigInterface {
    $storage = FieldStorageConfig::loadByName($entityType, $fieldName);
    return $storage instanceof FieldStorageConfigInterface ? $storage : NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function createFieldStorage(array $config): FieldStorageConfigInterface {
    $fieldStorage = FieldStorageConfig::create($config);
    $fieldStorage->save();

    return $fieldStorage;
  }

  /**
   * {@inheritdoc}
   */
  public function deleteFieldStorage(FieldStorageConfigInterface $fieldStorage): void {
    $fieldStorage->delete();
  }

  /**
   * {@inheritdoc}
   */
  public function loadFieldConfig(string $entityType, string $bundle, string $fieldName): ?FieldConfig {
    $field = FieldConfig::loadByName($entityType, $bundle, $fieldName);
    return $field instanceof FieldConfig ? $field : NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function loadFieldConfigById(string $fieldConfigId): ?FieldConfig {
    $field = $this->entityTypeManager->getStorage('field_config')->load($fieldConfigId);
    return $field instanceof FieldConfig ? $field : NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function createFieldConfig(array $config): FieldConfig {
    $fieldConfig = FieldConfig::create($config);
    $fieldConfig->save();

    return $fieldConfig;
  }

  /**
   * {@inheritdoc}
   */
  public function deleteFieldConfig(FieldConfigInterface $fieldConfig): void {
    $fieldConfig->delete();
  }

  /**
   * {@inheritdoc}
   */
  public function loadFieldStorageById(string $storageConfigId): ?FieldStorageConfigInterface {
    $storage = $this->entityTypeManager
      ->getStorage('field_storage_config')
      ->load($storageConfigId);
    return $storage instanceof FieldStorageConfigInterface ? $storage : NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function fieldStorageExists(string $entityType, string $fieldName): bool {
    return $this->loadFieldStorage($entityType, $fieldName) !== NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function fieldConfigExists(string $entityType, string $bundle, string $fieldName): bool {
    return $this->loadFieldConfig($entityType, $bundle, $fieldName) !== NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getBundlesUsingField(string $entityType, string $fieldName): array {
    $fieldMap = $this->entityFieldManager->getFieldMap();
    return $fieldMap[$entityType][$fieldName]['bundles'] ?? [];
  }

  /**
   * {@inheritdoc}
   */
  public function clearCachedFieldDefinitions(): void {
    $this->entityFieldManager->clearCachedFieldDefinitions();
  }

}
