<?php

namespace Drupal\reader\Form;

use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
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;

class ReaderSettingsForm extends ConfigFormBase {

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The entity type manager
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * ReaderSettingsForm constructor
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The factory for configuration objects.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager
   *   The typed config manager.
   */
  public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, TypedConfigManagerInterface $typed_config_manager) {
    parent::__construct($config_factory, $typed_config_manager);
    $this->moduleHandler = $module_handler;
    $this->entityTypeManager = $entity_type_manager;
  }

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

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

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

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

    $config = $this->config('reader.settings');

    $form['article'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Article display'),
    ];

    $filter_format_options = [];
    foreach (filter_formats() as $format) {
      $filter_format_options[$format->id()] = $format->label();
    }
    $form['article']['filter_format'] = [
      '#type' => 'select',
      '#options' => $filter_format_options,
      '#title' => $this->t('Filter format'),
      '#description' => $this->t('The filter format to use for the content in the timelines.'),
      '#default_value' => $config->get('filter_format'),
    ];

    $form['article']['node_actions'] = [
      '#type' => 'fieldset',
      '#tree' => TRUE,
      '#title' => $this->t('Response types'),
      '#description' => $this->t('Configure response types for every post in the reader.')
    ];

    $response_type_options = [
      '' => $this->t('- None -'),
      'reply' => $this->t('Reply'),
      'repost' => $this->t('Repost'),
      'bookmark' => $this->t('Bookmark'),
      'like' => $this->t('Like'),
    ];
    $node_actions = [];
    foreach ($config->get('node_actions') as $action) {
      $node_actions[$action['node_type']] = $action['response_type'];
    }
    foreach ($this->entityTypeManager->getStorage('node_type')->loadMultiple() as $type) {
      $form['article']['node_actions'][][$type->id()] = [
        '#type' => 'select',
        '#title' => $this->t('Action for <em>@label</em>', ['@label' => $type->label()]),
        '#options' => $response_type_options,
        '#default_value' => isset($node_actions[$type->id()]) ? $node_actions[$type->id()] : '',
      ];
    }

    $form['article']['use_prepopulate'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Use prepopulate'),
      '#default_value' => $config->get('use_prepopulate'),
      '#description' => $this->t('Pass data from inline actions to the node form:<ul><li>Post url to link fields</li><li>Set a default title</li></ul>'),
      '#disabled' => !$this->moduleHandler->moduleExists('prepopulate'),
    ];

    $form['article']['use_magnific_popup'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Use Magnific Popup'),
      '#default_value' => $config->get('use_magnific_popup'),
      '#description' => $this->t('Shows images in a popup using the Magnific Popup module.'),
      '#disabled' => !$this->moduleHandler->moduleExists('magnific_popup'),
    ];

    $form['article']['use_infinite_scroll'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Use infinite scroll'),
      '#default_value' => $config->get('use_infinite_scroll'),
      '#description' => $this->t('Autoload the next page when the pager becomes visible.'),
    ];

    $form['article']['read_more'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Read more'),
      '#default_value' => $config->get('read_more'),
      '#description' => $this->t('Add a read more button for long posts.'),
    ];

    $form['article']['read_more_height'] = [
      '#type' => 'number',
      '#min' => 30,
      '#max' => 1000,
      '#title' => $this->t('Read more height'),
      '#default_value' => $config->get('read_more_height'),
      '#description' => $this->t('Height of the article before applying the read more functionality.'),
    ];

    $form['forms'] = [
      '#type' => 'fieldset',
      '#open' => TRUE,
      '#title' => $this->t('Forms'),
    ];

    $node_hide_options = [];
    foreach ($this->entityTypeManager->getStorage('node_type')->loadMultiple() as $type) {
      $node_hide_options[$type->id()] = $type->label();
    }

    $form['forms']['alter_node_form'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Alter node form'),
      '#default_value' => $config->get('alter_node_form'),
      '#description' => $this->t('Alters the node form on /reader/add/{node_type} by removing elements like meta, menu and revision which can not be controlled by form display.')
    ];

    $form['forms']['node_hide'] = [
      '#type' => 'checkboxes',
      '#title' => $this->t('Hide content types'),
      '#options' => $node_hide_options,
      '#default_value' => $config->get('node_hide'),
      '#description' => $this->t('Hide content type in the create links block and content overview.'),
    ];

    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $node_actions = [];
    foreach ($form_state->getValue('node_actions') as $action) {
      $key = key($action);
      if (!empty($action[$key])) {
        $node_actions[] = [
          'node_type' => $key,
          'response_type' => $action[$key],
        ];
      }
    }

    $this->config('reader.settings')
      ->set('read_more', $form_state->getValue('read_more'))
      ->set('read_more_height', $form_state->getValue('read_more_height'))
      ->set('node_actions', $node_actions)
      ->set('filter_format', $form_state->getValue('filter_format'))
      ->set('node_hide', array_filter($form_state->getValue('node_hide')))
      ->set('use_prepopulate', $form_state->getValue('use_prepopulate'))
      ->set('use_magnific_popup', $form_state->getValue('use_magnific_popup'))
      ->set('use_infinite_scroll', $form_state->getValue('use_infinite_scroll'))
      ->set('alter_node_form', $form_state->getValue('alter_node_form'))
      ->save();
    Cache::invalidateTags(['reader']);
    parent::submitForm($form, $form_state);
  }

}
