<?php

/**
 * @file
 * The Social search module.
 */

use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\group\Entity\GroupType;
use Drupal\search_api\Entity\Index;

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Enhance the Views exposed filter blocks forms.
 */
function social_search_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $filter_forms = [
    'views-exposed-form-search-content-page',
    'views-exposed-form-search-groups-page',
    'views-exposed-form-search-users-page',
  ];

  if (in_array($form['#id'], $filter_forms, TRUE)) {
    // Always enable the reset button.
    $form['actions']['reset']['#access'] = TRUE;
    $form['#attached']['library'][] = 'social_search/search_filters';
    switch ($form['#id']) {
      case 'views-exposed-form-search-users-page':
        social_search_alter_users_exposed_filter_block($form, $form_state, $form_id);
        break;

      case 'views-exposed-form-search-groups-page':
        social_search_alter_groups_exposed_filter_block($form, $form_state, $form_id);
        break;

      case 'views-exposed-form-search-content-page':
        social_search_alter_content_exposed_filter_block($form, $form_state, $form_id);
        break;

    }
  }
}

/**
 * Makes changes for the filter block on the user search page.
 */
function social_search_alter_users_exposed_filter_block(&$form, FormStateInterface $form_state, $form_id) {
  foreach ($form as &$element) {
    if (is_array($element) && isset($element['#type']) && $element['#type'] === 'entity_autocomplete') {
      $element['#selection_settings']['hide_id'] = TRUE;
    }
  }

  if (!empty($form['created_wrapper']['created'])
    && !empty($form['created_wrapper']['created_op'])) {
    $form['settings']['created_op'] = $form['created_wrapper']['created_op'];
    $form['settings']['created'] = $form['created_wrapper']['created'];
    // $form['settings']['#attributes']['class'] = ['indent_filter'];
    unset($form['created_wrapper']);
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Makes changes for the filter block on the groups search page.
 */
function social_search_alter_groups_exposed_filter_block(&$form, FormStateInterface $form_state, $form_id) {
  if (!isset($form['type'])) {
    return;
  }

  $options = [
    'All' => t('- Any -'),
  ];
  $group_types = GroupType::loadMultiple();
  /** @var \Drupal\group\Entity\GroupType $group_type */
  foreach ($group_types as $group_type) {
    $options[$group_type->id()] = $group_type->label();
  }

  $form['type'] = [
    '#type' => 'select',
    '#options' => $options,
  ];
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Makes changes for the filter block on the content search page.
 */
function social_search_alter_content_exposed_filter_block(&$form, FormStateInterface $form_state, $form_id) {
  if (!empty($form['type'])) {
    $form['type']['#weight'] = '-100';
  }

  if (!empty($form['field_event_date_wrapper']['field_event_date_wrapper']['field_event_date'])
    && !empty($form['field_event_date_wrapper']['field_event_date_wrapper']['field_event_date_op'])) {
    if (!empty($form['settings'])) {
      $form['settings']['#states'] = [
        'visible' => [
          ':input[name=type]' => [
            'value' => 'event',
          ],
        ],
      ];

    }

    $form['settings']['field_event_date_op'] = $form['field_event_date_wrapper']['field_event_date_wrapper']['field_event_date_op'];
    $form['settings']['field_event_date'] = $form['field_event_date_wrapper']['field_event_date_wrapper']['field_event_date'];
    unset($form['field_event_date_wrapper']);
  }

  if (!empty($form['location_details'])) {
    $form['location_details']['#weight'] = '-98';
    $form['location_details']['#attributes']['class'] = ['indent_filter'];
  }

  // When combined sorting and filtering is used we make some changes to
  // accommodate theming.
  if (isset($form['sort_bef_combine'])) {
    // Ensure the sort option shows up at the top.
    $form['sort_bef_combine']['#weight'] = -9999;

    // From a UX perspective it doesn't make sense to show the least relevant
    // results first so we remove this sorting option.
    if (isset($form['sort_bef_combine']['#options']['search_api_relevance ASC'])) {
      unset($form['sort_bef_combine']['#options']['search_api_relevance ASC']);
    }

    // We attach custom CSS so that we can properly translate the filter title.
    // This selector should match the value in sort_filter.css of this module.
    // Use a useless variable to trick phpcs from giving us invalid warnings.
    $translated_filter = t('Filter');
    $form['social_search_translated_filter_string'] = [
      '#type' => 'html_tag',
      '#tag' => 'style',
      '#attributes' => [
        'type' => 'text/css',
      ],
      '#value' => "#block-filter .form-item-sort-bef-combine:after { content: '${translated_filter}'; }",
    ];
  }
}

/**
 * Implements hook_block_view_BASE_BLOCK_ID_alter().
 *
 * Enhance the Views exposed filter blocks.
 */
function social_search_block_view_views_exposed_filter_block_alter(array &$build, BlockPluginInterface $block) {
  $filter_blocks = [
    'search_content-page',
    'search_groups-page',
    'search_users-page',
  ];

  if (in_array($build['#derivative_plugin_id'], $filter_blocks)) {
    // Disable cache for exposed filter block to get correct current path,
    // which is used in $form['#action'].
    $build['#cache'] = [
      'max-age' => 0,
    ];
  }
}

/**
 * Implements hook_views_data_alter().
 */
function social_search_views_data_alter(array &$data) {
  // Custom Event Date filters see SocialDate.php.
  $data['node']['social_date_filter'] = [
    'title' => t('Date Filter by Open Social'),
    'filter' => [
      'title' => t('Date Filter by Open Social'),
      'help' => t('Filters for date used in Open Social'),
      'id' => 'social_date_filter',
      'field' => 'field_event_date_value',
    ],
  ];

  $data['node']['social_created_filter'] = [
    'title' => t('Created Date Filter by Open Social'),
    'filter' => [
      'title' => t('Date Filter by Open Social'),
      'help' => t('Filters for date used in Open Social'),
      'id' => 'social_date_filter',
      'field' => 'created',
    ],
  ];
}

/**
 * Implements hook_block_view_BASE_BLOCK_ID_alter().
 *
 * Make the label/title translatable.
 */
function social_block_view_search_hero_block_alter(array &$build, BlockPluginInterface $block) {
  $build['#configuration']['label'] = t('Search');
}

/**
 * Re-saves search indices.
 *
 * This triggers the save for all search indexes which triggers updates of
 * fields and processors.
 *
 * @param array $index_ids
 *   An array of index IDs to re-save or NULL to re-save all indices.
 *
 * @throws \Drupal\Core\Entity\EntityStorageException
 */
function social_search_resave_search_indexes(array $index_ids = NULL) {
  // We load all indexes, we assume there will never be hundreds of search
  // indexes which would create its own problems for a site.
  $indexes = Index::loadMultiple($index_ids);

  /** @var \Drupal\search_api\IndexInterface $index */
  foreach ($indexes as $index) {
    // No need to disable and enable the index here, this worked around a
    // validation of the Search Settings form that prevented the save from being
    // triggered. However, this validation is not present in the entity save
    // logic. So a simple call to `save()` will trigger the reprocessing of
    // fields and processors.
    $index->save();
  }
}
