<?php

declare(strict_types=1);

namespace Drupal\flowdrop_trigger\Form;

use Drupal\Core\Form\FormStateInterface;

/**
 * Form events settings form for FlowDrop Trigger module.
 *
 * Allows configuration of form-related trigger settings including:
 * - Which form event types to allow (submit, validate)
 * - Which form IDs should trigger workflows (allowlist)
 * - Which form IDs should be excluded (blocklist)
 * - Additional form-specific options.
 *
 * @see \Drupal\flowdrop_trigger\Form\TriggerSettingsCategoryFormBase
 */
final class TriggerSettingsFormEventsForm extends TriggerSettingsCategoryFormBase {

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

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

  /**
   * {@inheritdoc}
   */
  protected function getCategoryId(): string {
    return "form";
  }

  /**
   * {@inheritdoc}
   */
  protected function getCategoryLabel(): string {
    return "Form";
  }

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

    $form["description"] = [
      "#type" => "markup",
      "#markup" => "<p>" . $this->t("Configure which form events should trigger workflows. These settings apply to form submission and validation events.") . "</p>",
    ];

    // =========================================================================
    // Master Toggle.
    // =========================================================================
    $form["enabled"] = $this->buildEnabledField($form_state);

    // =========================================================================
    // Event Types Section.
    // =========================================================================
    $form["event_types_wrapper"] = $this->buildEventTypesField($form_state);

    // =========================================================================
    // Form ID Allowlist.
    // =========================================================================
    $allowedFormIds = $config->get("allowed_form_ids") ?? [];

    $form["form_ids_wrapper"] = [
      "#type" => "details",
      "#title" => $this->t("Allowed Form IDs"),
      "#open" => !empty($allowedFormIds),
      "#description" => $this->t("Specify which form IDs should trigger workflows. Supports wildcards (e.g., <code>node_*_form</code>). Leave empty to allow all forms."),
      "#tree" => TRUE,
    ];

    $form["form_ids_wrapper"]["allowed_form_ids"] = [
      "#type" => "textarea",
      "#title" => $this->t("Allowed Form IDs"),
      "#description" => $this->t("Enter one form ID per line. Use <code>*</code> as a wildcard. Examples: <code>contact_message_*_form</code>, <code>user_login_form</code>, <code>node_article_form</code>"),
      "#default_value" => $this->arrayToTextarea($allowedFormIds),
      "#rows" => 6,
      "#placeholder" => "contact_message_*_form\nuser_login_form\nnode_*_edit_form",
    ];

    // =========================================================================
    // Form ID Blocklist.
    // =========================================================================
    $excludedFormIds = $config->get("excluded_form_ids") ?? [];

    $form["excluded_wrapper"] = [
      "#type" => "details",
      "#title" => $this->t("Excluded Form IDs"),
      "#open" => !empty($excludedFormIds),
      "#description" => $this->t("Specify form IDs to explicitly exclude from triggering workflows. These take precedence over the allowlist."),
      "#tree" => TRUE,
    ];

    $form["excluded_wrapper"]["excluded_form_ids"] = [
      "#type" => "textarea",
      "#title" => $this->t("Excluded Form IDs"),
      "#description" => $this->t("Enter one form ID per line. Supports wildcards. Examples: <code>search_form</code>, <code>search_block_form</code>"),
      "#default_value" => $this->arrayToTextarea($excludedFormIds),
      "#rows" => 4,
      "#placeholder" => "search_form\nsearch_block_form",
    ];

    // =========================================================================
    // Additional Options.
    // =========================================================================
    $form["options"] = [
      "#type" => "details",
      "#title" => $this->t("Data Options"),
      "#open" => FALSE,
      "#tree" => TRUE,
    ];

    $form["options"]["include_form_values"] = [
      "#type" => "checkbox",
      "#title" => $this->t("Include form values in trigger data"),
      "#description" => $this->t("When enabled, submitted form values are included in the trigger context. Disable for sensitive forms to protect privacy."),
      "#default_value" => $config->get("include_form_values") ?? TRUE,
    ];

    $form["options"]["include_form_state"] = [
      "#type" => "checkbox",
      "#title" => $this->t("Include form state in trigger data"),
      "#description" => $this->t("When enabled, the full form state object is included. This increases data size but provides more context."),
      "#default_value" => $config->get("include_form_state") ?? FALSE,
    ];

    // =========================================================================
    // Help Section.
    // =========================================================================
    $form["help"] = [
      "#type" => "details",
      "#title" => $this->t("Finding Form IDs"),
      "#open" => FALSE,
    ];

    $form["help"]["info"] = [
      "#type" => "markup",
      "#markup" => "<p>" . $this->t("To find a form ID:") . "</p><ol>" .
      "<li>" . $this->t("Enable Devel module and use <code>dpm(\$form_id)</code> in a form alter hook") . "</li>" .
      "<li>" . $this->t("Inspect the form HTML and look for the <code>id</code> attribute (convert dashes to underscores)") . "</li>" .
      "<li>" . $this->t("Check the form class name - it often matches the form ID pattern") . "</li>" .
      "</ol><p>" . $this->t("Common form ID patterns:") . "</p><ul>" .
      "<li><code>node_{bundle}_form</code> - " . $this->t("Node create forms") . "</li>" .
      "<li><code>node_{bundle}_edit_form</code> - " . $this->t("Node edit forms") . "</li>" .
      "<li><code>user_login_form</code> - " . $this->t("User login form") . "</li>" .
      "<li><code>contact_message_{bundle}_form</code> - " . $this->t("Contact forms") . "</li>" .
      "</ul>",
    ];

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

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

    $config->set("enabled", (bool) $form_state->getValue("enabled"));

    // Process event types from nested structure.
    $eventTypesWrapper = $form_state->getValue("event_types_wrapper", []);
    $allowedEventTypes = $this->filterCheckboxValues(
      $eventTypesWrapper["allowed_event_types"] ?? []
    );
    $config->set("allowed_event_types", $allowedEventTypes);

    // Process form IDs from nested structure.
    $formIdsWrapper = $form_state->getValue("form_ids_wrapper", []);
    $allowedFormIds = $this->filterTextareaValues(
      $formIdsWrapper["allowed_form_ids"] ?? ""
    );
    $config->set("allowed_form_ids", $allowedFormIds);

    // Process excluded form IDs from nested structure.
    $excludedWrapper = $form_state->getValue("excluded_wrapper", []);
    $excludedFormIds = $this->filterTextareaValues(
      $excludedWrapper["excluded_form_ids"] ?? ""
    );
    $config->set("excluded_form_ids", $excludedFormIds);

    // Process additional options from nested structure.
    $options = $form_state->getValue("options", []);
    $config->set("include_form_values", (bool) ($options["include_form_values"] ?? TRUE));
    $config->set("include_form_state", (bool) ($options["include_form_state"] ?? FALSE));

    $config->save();

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

}
