<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media_ui\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Settings form for FFmpeg Media UI.
 */
final class SettingsForm extends ConfigFormBase {

  /**
   * {@inheritdoc}
   */
  #[\Override]
  public function getFormId(): string {
    return 'ffmpeg_media_ui_settings';
  }

  /**
   * {@inheritdoc}
   *
   * @return array<int, string>
   *   An array of editable config names.
   */
  #[\Override]
  protected function getEditableConfigNames(): array {
    return ['ffmpeg_media_ui.settings'];
  }

  /**
   * {@inheritdoc}
   *
   * @return array<string, mixed>
   *   The form render array.
   */
  #[\Override]
  public function buildForm(array $form, FormStateInterface $form_state): array {
    $config = $this->config('ffmpeg_media_ui.settings');

    $form['poster_settings'] = [
      '#type' => 'details',
      '#title' => $this->t('Poster Selection'),
      '#open' => TRUE,
    ];

    $form['poster_settings']['poster_thumbnail_count'] = [
      '#type' => 'number',
      '#title' => $this->t('Number of thumbnail options'),
      '#min' => 4,
      '#max' => 24,
      '#default_value' => $config->get('poster_thumbnail_count') ?? 12,
      '#description' => $this->t('Number of thumbnails to show when selecting a poster frame.'),
    ];

    $form['poster_settings']['poster_thumbnail_width'] = [
      '#type' => 'number',
      '#title' => $this->t('Thumbnail preview width'),
      '#min' => 80,
      '#max' => 320,
      '#default_value' => $config->get('poster_thumbnail_width') ?? 160,
      '#description' => $this->t('Width of thumbnail previews in pixels.'),
      '#field_suffix' => 'px',
    ];

    $form['display_settings'] = [
      '#type' => 'details',
      '#title' => $this->t('Display Settings'),
      '#open' => FALSE,
    ];

    $form['display_settings']['video_preview_enabled'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable video preview player'),
      '#default_value' => $config->get('video_preview_enabled') ?? TRUE,
      '#description' => $this->t('Show a video player for previewing source files.'),
    ];

    $form['display_settings']['show_technical_details'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Show technical details'),
      '#default_value' => $config->get('show_technical_details') ?? TRUE,
      '#description' => $this->t('Display codec, bitrate, and other technical information.'),
    ];

    $form['display_settings']['dashboard_items_per_page'] = [
      '#type' => 'number',
      '#title' => $this->t('Dashboard items per page'),
      '#min' => 10,
      '#max' => 100,
      '#default_value' => $config->get('dashboard_items_per_page') ?? 25,
      '#description' => $this->t('Number of items to show on the dashboard.'),
    ];

    $form['display_settings']['queue_editor_list_limit'] = [
      '#type' => 'number',
      '#title' => $this->t('Queue editor list limit'),
      '#min' => 25,
      '#max' => 1000,
      '#default_value' => $config->get('queue_editor_list_limit') ?? 250,
      '#description' => $this->t('Maximum queue items returned in one queue editor request. Lower values reduce payload size on very large queues.'),
    ];

    $form['progress_settings'] = [
      '#type' => 'details',
      '#title' => $this->t('Progress Updates'),
      '#open' => FALSE,
    ];

    $form['progress_settings']['auto_refresh_interval'] = [
      '#type' => 'number',
      '#title' => $this->t('Auto-refresh interval'),
      '#min' => 0,
      '#max' => 60,
      '#default_value' => $config->get('auto_refresh_interval') ?? 5,
      '#description' => $this->t('Seconds between progress updates. Set to 0 to disable.'),
      '#field_suffix' => $this->t('seconds'),
    ];

    $form['progress_settings']['show_progress_notifications'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Show browser notifications'),
      '#default_value' => $config->get('show_progress_notifications') ?? TRUE,
      '#description' => $this->t('Show browser notifications when conversions complete.'),
    ];

    $form['progress_settings']['sse_tuning'] = [
      '#type' => 'details',
      '#title' => $this->t('Real-time stream tuning (advanced)'),
      '#open' => FALSE,
    ];

    $form['progress_settings']['sse_tuning']['sse_max_stream_duration'] = [
      '#type' => 'number',
      '#title' => $this->t('Maximum stream duration'),
      '#min' => 30,
      '#max' => 3600,
      '#default_value' => $config->get('sse_max_stream_duration') ?? 900,
      '#description' => $this->t('Maximum time in seconds for one <abbr title="Server-Sent Events">SSE</abbr> connection before timeout.'),
      '#field_suffix' => $this->t('seconds'),
    ];

    $form['progress_settings']['sse_tuning']['sse_heartbeat_interval'] = [
      '#type' => 'number',
      '#title' => $this->t('Heartbeat interval'),
      '#min' => 5,
      '#max' => 120,
      '#default_value' => $config->get('sse_heartbeat_interval') ?? 15,
      '#description' => $this->t('Seconds between SSE heartbeat comments to keep connections alive.'),
      '#field_suffix' => $this->t('seconds'),
    ];

    $form['progress_settings']['sse_tuning']['sse_min_interval_ms'] = [
      '#type' => 'number',
      '#title' => $this->t('Minimum client update interval'),
      '#min' => 250,
      '#max' => 10000,
      '#default_value' => $config->get('sse_min_interval_ms') ?? 500,
      '#description' => $this->t('Minimum allowed `interval` query value for SSE endpoints.'),
      '#field_suffix' => $this->t('ms'),
    ];

    $form['progress_settings']['sse_tuning']['sse_max_interval_ms'] = [
      '#type' => 'number',
      '#title' => $this->t('Maximum client update interval'),
      '#min' => 500,
      '#max' => 60000,
      '#default_value' => $config->get('sse_max_interval_ms') ?? 30000,
      '#description' => $this->t('Maximum allowed `interval` query value for SSE endpoints.'),
      '#field_suffix' => $this->t('ms'),
    ];

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

  /**
   * {@inheritdoc}
   */
  #[\Override]
  public function validateForm(array &$form, FormStateInterface $form_state): void {
    parent::validateForm($form, $form_state);

    $minInterval = (int) $form_state->getValue('sse_min_interval_ms');
    $maxInterval = (int) $form_state->getValue('sse_max_interval_ms');
    $queueEditorListLimit = (int) $form_state->getValue('queue_editor_list_limit');

    if ($maxInterval < $minInterval) {
      $form_state->setErrorByName(
        'sse_max_interval_ms',
        $this->t('Maximum client update interval must be greater than or equal to the minimum interval.'),
      );
    }

    if ($queueEditorListLimit < 25 || $queueEditorListLimit > 1000) {
      $form_state->setErrorByName(
        'queue_editor_list_limit',
        $this->t('Queue editor list limit must be between 25 and 1000.'),
      );
    }

    $heartbeat = (int) $form_state->getValue('sse_heartbeat_interval');
    $maxDuration = (int) $form_state->getValue('sse_max_stream_duration');
    if ($heartbeat >= $maxDuration) {
      $form_state->setErrorByName('sse_heartbeat_interval', $this->t(
        'Heartbeat interval must be less than the maximum stream duration.',
      ));
    }
  }

  /**
   * {@inheritdoc}
   */
  #[\Override]
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    $this->config('ffmpeg_media_ui.settings')
      ->set('poster_thumbnail_count', (int) $form_state->getValue('poster_thumbnail_count'))
      ->set('poster_thumbnail_width', (int) $form_state->getValue('poster_thumbnail_width'))
      ->set('video_preview_enabled', (bool) $form_state->getValue('video_preview_enabled'))
      ->set('show_technical_details', (bool) $form_state->getValue('show_technical_details'))
      ->set('dashboard_items_per_page', (int) $form_state->getValue('dashboard_items_per_page'))
      ->set('queue_editor_list_limit', (int) $form_state->getValue('queue_editor_list_limit'))
      ->set('auto_refresh_interval', (int) $form_state->getValue('auto_refresh_interval'))
      ->set('show_progress_notifications', (bool) $form_state->getValue('show_progress_notifications'))
      ->set('sse_max_stream_duration', (int) $form_state->getValue('sse_max_stream_duration'))
      ->set('sse_heartbeat_interval', (int) $form_state->getValue('sse_heartbeat_interval'))
      ->set('sse_min_interval_ms', (int) $form_state->getValue('sse_min_interval_ms'))
      ->set('sse_max_interval_ms', (int) $form_state->getValue('sse_max_interval_ms'))
      ->save();

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

}
