<?php

namespace Drupal\pagedesigner\Form;

use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * The settings form for pagedesigner.
 */
class PagedesignerSettingsForm extends ConfigFormBase {

  /**
   * Constructs a PagedesignerSettingsForm object.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The factory for configuration objects.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
   *   The module handler.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   */
  public function __construct(
    ConfigFactoryInterface $config_factory,
    protected ModuleHandlerInterface $moduleHandler,
    protected EntityTypeManagerInterface $entityTypeManager,
  ) {
    parent::__construct($config_factory);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('config.factory'),
      $container->get('module_handler'),
      $container->get('entity_type.manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [
      'pagedesigner.settings',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'pagedesigner_settings_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    parent::buildForm($form, $form_state);
    $config = $this->config('pagedesigner.settings');

    $form['pagedesigner_settings'] = [
      '#type' => 'vertical_tabs',
      '#title' => $this->t('Pagedsigner Settings'),
    ];

    $form['general'] = [
      '#type' => 'details',
      '#title' => $this->t('General settings'),
      '#open' => TRUE,
      '#group' => 'pagedesigner_settings',
    ];
    $form['general'] = $this->addGeneralSettings($form['general'], $form_state, $config);

    $form['traits'] = [
      '#type' => 'details',
      '#title' => $this->t('Trait settings'),
      '#open' => TRUE,
      '#group' => 'pagedesigner_settings',
    ];
    $form['traits'] = $this->addTraitSettings($form['traits'], $form_state, $config);

    $form['performance'] = [
      '#type' => 'details',
      '#title' => $this->t('Performance settings'),
      '#open' => TRUE,
      '#group' => 'pagedesigner_settings',
    ];
    $form['performance'] = $this->addPerformanceSettings($form['performance'], $form_state, $config);
    return parent::buildForm($form, $form_state);

  }

  /**
   * Add the general settings.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   * @param \Drupal\Core\Config\Config $config
   *   The pagedesigner settings configuration.
   *
   * @return array
   *   The sub form for the general settings.
   */
  protected function addGeneralSettings(array $form, FormStateInterface $form_state, Config $config) {
    $form['general']['help_content'] = [
      '#type' => 'text_format',
      '#title' => $this->t('Pagedesigner Help'),
      '#format' => (!empty($config->get('help_content')['format'])) ? $config->get('help_content')['format'] : 'full_html',
      '#default_value' => $config->get('help_content')['value'],
      '#base_type' => 'textarea',
    ];

    $form['general']['loading_screen'] = [
      '#type' => 'text_format',
      '#title' => $this->t('Loading Screen'),
      '#format' => (!empty($config->get('loading_screen')['format'])) ? $config->get('loading_screen')['format'] : 'full_html',
      '#default_value' => $config->get('loading_screen')['value'],
      '#base_type' => 'textarea',
    ];

    $form['general']['editor_dom_element'] = [
      '#type' => 'textfield',
      '#title' => $this->t('DOM element of editor'),
      '#default_value' => $config->get('editor_dom_element'),
      '#description' => $this->t('CSS selector'),
    ];
    return $form;
  }

  /**
   * Add the trait settings.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   * @param \Drupal\Core\Config\Config $config
   *   The pagedesigner settings configuration.
   *
   * @return array
   *   The sub form for the trait settings.
   */
  protected function addTraitSettings(array $form, FormStateInterface $form_state, Config $config) {
    $form['traits']['editor'] = [
      '#type' => 'fieldset',
      '#open' => TRUE,
      '#title' => $this->t('Editor settings'),
    ];
    $form['traits']['editor']['filter_format'] = [
      '#type' => 'select',
      '#title' => $this->t('Editor for HTML traits'),
      '#default_value' => $config->get('filter_format'),
      '#options' => $this->getFilterFormatsOptions(),
    ];

    $form['traits']['editor']['filter_format_textarea'] = [
      '#type' => 'select',
      '#title' => $this->t('Editor for textarea traits'),
      '#default_value' => $config->get('filter_format_textarea'),
      '#options' => $this->getFilterFormatsOptions(),
    ];

    $form['traits']['editor']['filter_format_longtext'] = [
      '#type' => 'select',
      '#title' => $this->t('Editor for longtext traits'),
      '#default_value' => $config->get('filter_format_longtext'),
      '#options' => $this->getFilterFormatsOptions(),
    ];
    return $form;
  }

  /**
   * Add the performance settings.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   * @param \Drupal\Core\Config\Config $config
   *   The pagedesigner settings configuration.
   *
   * @return array
   *   The sub form for the performance settings.
   */
  protected function addPerformanceSettings(array $form, FormStateInterface $form_state, Config $config) {
    $form['performance']['exclude_dom_elements_before'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Exclude DOM elements from Canvas (before pagedesigner)'),
      '#default_value' => $config->get('exclude_dom_elements_before'),
      '#description' => $this->t('CSS selectors, one per line'),
    ];

    $form['performance']['exclude_dom_elements_after'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Exclude DOM elements from Canvas (after pagedesigner)'),
      '#default_value' => $config->get('exclude_dom_elements_after'),
      '#description' => $this->t('CSS selectors, one per line'),
    ];

    return $form;
  }

  /**
   * Returns the available filter format options.
   *
   * @return array
   *   The available filter format options as [id => label].
   */
  protected function getFilterFormatsOptions() {
    $filterFormatOptions = [];
    $filterFormats = $this->entityTypeManager->getStorage('filter_format')->loadMultiple();
    foreach ($filterFormats as $filterFormat) {
      $filterFormatOptions[$filterFormat->id()] = $filterFormat->label();
    }
    return $filterFormatOptions;
  }

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

  }

  /**
   * Validate general settings.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  protected function validateGeneralSettings(array &$form, FormStateInterface $form_state) {

  }

  /**
   * Validate trait settings.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  protected function validateTraitSettings(array &$form, FormStateInterface $form_state) {
    if (!in_array($form_state->getValue('filter_format'), $this->getFilterFormatsOptions())) {
      $form_state->setErrorByName('filter_format', $this->t('The selected filter format is not available.'));
    }
    if (!in_array($form_state->getValue('filter_format_textarea'), $this->getFilterFormatsOptions())) {
      $form_state->setErrorByName('filter_format_textarea', $this->t('The selected filter format is not available.'));
    }
    if (!in_array($form_state->getValue('filter_format_longtext'), $this->getFilterFormatsOptions())) {
      $form_state->setErrorByName('filter_format_longtext', $this->t('The selected filter format is not available.'));
    }
  }

  /**
   * Validate performance settings.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  protected function validatePerformanceSettings(array &$form, FormStateInterface $form_state) {

  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    parent::submitForm($form, $form_state);
    $config = $this->config('pagedesigner.settings');
    $config->set('help_content', $form_state->getValue('help_content'));
    $config->set('exclude_dom_elements_before', $form_state->getValue('exclude_dom_elements_before'));
    $config->set('exclude_dom_elements_after', $form_state->getValue('exclude_dom_elements_after'));
    $config->set('filter_format', $form_state->getValue('filter_format'));
    $config->set('filter_format_textarea', $form_state->getValue('filter_format_textarea'));
    $config->set('filter_format_longtext', $form_state->getValue('filter_format_longtext'));
    $config->set('loading_screen', $form_state->getValue('loading_screen'));
    $config->set('editor_dom_element', $form_state->getValue('editor_dom_element'));
    $config->save();
  }

}
