<?php

declare(strict_types=1);

namespace Drupal\cron_fail_alert\Form;

use Drupal\Component\Utility\EmailValidatorInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Configure Cron fail alert settings for this site.
 */
class SettingsForm extends ConfigFormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return 'cron_fail_alert_settings';
  }

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

  /**
   * Cron fail alert SettingsForm constructor.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   The factory for configuration objects.
   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typedConfigManager
   *   The typed config manager.
   * @param \Drupal\Component\Utility\EmailValidatorInterface $emailValidator
   *   The email validator service.
   */
  public function __construct(
    ConfigFactoryInterface $configFactory,
    TypedConfigManagerInterface $typedConfigManager,
    protected EmailValidatorInterface $emailValidator,
  ) {
    parent::__construct($configFactory, $typedConfigManager);
  }

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state): array {
    // Monitoring settings.
    $form['monitoring'] = [
      '#type' => 'details',
      '#title' => $this->t('Monitoring settings'),
      '#open' => TRUE,
    ];

    $form['monitoring']['frequency'] = [
      '#type' => 'number',
      '#required' => TRUE,
      '#title' => $this->t('Check frequency'),
      '#description' => $this->t('How often to check if cron has failed, in minutes. This prevents excessive checking on every page load.'),
      '#config_target' => 'cron_fail_alert.settings:frequency',
      '#step' => 1,
      '#min' => 1,
      '#max' => 1440,
      '#field_suffix' => $this->t('minutes'),
    ];

    $form['monitoring']['tolerance'] = [
      '#type' => 'number',
      '#required' => TRUE,
      '#title' => $this->t('Cron failure tolerance'),
      '#description' => $this->t("Maximum time allowed since the last successful cron run before considering it failed, in minutes. This should be greater than your site's cron frequency. For example, if your cron runs every 15 minutes, set this to 20 or higher."),
      '#config_target' => 'cron_fail_alert.settings:tolerance',
      '#step' => 1,
      '#min' => 1,
      '#max' => 10080,
      '#field_suffix' => $this->t('minutes'),
    ];

    // Email notification settings.
    $form['notification'] = [
      '#type' => 'details',
      '#title' => $this->t('Email notification settings'),
      '#open' => TRUE,
    ];

    $form['notification']['to'] = [
      '#type' => 'email',
      '#required' => FALSE,
      '#title' => $this->t('Recipient email address'),
      '#description' => $this->t("Email address to receive cron failure notifications. Leave empty to use the site's default email address (@default).", [
        '@default' => $this->configFactory->get('system.site')->get('mail') ?? 'not configured',
      ]),
      '#config_target' => 'cron_fail_alert.settings:to',
    ];

    $form['notification']['subject'] = [
      '#type' => 'textfield',
      '#required' => TRUE,
      '#title' => $this->t('Email subject'),
      '#description' => $this->t('Subject line for the failure notification email. The site name will be automatically appended.'),
      '#config_target' => 'cron_fail_alert.settings:subject',
      '#maxlength' => 255,
    ];

    $form['notification']['message'] = [
      '#type' => 'textarea',
      '#required' => TRUE,
      '#title' => $this->t('Email message'),
      '#description' => $this->t('Body of the failure notification email. Available tokens: <code>@minutes</code> (minutes since last cron run) and <code>:site</code> (site URL).'),
      '#config_target' => 'cron_fail_alert.settings:message',
      '#rows' => 5,
    ];

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

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state): void {
    // Validate email address only when provided; empty falls back to site mail.
    $email_address = $form_state->getValue('to');
    if (!empty($email_address) && !$this->emailValidator->isValid($email_address)) {
      $form_state->setErrorByName('to', $this->t('The email address %mail is not valid.', ['%mail' => $email_address]));
    }

    // Validate that tolerance is greater than frequency.
    $frequency = (int) $form_state->getValue('frequency');
    $tolerance = (int) $form_state->getValue('tolerance');
    if ($tolerance <= $frequency) {
      $form_state->setErrorByName('tolerance', $this->t('The cron failure tolerance must be greater than the check frequency to avoid false positives.'));
    }

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

}
