<?php

namespace Drupal\castorcito\Plugin\CastorcitoComponentField;

use Drupal\Core\Form\FormStateInterface;
use Drupal\castorcito\ConfigurableComponentFieldBase;

/**
 * Entity reference configuration.
 *
 * @CastorcitoComponentField(
 *   id = "entity_reference",
 *   label = @Translation("Entity reference"),
 *   description = @Translation("Field to reference other content.")
 * )
 */
class EntityReference extends ConfigurableComponentFieldBase {

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

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'entity_type' => '',
      'entity_bundle' => [],
      'display' => [],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $castorcito_manager = \Drupal::service('castorcito.manager');
    $entity_type_manager = \Drupal::entityTypeManager();
    $entity_display_repository = \Drupal::service('entity_display.repository');
    $filter = function (string $entity_type_id) use ($entity_type_manager): bool {
      return $entity_type_manager->getDefinition($entity_type_id)
        ->hasKey('id');
    };

    $entity_type_labels = \Drupal::service('entity_type.repository')->getEntityTypeLabels(TRUE);
    $first_group = reset($entity_type_labels);
    $options = array_filter($first_group, $filter, ARRAY_FILTER_USE_KEY);

    $form['entity_type'] = [
      '#type' => 'select',
      '#title' => $this->t('Entity type'),
      '#default_value' => $this->configuration['entity_type'],
      '#required' => TRUE,
      '#options' => $options,
      '#empty_option' => $this->t('- Select -'),
    ];

    $form['display'] = [
      '#type' => 'details',
      '#title' => $this->t('Display'),
      '#open' => TRUE,
      '#weight' => 1,
      '#states' => [
        'visible' => [
          ':input[name="settings[entity_type]"]' => ['filled' => TRUE],
        ],
      ],
    ];

    if (!empty($options)) {
      foreach ($options as $key => $option) {
        if ($castorcito_manager->isBundleEntityType($key)) {
          $bundle_info = \Drupal::service('entity_type.bundle.info');
          $types = $bundle_info->getBundleInfo($key);

          if (!empty($types)) {
            $bundle_options = [];
            foreach ($types as $type_id => $info) {
              $bundle_options[$type_id] = $info['label'];
            }

            $form[$key . '_bundle'] = [
              '#type' => 'checkboxes',
              '#title' => $this->t('Entity bundle'),
              '#options' => $bundle_options,
              '#default_value' => $this->configuration['entity_bundle'],
              '#description' => $this->t('Choose the required bundle types.'),
              '#multiple' => TRUE,
              '#states' => [
                'visible' => [
                  ':input[name="settings[entity_type]"]' => ['value' => $key],
                ],
              ],
            ];
          }
        }

        $view_mode_options = $entity_display_repository->getViewModeOptions($key);
        if (!empty($view_mode_options)) {
          $form['display'][$key . '_view_mode'] = [
            '#type' => 'select',
            '#title' => $this->t('View mode'),
            '#options' => $view_mode_options,
            '#default_value' => $this->configuration['display']['view_mode'] ?? '',
            '#states' => [
              'visible' => [
                ':input[name="settings[entity_type]"]' => ['value' => $key],
              ],
            ],
            '#empty_option' => $this->t('- Select -'),
          ];
        }
      }
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {}

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $castorcito_manager = \Drupal::service('castorcito.manager');
    $entity_type = $form_state->getValue('entity_type');
    $view_mode = $form_state->getValue(['display', $entity_type . '_view_mode']);
    $this->configuration['entity_type'] = $entity_type;
    $this->configuration['display']['view_mode'] = $view_mode;

    if ($castorcito_manager->isBundleEntityType($entity_type)) {
      $target_bundles = array_filter($form_state->getValue($entity_type . '_bundle'));
      $this->configuration['entity_bundle'] = $target_bundles;
    }
  }

}
