<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media\Form\SettingsTab;

use Drupal\Core\Config\Config;
use Drupal\Core\State\StateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Builds the security settings tab for the FFmpeg Media settings form.
 *
 * @internal
 */
final class SecuritySettingsBuilder {

  use StringTranslationTrait;

  /**
   * Constructs a SecuritySettingsBuilder.
   *
   * @param \Drupal\Core\State\StateInterface $state
   *   State storage for non-exportable secrets.
   */
  public function __construct(
    protected readonly StateInterface $state,
  ) {
  }

  /**
   * Builds the security section render array.
   *
   * @param array<string, mixed> $form
   *   Form structure, passed by reference.
   * @param \Drupal\Core\Config\Config $config
   *   Module configuration.
   */
  public function build(array &$form, Config $config): void {
    $form['security'] = [
      '#type' => 'details',
      '#title' => $this->t('Security'),
      '#description' => $this->t('Health probe authentication settings. Protects liveness and readiness endpoints from unauthorized access.'),
      '#group' => 'settings_tabs',
      '#open' => FALSE,
    ];

    $form['security']['health_probe_token_required'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Require health probe token'),
      '#description' => $this->t('When enabled, liveness and readiness probes require a valid token in the X-FFmpeg-Health-Token header. Recommended for production.'),
      '#default_value' => (bool) ($config->get('health_probe_token_required') ?? FALSE),
    ];

    $existingToken = (string) ($this->state->get('ffmpeg_media.health_probe_token') ?? '');
    $form['security']['health_probe_token'] = [
      '#type' => 'password',
      '#title' => $this->t('Health probe token'),
      '#description' => $existingToken !== ''
        ? $this->t('A token is currently set. Leave empty to keep the existing token, or enter a new value to replace it. Can be overridden via FFMPEG_HEALTH_PROBE_TOKEN environment variable.')
        : $this->t('Shared secret for probe authentication. Can be overridden via FFMPEG_HEALTH_PROBE_TOKEN environment variable.'),
      '#maxlength' => 255,
      '#attributes' => ['autocomplete' => 'off'],
      '#states' => [
        'visible' => [
          ':input[name="health_probe_token_required"]' => ['checked' => TRUE],
        ],
      ],
    ];

    // Rate limiting settings.
    $form['security']['rate_limit_requests'] = [
      '#type' => 'number',
      '#title' => $this->t('Rate limit (requests per window)'),
      '#description' => $this->t('Maximum number of API/AJAX requests allowed per client IP per time window.'),
      '#default_value' => $config->get('rate_limit_requests') ?? 60,
      '#min' => 1,
      '#max' => 10000,
      '#required' => TRUE,
    ];

    $form['security']['rate_limit_window'] = [
      '#type' => 'number',
      '#title' => $this->t('Rate limit window (seconds)'),
      '#description' => $this->t('Time window in seconds for rate limiting. Requests exceeding the limit within this window receive a 429 response.'),
      '#default_value' => $config->get('rate_limit_window') ?? 60,
      '#min' => 1,
      '#max' => 3600,
      '#required' => TRUE,
    ];

    $envToken = getenv('FFMPEG_HEALTH_PROBE_TOKEN');
    if ($envToken !== FALSE && trim($envToken) !== '') {
      $form['security']['health_probe_env_notice'] = [
        '#type' => 'container',
        '#attributes' => ['class' => ['messages', 'messages--warning']],
        '#states' => [
          'visible' => [
            ':input[name="health_probe_token_required"]' => ['checked' => TRUE],
          ],
        ],
        'message' => [
          '#type' => 'html_tag',
          '#tag' => 'div',
          '#value' => $this->t('The FFMPEG_HEALTH_PROBE_TOKEN environment variable is set and will override the token configured above at runtime.'),
        ],
      ];
    }
  }

}
