<?php

namespace Drupal\reader\Services;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;

class ReaderFormAlter implements ReaderFormAlterInterface {

  use StringTranslationTrait;
  use DependencySerializationTrait {
    __sleep as traitSleep;
  }

  /**
   * The route match.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

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

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

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

  /**
   * ReaderPubFormAlter constructor
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   */
  public function __construct(RouteMatchInterface $route_match, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler) {
    $this->routeMatch = $route_match;
    $this->entityTypeManager = $entity_type_manager;
    $this->configFactory = $config_factory;
    $this->moduleHandler = $module_handler;
  }

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

    if (!$this->isReaderContentRoute()) {
      return;
    }

    // Hide elements which can not be controlled through form display.
    if ($this->configFactory->get('reader.settings')->get('alter_node_form')) {
      $form['revision_information']['#access'] = FALSE;
      $form['meta']['#access'] = FALSE;
      $form['menu']['#access'] = FALSE;
      $form['actions']['preview']['#access'] = FALSE;
    }

    // Add submit handler.
    $form['actions']['submit']['#submit'][] = [$this, 'submitNodeForm'];
  }

  /**
   * Submit callback.
   *
   * @param array $form
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   */
  public function submitNodeForm(array $form, FormStateInterface $form_state) {
    $form_state->setRedirect('reader.content');
  }

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

    if (!$this->isReaderContentRoute()) {
      return;
    }

  }

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

    if (!$this->isReaderLoginRoute()) {
      return;
    }

    $form['reset_link'] = ['#markup' => '<p class="user-link">' . Link::createFromRoute($this->t('Forgot password?'), 'reader.password')->toString() . '</p>'];
    $form['#submit'][] = [$this, 'loginSubmit'];
  }

  /**
   * Submit callback after login.
   *
   * @param array $form
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *
   * @see alterLoginForm();
   */
  public function loginSubmit(array &$form, FormStateInterface $form_state) {
    if (!$this->moduleHandler->moduleExists('tfa')) {
      $form_state->setRedirect('reader.home');
    }
    else {
      $redirect = $form_state->getRedirect();
      if ($redirect instanceof Url) {
        $options = $redirect->getOptions();
        $options['query']['destination'] = '/reader';
        $redirect->setOptions($options);
        $form_state->setRedirectUrl($redirect);
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function alterResetPasswordForm(array &$form) {
    unset($_SESSION['use_reader_theme']);
    $form['#action'] .= '?destination=/reader';
  }

  /**
   * Submit callback after reset login.
   *
   * @param array $form
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *
   * @see alterLoginForm();
   */
  public function resetSubmit(array &$form, FormStateInterface $form_state) {
    $form_state->setRedirect('reader.home');
  }

  /**
   * Returns whether this is a reader content route or not.
   *
   * @return bool
   */
  protected function isReaderContentRoute() {
    if (in_array($this->routeMatch->getRouteName(), ['reader.add', 'reader.node.edit'])) {
      return TRUE;
    }

    return FALSE;
  }

  /**
   * Returns whether this is a reader login or not.
   *
   * @return bool
   */
  protected function isReaderLoginRoute() {
    if ($this->routeMatch->getRouteName() == 'reader.login') {
      return TRUE;
    }

    return FALSE;
  }

}
