<?php

/**
 * @file
 * Contains paragraphs related hook implementations and functions.
 */

use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\WidgetInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\paragraphs\Plugin\Field\FieldWidget\ParagraphsWidget;

/**
 * Implements hook_field_widget_third_party_settings_form().
 */
function thunder_paragraphs_field_widget_third_party_settings_form(WidgetInterface $plugin, FieldDefinitionInterface $field_definition, string $form_mode, array $form, FormStateInterface $form_state): array {
  $element = [];

  if ($plugin instanceof ParagraphsWidget) {
    // Add library for hard-wiring and disabling options.
    $element['#attached']['library'][] = 'thunder_paragraphs/fieldwidget_settings';
  }

  return $element;
}

/**
 * Implements hook_preprocess_HOOK() for field_multiple_value_form.
 */
function thunder_paragraphs_preprocess_field_multiple_value_form(array &$variables): void {
  if (isset($variables['element']['#paragraphs_widget'])
    && $variables['element']['#paragraphs_widget'] === TRUE
    && isset($variables['table']['#header'][0]['data']['#attributes'])) {
    $variables['table']['#header'][0]['data']['#attributes']->addClass('paragraphs-table-header__label');
  }
}

/**
 * Implements hook_field_widget_single_element_WIDGET_TYPE_form_alter().
 */
function thunder_paragraphs_field_widget_single_element_paragraphs_form_alter(array &$element, FormStateInterface $form_state, array $context): void {
  // Based on logic in ParagraphsWidget::formMultipleElements - execution of
  // alter hook for existing paragraphs will be executed first and only with
  // list of editable paragraphs. Since all editable paragraphs are processed
  // before new paragraphs, we can simply disable "Collapse and save" for any
  // following paragraph.
  $processing_new_paragraphs = FALSE;

  /** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $item */
  foreach ($context['items'] as $item) {
    if ($item->isEmpty()) {
      $processing_new_paragraphs = TRUE;

      break;
    }
  }

  thunder_paragraphs__attach_ief_submit(
    $element,
    [
      'top',
      'actions',
      'actions',
      'collapse_button',
    ],
    !$processing_new_paragraphs
  );

  if (isset($element['preview'])) {
    $element['#attributes']['class'][] = 'paragraph-form-item--has-preview';
  }
  elseif (isset($element['subform'])) {
    $element['#attributes']['class'][] = 'paragraph-form-item--has-subform';
  }

  // Add custom styling.
  $element['#attached']['library'][] = 'thunder_paragraphs/paragraphs.widget';
}

/**
 * Helper for attaching IEF submit trigger and functions.
 *
 * @param array $element
 *   Element render array for paragraph.
 * @param array $button_parents
 *   Array with parents for paragraph collapse button.
 * @param bool $is_displayed
 *   Flag if "Collapse and save" button should be visible.
 */
function thunder_paragraphs__attach_ief_submit(array &$element, array $button_parents, bool $is_displayed = TRUE): void {
  if (isset($element['subform'])) {
    foreach (Element::children($element['subform']) as $index) {
      if (isset($element['subform'][$index]['widget'][0]['inline_entity_form'])
        || isset($element['subform'][$index]['widget']['#ief_id'])
        || isset($element['subform'][$index]['widget']['#attach_ief_submit'])) {

        $button = NestedArray::getValue($element, $button_parents);
        if ($button) {
          $button['#submit'] = array_merge([
            ['Drupal\inline_entity_form\ElementSubmit', 'trigger'],
          ], $button['#submit']);
          $button['#value'] = t('Collapse and save');
          $button['#ief_submit_trigger'] = TRUE;
          $button['#ief_submit_trigger_all'] = TRUE;
          $button['#paragraphs_show_warning'] = FALSE;
          $button['#access'] = $is_displayed;

          NestedArray::setValue($element, $button_parents, $button);
        }
      }
    }
  }
}
