<?php

declare(strict_types=1);

namespace Drupal\simple_interactive_maps;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use function assert;

/**
 * Provides a listing of interactive maps.
 */
final class InteractiveMapListBuilder extends ConfigEntityListBuilder {

  /**
   * Module configuration.
   */
  protected ImmutableConfig $moduleConfig;

  public function __construct(
    EntityTypeInterface $entity_type,
    // @phpstan-ignore drupal.entityStorageDirectInjection (Required by the EntityListBuilder::__construct() contract; storage can't be fetched at the call site since the parent constructor assigns it.)
    EntityStorageInterface $storage,
    protected ClippableContent $clippableContent,
    protected MapDefinitionPluginManager $mapPluginManager,
    ConfigFactoryInterface $configFactory,
  ) {
    parent::__construct($entity_type, $storage);

    $this->moduleConfig = $configFactory->get('simple_interactive_maps.settings');
  }

  /**
   * {@inheritDoc}
   */
  public function buildHeader(): array {
    $header['thumb'] = $this->t('Thumbnail');
    $header['label'] = $this->t('Label');
    $header['base'] = $this->t('Base map');

    if ($this->moduleConfig->get('show_shortcodes')) {
      $header['embed'] = $this->t('CKEditor4 short code');
    }

    return $header +

    parent::buildHeader();
  }

  /**
   * {@inheritDoc}
   */
  public function buildRow(EntityInterface $entity): array {
    \assert($entity instanceof InteractiveMapInterface);

    $plugin = $this->mapPluginManager->createInstance($entity->get('base_map'));
    $pluginDefinition = $plugin->getPluginDefinition();

    /** @var \Drupal\simple_interactive_maps\InteractiveMapInterface $entity */
    $row['thumb'] = [
      'data' => [
        '#attributes' => [
          'alt' => $entity->label(),
          'height' => '100px',
          'src' => Url::fromRoute('simple_interactive_maps.map_thumbnail', [
            'interactive_map' => $entity->id(),
          ])->toString(TRUE)->getGeneratedUrl(),
          'style' => 'max-height: 100px; min-height: 100px; min-width: 100px;',
          'width' => '100px',
        ],
        '#tag' => 'img',
        '#type' => 'html_tag',
      ],
    ];
    $row['label'] = $entity->label();
    $row['base'] = $pluginDefinition['label'];

    if ($this->moduleConfig->get('show_shortcodes')) {
      $row['embed'] = [
        'data' => $this->clippableContent->createClippableItem(
            $entity->getEmbedCode(),
            'simple_interactive_maps_embed_code'
        ),
      ];
    }

    return $row +

    parent::buildRow($entity);
  }

  /**
   * {@inheritDoc}
   */
  public function getDefaultOperations(EntityInterface $entity, ?CacheableMetadata $cacheability = NULL): array {
    $operations = parent::getDefaultOperations($entity, $cacheability);

    $operations['details'] = [
      'title' => $this->t('Edit Regions'),
      'url' => Url::fromRoute('simple_interactive_maps.map_regions_form', ['interactive_map' => $entity->id()]),
      'weight' => 10,
    ];

    $operations['groups'] = [
      'title' => $this->t('Edit Groups'),
      'url' => Url::fromRoute('simple_interactive_maps.map_groups_form', ['interactive_map' => $entity->id()]),
      'weight' => 20,
    ];

    $operations['preview'] = [
      'title' => $this->t('Preview'),
      'url' => Url::fromRoute('simple_interactive_maps.map_preview', ['interactive_map' => $entity->id()]),
      'weight' => 30,
    ];

    $operations['tools'] = [
      'title' => $this->t('Tools'),
      'url' => Url::fromRoute(
          'simple_interactive_maps.simple_interactive_maps_tools',
          ['interactive_map' => $entity->id()],
      ),
      'weight' => 40,
    ];

    return $operations;
  }

  /**
   * {@inheritDoc}
   */
  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
    $clippableContent = $container->get('simple_interactive_maps.clippable_content');
    assert($clippableContent instanceof ClippableContent);

    $mapPluginManager = $container->get('plugin.manager.map_definition');
    \assert($mapPluginManager instanceof MapDefinitionPluginManager);

    $configFactory = $container->get('config.factory');

    return new static($entity_type, $container->get('entity_type.manager')
      ->getStorage('interactive_map'), $clippableContent, $mapPluginManager, $configFactory);
  }

}
