<?php

namespace Drupal\nodehive_core\Form;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Datetime\TimeZoneFormHelper;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\ConfigTarget;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Locale\CountryManagerInterface;
use Drupal\Core\Url;
use Drupal\nodehive_core\CKEditor5ExternalCssParserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Settings form for nodehive.
 */
class NodeHiveSettingsForm extends ConfigFormBase {

  /**
   * The css parser.
   *
   * @var Drupal\nodehive_core\CKEditor5ExternalCssParserInterface
   */
  protected $cssParser;

  /**
   * The country manager.
   *
   * @var \Drupal\Core\Locale\CountryManagerInterface
   */
  protected $countryManager;

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

  /**
   * Constructs a new NodeHiveSettingsForm.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The factory for configuration objects.
   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typedConfigManager
   *   The typed config manager.
   * @param \Drupal\nodehive_core\CKEditor5ExternalCssParserInterface $parser
   *   The css parser.
   * @param \Drupal\Core\Locale\CountryManagerInterface $country_manager
   *   The country manager.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   */
  public function __construct(
    ConfigFactoryInterface $config_factory,
    TypedConfigManagerInterface $typedConfigManager,
    CKEditor5ExternalCssParserInterface $parser,
    CountryManagerInterface $country_manager,
    ModuleHandlerInterface $module_handler,
  ) {
    parent::__construct($config_factory, $typedConfigManager);
    $this->cssParser = $parser;
    $this->countryManager = $country_manager;
    $this->moduleHandler = $module_handler;
  }

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

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

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

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

    // Section 1: Base Settings.
    $form['base_settings'] = [
      '#type' => 'details',
      '#title' => $this->t('Base Settings'),
      '#open' => TRUE,
    ];

    $form['base_settings']['company_name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Company Name'),
      '#default_value' => $config->get('company_name'),
      '#required' => TRUE,
    ];

    // Section 2: Configure Editor Experience.
    $form['editor_experience'] = [
      '#type' => 'details',
      '#title' => $this->t('Configure Editor Experience'),
      '#open' => TRUE,
    ];

    $form['editor_experience']['ckeditor_styles_url'] = [
      '#type' => 'url',
      '#title' => $this->t('CKEditor Styles URL'),
      '#default_value' => $config->get('ckeditor_styles_url'),
      '#description' => $this->t(
        'Example: https://www.yourfrontend.com/ckeditor.css'
      ),
    ];

    $form['editor_experience']['webform_styles_url'] = [
      '#type' => 'url',
      '#title' => $this->t('Webform Styles URL'),
      '#default_value' => $config->get('webform_styles_url'),
      '#description' => $this->t(
        'Example: https://www.yourfrontend.com/webform.css'
      ),
    ];

    // Section 2: Regional settings.
    $form['regional_settings'] = [
      '#type' => 'details',
      '#title' => $this->t('Regional settings'),
      '#open' => TRUE,
    ];

    $countries = $this->countryManager->getList();
    $form['regional_settings']['site_default_country'] = [
      '#type' => 'select',
      '#title' => $this->t('Default country'),
      '#empty_value' => '',
      '#config_target' => 'system.date:country.default',
      '#options' => $countries,
      '#attributes' => ['class' => ['country-detect']],
    ];

    $form['regional_settings']['date_first_day'] = [
      '#type' => 'select',
      '#title' => $this->t('First day of week'),
      '#config_target' => 'system.date:first_day',
      '#options' => [
        0 => $this->t('Sunday'),
        1 => $this->t('Monday'),
        2 => $this->t('Tuesday'),
        3 => $this->t('Wednesday'),
        4 => $this->t('Thursday'),
        5 => $this->t('Friday'),
        6 => $this->t('Saturday'),
      ],
    ];

    $zones = TimeZoneFormHelper::getOptionsListByRegion();
    $form['regional_settings']['date_default_timezone'] = [
      '#type' => 'select',
      '#title' => $this->t('Default time zone'),
      '#config_target' => new ConfigTarget(
        'system.date',
        'timezone.default',
        static::class . '::loadDefaultTimeZone',
      ),
      '#options' => $zones,
    ];

    $form['regional_settings']['configurable_timezones'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Users may set their own time zone'),
      '#config_target' => 'system.date:timezone.user.configurable',
    ];

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

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $ckeditor_styles_url = $form_state->getValue('ckeditor_styles_url');

    // Save the configuration.
    $this->config('nodehive_core.settings')
      ->set('company_name', $form_state->getValue('company_name'))
      ->set('webform_styles_url', $form_state->getValue('webform_styles_url'))
      ->set('ckeditor_styles_url', $ckeditor_styles_url)
      ->save();

    // Parse the new css file.
    if ($ckeditor_styles_url && Url::fromUri($ckeditor_styles_url)->isExternal()) {
      $this->cssParser->parseCss($ckeditor_styles_url);
    }

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

  /**
   * Prepares the saved timezone.default property to be displayed in the form.
   *
   * @param string $value
   *   The value saved in config.
   *
   * @return string
   *   The value of the form element.
   */
  public static function loadDefaultTimeZone(string $value): string {
    return $value ?: date_default_timezone_get();
  }

}
