<?php

/**
 * @file
 * The Social Content Block module.
 */

use Drupal\block_content\BlockContentInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\social_content_block\ContentBuilder;
use Drupal\social_content_block\Entity\BlockContent\ContentList;
use Drupal\social_content_block\Entity\BlockContent\ContentListInterface;

/**
 * Implements hook_preprocess_block().
 */
function social_content_block_preprocess_block(array &$variables): void {
  if (
    isset($variables['content']['#block_content']) &&
    $variables['content']['#block_content'] instanceof ContentListInterface
  ) {
    if ($variables['base_plugin_id'] === 'block_content') {
      $variables['card'] = TRUE;
    }
    // Add subtitle and content type icon for display on dashboards.
    elseif ($variables['base_plugin_id'] === 'inline_block') {
      /** @var \Drupal\social_content_block\Entity\BlockContent\ContentListInterface $block_entity */
      $block_entity = $variables['content']['#block_content'];

      $variables['content_type'] = [
        '#plain_text' => _social_content_block_get_content_type_for_block($block_entity),
      ];

      if ($block_entity->hasSubtitle()) {
        $variables['subtitle'] = $block_entity->field_subtitle->view(['label' => 'hidden']);
      }
    }
  }
}

/**
 * Implements hook_entity_bundle_info_alter().
 */
function social_content_block_entity_bundle_info_alter(array &$bundles): void {
  if (isset($bundles['block_content']['custom_content_list'])) {
    $bundles['block_content']['custom_content_list']['class'] = ContentList::class;
  }
}

/**
 * Implements hook_entity_extra_field_info().
 */
function social_content_block_entity_extra_field_info() {
  return [
    'block_content' => [
      'custom_content_list' => [
        'display' => [
          'entities' => [
            'label' => t('Entities'),
            'weight' => 0,
          ],
        ],
      ],
    ],
  ];
}

/**
 * Implements hook_ENTITY_TYPE_view().
 */
function social_content_block_block_content_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  if ($entity->bundle() === 'custom_content_list' && $display->getComponent('entities')) {
    $build['social_content_block'] = [
      '#lazy_builder' => [
        'social_content_block.content_builder:build',
        [
          $entity->id(),
          $entity->getEntityTypeId(),
          $entity->bundle(),
        ],
      ],
      '#create_placeholder' => TRUE,
    ];
  }
}

/**
 * Get content type for the block.
 *
 * @param \Drupal\block_content\BlockContentInterface $block_entity
 *   The block content entity object.
 *
 * @return string
 *   The entity type.
 */
function _social_content_block_get_content_type_for_block(BlockContentInterface $block_entity) {
  if ($block_entity->field_plugin_id->isEmpty()) {
    return '';
  }

  $plugin_id = $block_entity->field_plugin_id->value;
  $definition = \Drupal::service('plugin.manager.content_block')->getDefinition($plugin_id);

  // For nodes we distinguish bundles, otherwise we only show the entity type.
  if ($definition['entityTypeId'] === 'node') {
    return $definition['bundle'];
  }

  return $definition['entityTypeId'];
}

/**
 * Implements hook_form_alter().
 */
function social_content_block_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  switch ($form_id) {
    case 'block_content_custom_content_list_form':
    case 'block_content_custom_content_list_edit_form':
      $element = &$form;
      break;

    case 'layout_builder_add_block':
      /** @var \Drupal\layout_builder\SectionComponent $component */
      $component = $form_state->get('layout_builder__component');

      if ($component->getPluginId() === 'inline_block:custom_content_list') {
        $element = &$form['settings']['block_form'];
      }
      break;

    case 'layout_builder_update_block':
      if (isset($form['settings']['block_form']['#block']) && $form['settings']['block_form']['#block']->bundle() === 'custom_content_list') {
        $element = &$form['settings']['block_form'];
      }
      break;
  }

  if (isset($element)) {
    $element['#process'][] = [ContentBuilder::class, 'processBlockForm'];
  }
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function social_content_block_form_block_content_custom_content_list_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  // Add submit handler to clear cache.
  foreach (array_keys($form['actions']) as $action) {
    if ($action !== 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
      $form['actions'][$action]['#submit'][] = 'custom_content_block_form_submit';
    }
  }
}

/**
 * Custom submit handler.
 */
function custom_content_block_form_submit($form, FormStateInterface $form_state) {
  // Clear plugin cache.
  \Drupal::service('plugin.cache_clearer')->clearCachedDefinitions();
}

/**
 * Sets dynamic allowed values for the sorting field.
 *
 * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $definition
 *   The field storage definition.
 * @param \Drupal\Core\Entity\FieldableEntityInterface|null $entity
 *   (optional) The entity object.
 *
 * @return array
 *   The options list.
 */
function _social_content_block_allowed_values_callback(FieldStorageDefinitionInterface $definition, FieldableEntityInterface $entity = NULL) {
  $values = [];

  if (
    $definition->getName() !== 'field_sorting' ||
    $definition->getTargetEntityTypeId() !== 'block_content' ||
    !$entity instanceof ContentListInterface
  ) {
    return $values;
  }

  /** @var \Drupal\social_content_block\ContentBlockManagerInterface $manager */
  $manager = \Drupal::service('plugin.manager.content_block');

  if ($entity->field_plugin_id->isEmpty()) {
    $plugin_ids = array_keys($manager->getDefinitions());
  }
  else {
    $plugin_ids = array_column($entity->field_plugin_id->getValue(), 'value');
  }

  foreach ($plugin_ids as $plugin_id) {
    if ($manager->hasDefinition($plugin_id)) {
      $plugin = $manager->createInstance($plugin_id);
      foreach ($plugin->supportedSortOptions() as $name => $settings) {
        $values[$name] = is_array($settings) ? $settings['label'] : $settings;
      }
    }
  }

  return $values;
}

/**
 * Implements hook_theme().
 */
function social_content_block_theme(): array {
  return [
    'block__multiple_content_block' => [
      'base hook' => 'block',
    ],
  ];
}

/**
 * Implements hook_preprocess_HOOK().
 */
function social_content_block_preprocess_block__multiple_content_block(array &$variables): void {
  $variables['subtitle'] = $variables['configuration']['subtitle'];
}
