<?php

declare(strict_types=1);

namespace Drupal\sobki_admin\Service;

use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\block_content\Plugin\Block\BlockContentBlock;
use Drupal\layout_builder\DefaultsSectionStorageInterface;
use Drupal\layout_builder\OverridesSectionStorageInterface;
use Drupal\layout_builder\Plugin\Block\InlineBlock;
use Drupal\layout_builder\SectionComponent;
use Drupal\layout_builder\SectionStorageInterface;

/**
 * A helper service that looks up additional information about layout sections.
 *
 * Hopefully we won't need this forever.
 *
 * @see https://www.drupal.org/project/drupal/issues/3279716
 */
class LayoutContextHelper implements LayoutContextHelperInterface {

  /**
   * Gets an array of context information (if available) for a section.
   *
   * @param \Drupal\layout_builder\SectionStorageInterface $section
   *   The section to look up info on.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   *   Should never happen.
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   *   Should never happen.
   *
   * @return string[]
   *   An array of additional context information.
   */
  protected static function getHostEntityInfo(SectionStorageInterface $section): array {
    $info = [];

    $storage_id = $section->getStorageId();
    if ($section instanceof DefaultsSectionStorageInterface) {
      $display = \Drupal::entityTypeManager()
        ->getStorage('entity_view_display')
        ->load($storage_id);
      if ($display instanceof EntityViewDisplayInterface) {
        $info['entity_type_id'] = $display->getTargetEntityTypeId();
        $info['bundle'] = $display->getTargetBundle();
      }
    }
    elseif ($section instanceof OverridesSectionStorageInterface) {
      [$entity_type_id, $id] = \explode('.', $storage_id);
      $info['entity_type_id'] = $entity_type_id;
      $entity = \Drupal::entityTypeManager()
        ->getStorage($entity_type_id)
        ->load($id);
      if ($entity) {
        $info['bundle'] = $entity->bundle();
      }
    }
    return $info;
  }

  /**
   * {@inheritdoc}
   */
  public static function getHostEntityTypeId(SectionStorageInterface $section): ?string {
    return static::getHostEntityInfo($section)['entity_type_id'] ?? NULL;
  }

  /**
   * {@inheritdoc}
   */
  public static function getHostEntityBundle(SectionStorageInterface $section): ?string {
    return static::getHostEntityInfo($section)['bundle'] ?? NULL;
  }

  /**
   * {@inheritdoc}
   */
  public static function getBlockType(SectionComponent $component): ?string {
    $block_type = NULL;
    $plugin = $component->getPlugin();
    if ($plugin instanceof InlineBlock) {
      $block_type = $plugin->getDerivativeId();
    }
    elseif ($plugin instanceof BlockContentBlock) {
      /** @var \Drupal\Core\Entity\EntityRepositoryInterface $entity_repo */
      $entity_repo = \Drupal::service('entity.repository');
      $uuid = \explode(':', $plugin->getPluginId())[1];
      $entity = $entity_repo->loadEntityByUuid('block_content', $uuid);
      if ($entity) {
        $block_type = $entity->bundle();
      }
    }
    else {
      $block_type = $plugin->getPluginId();
    }
    return $block_type;
  }

}
