<?php

declare(strict_types=1);

namespace Drupal\flowdrop_trigger\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\flowdrop_orchestration\Service\Orchestrator\OrchestratorPluginManager;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * General settings form for FlowDrop Trigger module.
 *
 * Provides global configuration options that apply across all trigger
 * categories, such as default orchestrator and logging settings.
 *
 * Category-specific settings are managed in dedicated forms:
 * - TriggerSettingsEntityForm: Entity event settings
 * - TriggerSettingsFormEventsForm: Form event settings
 * - TriggerSettingsUserForm: User event settings
 *
 * @see \Drupal\flowdrop_trigger\Form\TriggerSettingsEntityForm
 * @see \Drupal\flowdrop_trigger\Form\TriggerSettingsFormEventsForm
 * @see \Drupal\flowdrop_trigger\Form\TriggerSettingsUserForm
 *
 * @internal This class is not part of the public API and may change without notice.
 */
final class TriggerSettingsGeneralForm extends ConfigFormBase {

  /**
   * The orchestrator plugin manager.
   *
   * @var \Drupal\flowdrop_orchestration\Service\Orchestrator\OrchestratorPluginManager
   */
  protected OrchestratorPluginManager $orchestratorManager;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): static {
    $instance = parent::create($container);
    $instance->orchestratorManager = $container->get("flowdrop_orchestration.plugin_manager");
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return "flowdrop_trigger_settings_general";
  }

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

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

    $form["description"] = [
      "#type" => "markup",
      "#markup" => "<p>" . $this->t("Configure general settings for FlowDrop triggers. Category-specific settings (Entity, Form, User events) are available in their respective tabs.") . "</p>",
    ];

    // =========================================================================
    // Orchestrator Settings.
    // =========================================================================
    $form["orchestrator"] = [
      "#type" => "details",
      "#title" => $this->t("Orchestrator Settings"),
      "#open" => TRUE,
    ];

    $form["orchestrator"]["default_orchestrator"] = [
      "#type" => "radios",
      "#title" => $this->t("Default Orchestrator"),
      "#description" => $this->t("Select the default orchestrator type for workflow execution. Individual triggers can override this setting."),
      "#options" => $this->getOrchestratorOptions(),
      "#default_value" => $config->get("default_orchestrator") ?? "flowdrop_runtime:asynchronous",
    ];

    // =========================================================================
    // Logging Settings.
    // =========================================================================
    $form["logging"] = [
      "#type" => "details",
      "#title" => $this->t("Logging Settings"),
      "#open" => TRUE,
    ];

    $form["logging"]["log_level"] = [
      "#type" => "select",
      "#title" => $this->t("Log Level"),
      "#description" => $this->t("Set the verbosity of trigger-related log messages."),
      "#options" => [
        "debug" => $this->t("Debug - All messages including detailed debugging"),
        "info" => $this->t("Info - General operational information"),
        "warning" => $this->t("Warning - Potential issues and warnings"),
        "error" => $this->t("Error - Only error messages"),
      ],
      "#default_value" => $config->get("log_level") ?? "info",
    ];

    // =========================================================================
    // Advanced Settings.
    // =========================================================================
    $form["advanced"] = [
      "#type" => "details",
      "#title" => $this->t("Advanced Settings"),
      "#open" => FALSE,
    ];

    $form["advanced"]["info"] = [
      "#type" => "markup",
      "#markup" => "<p>" . $this->t("Advanced settings for fine-tuning trigger behavior. Use with caution.") . "</p>",
    ];

    // Placeholder for future advanced settings.
    $form["advanced"]["placeholder"] = [
      "#type" => "markup",
      "#markup" => "<p><em>" . $this->t("Additional advanced settings will be available in future versions.") . "</em></p>",
    ];

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

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    $config = $this->config("flowdrop_trigger.settings");

    $config->set("default_orchestrator", $form_state->getValue("default_orchestrator"));
    $config->set("log_level", $form_state->getValue("log_level"));

    $config->save();

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

  /**
   * Get orchestrator options dynamically from registered orchestrators.
   *
   * Retrieves all orchestrator plugins from the plugin manager and builds
   * a radio options array with descriptions.
   *
   * @return array<string, string>
   *   Options array with orchestrator IDs as keys and labels as values.
   */
  protected function getOrchestratorOptions(): array {
    $options = [];

    // Get all registered orchestrators from the plugin manager.
    $definitions = $this->orchestratorManager->getDefinitions();

    foreach ($definitions as $id => $definition) {
      $label = $definition["label"] ?? ucfirst(str_replace("_", " ", $id));
      $description = $definition["description"] ?? "";

      // Convert TranslatableMarkup to string if needed.
      $labelStr = $label instanceof \Stringable ? (string) $label : $label;

      // Add description to label for radio buttons if available.
      if (!empty($description)) {
        $options[$id] = sprintf("%s - %s", $labelStr, $description);
      }
      else {
        $options[$id] = $labelStr;
      }
    }

    return $options;
  }

}
