<?php

/**
 * @file
 * Adds UI Patterns themes and UI Elements.
 */

declare(strict_types=1);

use Drupal\ui_patterns\Plugin\UiPatterns\Source\WysiwygWidget;

/**
 * Implements hook_element_info_alter().
 */
function ui_patterns_element_info_alter(array &$types) {
  if (isset($types['component'])) {
    array_unshift($types['component']['#pre_render'], 'ui_patterns.component_element_alter:alter');
    array_unshift($types['component']['#pre_render'], 'ui_patterns.component_element_builder:build');
  }
  $types['text_format']['#pre_render'][] = [WysiwygWidget::class, 'textFormat'];
}

/**
 * Prepare list of block plugins returned when using consumer 'ui_patterns'.
 *
 * @see \Drupal\ui_patterns\Plugin\UiPatterns\Source\BlockSource::listBlockDefinitions()
 *
 * Implements hook_plugin_filter_TYPE__CONSUMER_alter().
 */
function ui_patterns_plugin_filter_block__ui_patterns_alter(array &$definitions, array $extra) {
  // @todo Determine the 'inline_block' blocks should be allowed outside
  //   of layout_builder https://www.drupal.org/node/2979142.
  $definitions = array_filter($definitions, function ($definition) {
    return $definition['id'] !== 'inline_block';
  });
  // Remove blocks that are not useful within Layout Builder.
  unset($definitions['system_messages_block']);
  unset($definitions['help_block']);
  unset($definitions['local_tasks_block']);
  unset($definitions['local_actions_block']);
  // Remove blocks that are non-functional within Layout Builder.
  unset($definitions['system_main_block']);
  // @todo Restore the page title block in https://www.drupal.org/node/2938129.
  unset($definitions['page_title_block']);
  // Add a boolean marker '_ui_patterns_compatible' to all remaining definitions
  // Other modules can use the same hook to modify this value.
  // This allows to whitelist or blacklist blocks.
  $whitelisted_blocks = [
    "id" => ["search_form_block", "system_menu_block"],
    "provider" => ["views"],
  ];
  foreach ($definitions as $id => &$definition) {
    if (isset($definitions[$id]['_ui_patterns_compatible'])) {
      // When a block plugin already has 'ui_patterns_compatibilty'
      // It probably means it has been marked by another code.
      // Honor what the other code has done and do not override.
      continue;
    }
    $compatibilityFlag = TRUE;
    if (in_array($definition['provider'], $whitelisted_blocks["provider"]) ||
      in_array($definition["id"], $whitelisted_blocks["id"])) {
      // Those blacks are accepted.
    }
    elseif (isset($definition['class'])) {
      try {
        $class_name = $definition['class'];
        $reflector = new \ReflectionClass($class_name);
        if ($reflector->hasMethod("blockSubmit") && ($reflector->getMethod("blockSubmit")->getDeclaringClass()->getName() === $class_name)) {
          // Blocks having a custom implementation are discarded,
          // because some blocks may store in their configuration
          // a different structure than the form structure.
          // We can't support this properly yet.
          $compatibilityFlag = FALSE;
        }
      }
      catch (\ReflectionException $e) {

      }
    }
    // Filter out blocks with _block_ui_hidden ?
    $definitions[$id]['_ui_patterns_compatible'] = $compatibilityFlag;
  }
}