<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media\Form\SettingsTab;

use Drupal\Core\Config\Config;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\ffmpeg_media\Service\FFmpegExecutorInterface;
use Drupal\ffmpeg_media\Service\FormatterSettingsResolverInterface;
use Drupal\ffmpeg_media\Service\HardwareDetectorInterface;
use Drupal\ffmpeg_media\Service\ProfileManagerInterface;

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

  use StringTranslationTrait;

  /**
   * Constructs a StatusSettingsBuilder.
   *
   * @param \Drupal\ffmpeg_media\Service\FFmpegExecutorInterface $ffmpegExecutor
   *   FFmpeg executor service.
   * @param \Drupal\ffmpeg_media\Service\HardwareDetectorInterface $hardwareDetector
   *   Hardware detector service.
   * @param \Drupal\ffmpeg_media\Service\ProfileManagerInterface $profileManager
   *   Profile manager service.
   * @param \Drupal\ffmpeg_media\Service\FormatterSettingsResolverInterface $formatterSettingsResolver
   *   Formatter settings resolver service.
   */
  public function __construct(
    protected readonly FFmpegExecutorInterface $ffmpegExecutor,
    protected readonly HardwareDetectorInterface $hardwareDetector,
    protected readonly ProfileManagerInterface $profileManager,
    protected readonly FormatterSettingsResolverInterface $formatterSettingsResolver,
  ) {
  }

  /**
   * Builds the status 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['status'] = [
      '#type' => 'details',
      '#title' => $this->t('Status'),
      '#description' => $this->t('System health overview: FFmpeg availability, version, and detected hardware encoders.'),
      '#group' => 'settings_tabs',
      '#open' => TRUE,
    ];

    $ffmpegAvailable = $this->ffmpegExecutor->isAvailable();
    $form['status']['ffmpeg_status'] = [
      '#type' => 'item',
      '#title' => $this->t('FFmpeg'),
      'status' => [
        '#type' => 'html_tag',
        '#tag' => 'span',
        '#attributes' => ['class' => [$ffmpegAvailable ? 'color-success' : 'color-error']],
        '#value' => $ffmpegAvailable
          ? $this->t('Available (Version: @version)', ['@version' => $this->ffmpegExecutor->getVersion() ?? $this->t('Unknown')])
          : $this->t('Not available'),
      ],
    ];

    $capabilities = $this->hardwareDetector->getCapabilities();
    if (!empty($capabilities['available_encoders'])) {
      $form['status']['encoders'] = [
        '#type' => 'item',
        '#title' => $this->t('Hardware Encoders'),
        '#plain_text' => implode(', ', $capabilities['available_encoders']),
      ];
    }

    // Setup progress checklist — shown until all required steps are complete.
    $this->buildSetupProgress($form, $config, $ffmpegAvailable);

    $form['status']['quickstart'] = [
      '#type' => 'details',
      '#title' => $this->t('Quick start'),
      '#open' => !$ffmpegAvailable,
      'steps' => [
        '#theme' => 'item_list',
        '#list_type' => 'ol',
        '#items' => [
          $this->t('Ensure FFmpeg and ffprobe paths are configured in the <strong>FFmpeg</strong> tab.'),
          $this->t('Add the <em>FFmpeg Media: Converted video</em> formatter to a video field under <strong>Manage Display</strong>.'),
          $this->t('Enable <em>Auto convert</em> and select a conversion profile in the formatter settings.'),
        ],
      ],
    ];
  }

  /**
   * Builds the setup progress checklist.
   *
   * Shown only when at least one required configuration step is incomplete.
   * Hidden entirely for established installations where everything is set up.
   *
   * @param array<string, mixed> $form
   *   Form structure, passed by reference.
   * @param \Drupal\Core\Config\Config $config
   *   Module configuration.
   * @param bool $ffmpegAvailable
   *   Whether FFmpeg binary is detected.
   */
  private function buildSetupProgress(array &$form, Config $config, bool $ffmpegAvailable): void {
    $outputDir = (string) ($config->get('output_directory') ?? '');
    $hasProfiles = $this->profileManager->getAllProfiles() !== [];
    $hasFormatter = $this->formatterSettingsResolver->hasAnyConfiguration();

    $checks = [
      ['label' => $this->t('FFmpeg binary detected'), 'done' => $ffmpegAvailable],
      ['label' => $this->t('Output directory configured'), 'done' => $outputDir !== ''],
      ['label' => $this->t('At least one conversion profile exists'), 'done' => $hasProfiles],
      ['label' => $this->t('Video formatter assigned to a field'), 'done' => $hasFormatter],
    ];

    $allDone = array_all($checks, static fn(array $c): bool => $c['done']);
    if ($allDone) {
      return;
    }

    $items = array_map(static function (array $check): array {
      $icon = $check['done'] ? "\u{2713}" : "\u{2717}";
      $class = $check['done'] ? 'color-success' : 'color-warning';
      return [
        '#markup' => '<span class="' . $class . '">' . $icon . '</span> ' . $check['label'],
      ];
    }, $checks);

    $form['status']['setup_progress'] = [
      '#type' => 'details',
      '#title' => $this->t('Setup progress'),
      '#open' => TRUE,
      '#weight' => -10,
      'checklist' => [
        '#theme' => 'item_list',
        '#items' => $items,
      ],
    ];
  }

}
