<?php

declare(strict_types=1);

namespace Drupal\flowdrop_memory\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\TaggedContainerInterface;

/**
 * Settings form for FlowDrop Memory backend configuration.
 *
 * Allows administrators to configure backend-specific options such as the
 * cache bin used by the cached backend. The backend itself is selected
 * per node type when configuring a workflow node.
 *
 * @internal
 */
final class MemorySettingsForm extends ConfigFormBase {

  /**
   * Available cache bin names, keyed by name.
   *
   * @var array<string, string>
   */
  private array $cacheBinOptions;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): static {
    $instance = parent::create($container);
    $instance->cacheBinOptions = $instance->buildCacheBinOptions($container);
    return $instance;
  }

  /**
   * Builds a select list of registered cache bins from the service container.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   The service container.
   *
   * @return array<string, string>
   *   Cache bin names as both key and display value.
   */
  private function buildCacheBinOptions(ContainerInterface $container): array {
    $bins = [];
    if ($container instanceof TaggedContainerInterface) {
      foreach (array_keys($container->findTaggedServiceIds('cache.bin')) as $serviceId) {
        $bin = substr($serviceId, strlen('cache.'));
        $bins[$bin] = $bin;
      }
    }
    $bins['default'] = 'default';
    ksort($bins);
    return $bins;
  }

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

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

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

    $form['backend_config'] = [
      '#type'  => 'details',
      '#title' => $this->t('Backend Configuration'),
      '#open'  => TRUE,
      '#tree'  => TRUE,
    ];

    $form['backend_config']['cached'] = [
      '#type'  => 'fieldset',
      '#title' => $this->t('Cached Backend'),
    ];
    $form['backend_config']['cached']['cache_bin'] = [
      '#type'          => 'select',
      '#title'         => $this->t('Cache Bin'),
      '#description'   => $this->t('The Drupal cache bin used by the cached backend. Only registered cache bins are listed.'),
      '#options'       => $this->cacheBinOptions,
      '#default_value' => $config->get('backend_config.cached.cache_bin') ?? 'default',
    ];

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

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    $this->config('flowdrop_memory.settings')
      ->set('backend_config.cached.cache_bin', $form_state->getValue(['backend_config', 'cached', 'cache_bin']))
      ->save();

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

}
