<?php

namespace Drupal\eb\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\eb\Service\DiscoveryServiceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Configure Entity Builder settings.
 */
class EbSettingsForm extends ConfigFormBase {

  /**
   * Constructor.
   *
   * @param \Drupal\eb\Service\DiscoveryServiceInterface $discoveryService
   *   The discovery service.
   */
  public function __construct(
    protected DiscoveryServiceInterface $discoveryService,
  ) {}

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): self {
    return new self(
      $container->get('eb.discovery_service'),
    );
  }

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

  /**
   * {@inheritdoc}
   *
   * @return array<string>
   *   An array of configuration object names that are editable.
   */
  protected function getEditableConfigNames(): array {
    return ['eb.settings'];
  }

  /**
   * {@inheritdoc}
   *
   * @param array<string, mixed> $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @return array<string, mixed>
   *   The form structure.
   */
  public function buildForm(array $form, FormStateInterface $form_state): array {
    $config = $this->config('eb.settings');

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

    $form['general']['debug_mode'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable debug mode'),
      '#description' => $this->t('When enabled, additional debug information is logged and displayed.'),
      '#default_value' => $config->get('debug_mode'),
    ];

    $form['general']['log_operations'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Log all operations'),
      '#description' => $this->t('Log all Entity Builder operations to the watchdog.'),
      '#default_value' => $config->get('log_operations'),
    ];

    $form['general']['enable_preview'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable preview before execution'),
      '#description' => $this->t('Show a preview of operations before they are executed.'),
      '#default_value' => $config->get('enable_preview'),
    ];

    // Build checkbox options from all fieldable entity types.
    $options = [];
    foreach ($this->discoveryService->getFieldableEntityTypes() as $entityTypeId => $entityType) {
      $options[$entityTypeId] = $entityType['label'] . ' (' . $entityTypeId . ')';
    }
    asort($options);

    // Get the currently configured supported types.
    $supported = $config->get('supported_entity_types') ?? [];

    $form['general']['supported_entity_types'] = [
      '#type' => 'checkboxes',
      '#title' => $this->t('Supported entity types'),
      '#description' => $this->t('Select which fieldable entity types are available for use in Entity Builder definitions.'),
      '#options' => $options,
      '#default_value' => $supported,
    ];

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

    $form['import']['import_max_file_size'] = [
      '#type' => 'number',
      '#title' => $this->t('Maximum import file size'),
      '#description' => $this->t('Maximum file size for YAML imports. Default: 5 MB.'),
      '#default_value' => $config->get('import_max_file_size'),
      '#min' => 1,
      '#max' => 50,
      '#step' => 1,
      '#field_suffix' => $this->t('MB'),
    ];

    $form['import']['import_history_retention_days'] = [
      '#type' => 'number',
      '#title' => $this->t('Import history retention'),
      '#description' => $this->t('Number of days to keep import history records. Use 0 to keep indefinitely.'),
      '#default_value' => $config->get('import_history_retention_days'),
      '#min' => 0,
      '#max' => 365,
      '#field_suffix' => $this->t('days'),
    ];

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

    $form['rollback']['rollback_retention_days'] = [
      '#type' => 'number',
      '#title' => $this->t('Rollback retention'),
      '#description' => $this->t('Number of days to keep rollback data. Use 0 to keep indefinitely.'),
      '#default_value' => $config->get('rollback_retention_days'),
      '#min' => 0,
      '#max' => 365,
      '#field_suffix' => $this->t('days'),
    ];

    // Pagination.
    $form['pagination'] = [
      '#type' => 'details',
      '#title' => $this->t('Pagination'),
      '#open' => FALSE,
    ];

    $form['pagination']['default_items_per_page'] = [
      '#type' => 'select',
      '#title' => $this->t('Default items per page'),
      '#description' => $this->t('Default number of items to display per page in lists.'),
      '#default_value' => $config->get('default_items_per_page'),
      '#options' => [
        25 => '25',
        50 => '50',
        100 => '100',
        250 => '250',
        500 => '500',
      ],
    ];

    // Processing limits.
    $form['limits'] = [
      '#type' => 'details',
      '#title' => $this->t('Processing Limits'),
      '#description' => $this->t('These limits protect against resource exhaustion. Only adjust if you understand the implications.'),
      '#open' => FALSE,
    ];

    $form['limits']['batch_size'] = [
      '#type' => 'number',
      '#title' => $this->t('Batch size'),
      '#description' => $this->t('Number of operations to process in each batch when using batch processing.'),
      '#default_value' => $config->get('batch_size'),
      '#min' => 10,
      '#max' => 500,
    ];

    $form['limits']['batch_threshold'] = [
      '#type' => 'number',
      '#title' => $this->t('Batch processing threshold'),
      '#description' => $this->t('Number of operations above which batch processing is used instead of direct execution.'),
      '#default_value' => $config->get('batch_threshold'),
      '#min' => 10,
      '#max' => 500,
    ];

    $form['limits']['max_recursion_depth'] = [
      '#type' => 'number',
      '#title' => $this->t('Maximum recursion depth'),
      '#description' => $this->t('Maximum depth for recursive data processing operations.'),
      '#default_value' => $config->get('max_recursion_depth'),
      '#min' => 5,
      '#max' => 50,
    ];

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

  /**
   * {@inheritdoc}
   *
   * @param array<string, mixed> $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    // Filter checked entity types to get only the selected values.
    $supportedEntityTypes = array_values(array_filter(
      $form_state->getValue('supported_entity_types') ?? []
    ));

    $this->config('eb.settings')
      // General.
      ->set('debug_mode', (bool) $form_state->getValue('debug_mode'))
      ->set('log_operations', (bool) $form_state->getValue('log_operations'))
      ->set('enable_preview', (bool) $form_state->getValue('enable_preview'))
      // Import.
      ->set('import_max_file_size', (int) $form_state->getValue('import_max_file_size'))
      ->set('import_history_retention_days', (int) $form_state->getValue('import_history_retention_days'))
      // Rollback.
      ->set('rollback_retention_days', (int) $form_state->getValue('rollback_retention_days'))
      // Pagination.
      ->set('default_items_per_page', (int) $form_state->getValue('default_items_per_page'))
      // Limits.
      ->set('batch_size', (int) $form_state->getValue('batch_size'))
      ->set('batch_threshold', (int) $form_state->getValue('batch_threshold'))
      ->set('max_recursion_depth', (int) $form_state->getValue('max_recursion_depth'))
      // Entity type filtering.
      ->set('supported_entity_types', $supportedEntityTypes)
      ->save();

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

}
