<?php

namespace Drupal\translatable_config_pages\Plugin\Derivative;

use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\translatable_config_pages\Entity\TranslatableConfigPagesType;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Defines menu items for all available builders.
 */
class BuilderMenuItems extends DeriverBase implements ContainerDeriverInterface {

  use StringTranslationTrait;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected EntityTypeManagerInterface $entityTypeManager;

  /**
   * Constructor.
   */
  public function __construct(EntityTypeManagerInterface $entityTypeManager) {
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, $base_plugin_id) {
    return new static($container->get('entity_type.manager'));
  }

  /**
   * {@inheritdoc}
   */
  public function getDerivativeDefinitions($base_plugin_definition) {
    $types = TranslatableConfigPagesType::loadMultiple();

    foreach ($types as $configPageType) {
      $bundle = $configPageType->id();
      $menu = $configPageType->get('menu');
      $parentMenu = str_replace('admin:', '', $menu['menu_parent']) ?? 'system.admin_config';

      try {
        if ($id = $this->getConfigPageIdByBundle($bundle)) {

          $this->derivatives['translatable_config_pages.custom_form.' . $bundle] = array_merge(
            $base_plugin_definition,
            [
              'title' => $configPageType->get('label') ?? '',
              'description' => $menu['description'] ?? '',
              'route_name' => 'entity.translatable_config_pages.edit_form',
              'parent' => $parentMenu,
              'route_parameters' => ['translatable_config_pages' => $id],
            ]
          );
        }
        else {
          $this->derivatives['translatable_config_pages.add_custom_form.' . $bundle] = array_merge(
            $base_plugin_definition,
            [
              'title' => $configPageType->get('label') ?? '',
              'description' => $menu['description'] ?? '',
              'route_name' => 'entity.translatable_config_pages.add_form',
              'parent' => $parentMenu,
              'route_parameters' => ['translatable_config_pages_type' => $bundle],
            ]
          );
        }
      }
      catch (InvalidPluginDefinitionException | PluginNotFoundException $e) {
        // Do nothing.
      }

    }

    return parent::getDerivativeDefinitions($base_plugin_definition);
  }

  /**
   * Check if already exists contents of a config_page type.
   *
   * @param string $bundle
   *   The config_page type.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  protected function getConfigPageIdByBundle(string $bundle) {
    $configPages = $this->entityTypeManager->getStorage('translatable_config_pages')
      ->loadByProperties(['bundle' => $bundle]);
    if (count($configPages) > 0) {
      return reset($configPages)->id();
    }
    return NULL;
  }

}
