<?php

namespace Drupal\castorcito\Plugin\CastorcitoComponentField;

use Drupal\Core\Form\FormStateInterface;

/**
 * Container configuration.
 *
 * @CastorcitoComponentField(
 *   id = "advanced_container",
 *   label = @Translation("Advanced container"),
 *   description = @Translation("Configuration for the advanced container field.")
 * )
 */
class AdvancedContainer extends Container {

  /**
   * {@inheritdoc}
   */
  public function defaultModel() {
    return [
      'items' => [],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return parent::defaultConfiguration() + [
      'head_component' => '',
      'item_container_label' => '',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $head_component = [];
    $components = $this->componentList();
    if (!empty($components)) {
      foreach ($components as $c_key => $component) {
        if (!empty($this->headLabelOptions($c_key))) {
          $head_component[$c_key] = $component;
        }
      }
    }

    $form['markup'] = [
      '#markup' => $this->t('To be available as a header, a component must have a required <strong>Plain text</strong> field.'),
    ];

    $form['head_component'] = [
      '#type' => 'radios',
      '#title' => $this->t('Head component'),
      '#default_value' => $this->configuration['head_component'],
      '#options' => $head_component,
      '#description' => $this->t('Choose a component to be used as container header.'),
      '#required' => TRUE,
      '#ajax' => [
        'callback' => [$this, 'updateHeadLabel'],
        'wrapper' => 'head-label-select-wrapper',
      ],
    ];

    $form['item_container_label_wrapper'] = [
      '#type' => 'container',
      '#attributes' => ['id' => 'head-label-select-wrapper'],
    ];

    $user_input = $form_state->getUserInput();
    $head_component = $user_input['settings']['head_component'] ?? $this->configuration['head_component'] ?? NULL;

    if (!empty($head_component)) {
      $form['item_container_label_wrapper']['item_container_label'] = [
        '#type' => 'select',
        '#title' => $this->t('Item container label'),
        '#default_value' => $this->configuration['item_container_label'],
        '#options' => $this->headLabelOptions($head_component),
        '#description' => $this->t('This configuration is only displayed in the form and is used as the item container label.'),
        '#required' => TRUE,
        '#validated' => TRUE,
      ];
    }

    $form = parent::buildConfigurationForm($form, $form_state);

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
    if (empty($form_state->getValue('head_component'))) {
      $form_state->setErrorByName('head_component', $this->t('It is necessary to choose a component for the header.'));
    }

    if (empty($form_state->getValue(['item_container_label_wrapper', 'item_container_label']))) {
      $form_state->setErrorByName('item_container_label', $this->t('Please enter a label for the item container.'));
    }

    parent::validateConfigurationForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $this->configuration['head_component'] = $form_state->getValue('head_component');
    $this->configuration['item_container_label'] = $form_state->getValue(['item_container_label_wrapper', 'item_container_label']);
    parent::submitConfigurationForm($form, $form_state);
  }

  /**
   * Ajax callback for the update head label.
   */
  public function updateHeadLabel(array $form, FormStateInterface $form_state) {
    return $form['settings']['item_container_label_wrapper'];
  }

  /**
   * Retrieves the available fields that can be used as the header.
   *
   * @param string $head_component
   *   The machine name of the component from which to retrieve header label options.
   *
   * @return array
   *   An associative array where keys and values correspond to available
   *   text-based required fields, suitable for use in form elements.
   */
  protected function headLabelOptions($head_component) {
    if (!empty($head_component)) {
      $entity_type_manager = \Drupal::entityTypeManager();
      $component_storage = $entity_type_manager->getStorage('castorcito_component');
      $component = $component_storage->load($head_component);

      if ($field_configuration = $component->get('field_configuration')) {
        return array_map(
          fn($field) => $field['label'],
          array_filter($field_configuration, fn($field) => !empty($field['required']) && $field['id'] === 'plain_text')
        );
      }
    }

    return [];
  }

}
