<?php

declare(strict_types=1);

namespace Drupal\flowdrop_trigger\Form\Trait;

use Drupal\flowdrop_trigger\Enum\EventCategory;

/**
 * Provides condition form builder for the trigger config form.
 *
 * Extracts the dynamic conditions form building logic that renders
 * different form elements based on event type category (entity, user,
 * form, cron).
 *
 * Requirements for using this trait:
 * - The class must use TriggerFormOptionsTrait (for options methods)
 * - The class must have an $eventTypeManager property
 *   of type EventTypePluginManager
 * - The class must implement t() for translation
 *
 * @internal This trait is not part of the public API and may change without notice.
 */
trait TriggerConditionsFormTrait {

  /**
   * Builds condition form elements based on event type category.
   *
   * Different event types require different condition fields:
   * - Entity events: entity_types, bundles
   * - User events: roles
   * - Form events: form_ids
   * - Cron events: no conditions.
   *
   * @param array<string, mixed> &$form
   *   The form container to add elements to.
   * @param string|null $eventType
   *   The selected event type plugin ID.
   * @param array<string, mixed> $conditions
   *   Current condition values from the entity.
   */
  protected function buildConditionsForm(
    array &$form,
    ?string $eventType,
    array $conditions,
  ): void {
    // Get event type category.
    $category = $this->getEventTypeCategory($eventType);

    switch ($category) {
      case "entity":
        $form["entity_types"] = [
          "#type" => "select",
          "#title" => $this->t("Entity Types"),
          "#options" => $this->getEntityTypeOptions(),
          "#default_value" => $conditions["entity_types"] ?? [],
          "#multiple" => TRUE,
          "#description" => $this->t("Filter by entity types. Leave empty for all."),
        ];

        // Handle bundles - can be array (from entity) or string
        // (from form input).
        $bundlesValue = $conditions["bundles"] ?? [];
        if (is_array($bundlesValue)) {
          $bundlesValue = implode(", ", $bundlesValue);
        }

        $form["bundles"] = [
          "#type" => "textfield",
          "#title" => $this->t("Bundles"),
          "#default_value" => $bundlesValue,
          "#description" => $this->t("Comma-separated list of bundles. Leave empty for all."),
        ];
        break;

      case "user":
        $form["roles"] = [
          "#type" => "select",
          "#title" => $this->t("Roles"),
          "#options" => $this->getRoleOptions(),
          "#default_value" => $conditions["roles"] ?? [],
          "#multiple" => TRUE,
          "#description" => $this->t("Filter by user roles. Leave empty for all."),
        ];
        break;

      case "form":
        // Handle form_ids - can be array (from entity) or string
        // (from form input).
        $formIdsValue = $conditions["form_ids"] ?? [];
        if (is_array($formIdsValue)) {
          $formIdsValue = implode("\n", $formIdsValue);
        }

        $form["form_ids"] = [
          "#type" => "textarea",
          "#title" => $this->t("Form IDs"),
          "#default_value" => $formIdsValue,
          "#description" => $this->t("One form ID per line. Leave empty for all forms."),
          "#rows" => 4,
        ];
        break;

      case "cron":
        // Cron schedule configuration.
        $cronSchedule = $conditions["cron_schedule"] ?? [];

        $form["cron_schedule"] = [
          "#type" => "container",
          "#tree" => TRUE,
        ];

        $form["cron_schedule"]["mode"] = [
          "#type" => "radios",
          "#title" => $this->t("Schedule Mode"),
          "#description" => $this->t("Choose between simple interval-based scheduling or advanced cron expressions."),
          "#options" => [
            "simple" => $this->t("Simple (Interval)"),
            "advanced" => $this->t("Advanced (Cron Expression)"),
          ],
          "#default_value" => $cronSchedule["mode"] ?? "simple",
        ];

        $form["cron_schedule"]["schedule_type"] = [
          "#type" => "radios",
          "#title" => $this->t("Schedule Type"),
          "#description" => $this->t("Recurring runs continuously, One-shot runs a limited number of times."),
          "#options" => [
            "recurring" => $this->t("Recurring"),
            "one_shot" => $this->t("One-shot (Limited Runs)"),
          ],
          "#default_value" => $cronSchedule["schedule_type"] ?? "recurring",
        ];

        // Simple mode settings.
        $form["cron_schedule"]["simple_settings"] = [
          "#type" => "fieldset",
          "#title" => $this->t("Interval Settings"),
          "#description" => $this->t("Configure interval-based scheduling (used when mode is 'Simple')."),
          "#states" => [
            "visible" => [
              ":input[name=\"conditions[cron_schedule][mode]\"]" => ["value" => "simple"],
            ],
          ],
        ];

        $form["cron_schedule"]["simple_settings"]["interval"] = [
          "#type" => "select",
          "#title" => $this->t("Run Interval"),
          "#description" => $this->t("How often the trigger should fire."),
          "#options" => [
            "every_minute" => $this->t("Every minute"),
            "every_5_minutes" => $this->t("Every 5 minutes"),
            "every_15_minutes" => $this->t("Every 15 minutes"),
            "every_30_minutes" => $this->t("Every 30 minutes"),
            "every_hour" => $this->t("Every hour"),
            "every_2_hours" => $this->t("Every 2 hours"),
            "every_6_hours" => $this->t("Every 6 hours"),
            "every_12_hours" => $this->t("Every 12 hours"),
            "daily" => $this->t("Daily (24 hours)"),
            "weekly" => $this->t("Weekly (7 days)"),
            "custom" => $this->t("Custom (specify seconds)"),
          ],
          "#default_value" => $cronSchedule["interval"] ?? "every_hour",
        ];

        $form["cron_schedule"]["simple_settings"]["custom_interval"] = [
          "#type" => "number",
          "#title" => $this->t("Custom Interval (seconds)"),
          "#description" => $this->t("Custom interval in seconds when 'Custom' is selected. Minimum: 60 seconds."),
          "#default_value" => $cronSchedule["custom_interval"] ?? 3600,
          "#min" => 60,
          "#max" => 2592000,
          "#states" => [
            "visible" => [
              ":input[name=\"conditions[cron_schedule][simple_settings][interval]\"]" => ["value" => "custom"],
            ],
          ],
        ];

        $form["cron_schedule"]["simple_settings"]["time_window_start"] = [
          "#type" => "textfield",
          "#title" => $this->t("Time Window Start"),
          "#description" => $this->t("Optional start time for allowed execution window (HH:MM format, e.g., 09:00). Leave empty to allow any time."),
          "#default_value" => $cronSchedule["time_window_start"] ?? "",
          "#size" => 10,
          "#placeholder" => "09:00",
        ];

        $form["cron_schedule"]["simple_settings"]["time_window_end"] = [
          "#type" => "textfield",
          "#title" => $this->t("Time Window End"),
          "#description" => $this->t("Optional end time for allowed execution window (HH:MM format, e.g., 17:00). Leave empty to allow any time."),
          "#default_value" => $cronSchedule["time_window_end"] ?? "",
          "#size" => 10,
          "#placeholder" => "17:00",
        ];

        $form["cron_schedule"]["simple_settings"]["days_of_week"] = [
          "#type" => "checkboxes",
          "#title" => $this->t("Days of Week"),
          "#description" => $this->t("Select which days the trigger is allowed to fire. Leave all unchecked for all days."),
          "#options" => [
            "0" => $this->t("Sunday"),
            "1" => $this->t("Monday"),
            "2" => $this->t("Tuesday"),
            "3" => $this->t("Wednesday"),
            "4" => $this->t("Thursday"),
            "5" => $this->t("Friday"),
            "6" => $this->t("Saturday"),
          ],
          "#default_value" => array_map("strval", $cronSchedule["days_of_week"] ?? []),
        ];

        // Advanced mode settings.
        $form["cron_schedule"]["advanced_settings"] = [
          "#type" => "fieldset",
          "#title" => $this->t("Cron Expression Settings"),
          "#description" => $this->t("Configure using standard cron expressions (used when mode is 'Advanced')."),
          "#states" => [
            "visible" => [
              ":input[name=\"conditions[cron_schedule][mode]\"]" => ["value" => "advanced"],
            ],
          ],
        ];

        $form["cron_schedule"]["advanced_settings"]["cron_expression"] = [
          "#type" => "textfield",
          "#title" => $this->t("Cron Expression"),
          "#description" => $this->t("Standard cron expression (minute hour day-of-month month day-of-week). Examples: '0 * * * *' (hourly), '0 9 * * 1-5' (weekdays at 9am), '0 0 1 * *' (monthly)."),
          "#default_value" => $cronSchedule["cron_expression"] ?? "0 * * * *",
          "#size" => 30,
          "#placeholder" => "0 * * * *",
        ];

        $form["cron_schedule"]["advanced_settings"]["cron_examples"] = [
          "#type" => "details",
          "#title" => $this->t("Cron Expression Examples"),
          "#open" => FALSE,
        ];

        $form["cron_schedule"]["advanced_settings"]["cron_examples"]["list"] = [
          "#type" => "markup",
          "#markup" => "<ul>" .
          "<li><code>* * * * *</code> - " . $this->t("Every minute") . "</li>" .
          "<li><code>*/5 * * * *</code> - " . $this->t("Every 5 minutes") . "</li>" .
          "<li><code>0 * * * *</code> - " . $this->t("Every hour (at minute 0)") . "</li>" .
          "<li><code>0 */2 * * *</code> - " . $this->t("Every 2 hours") . "</li>" .
          "<li><code>0 9 * * *</code> - " . $this->t("Daily at 9:00 AM") . "</li>" .
          "<li><code>0 0 * * *</code> - " . $this->t("Daily at midnight") . "</li>" .
          "<li><code>0 9 * * 1-5</code> - " . $this->t("Weekdays at 9:00 AM") . "</li>" .
          "<li><code>0 0 * * 0</code> - " . $this->t("Weekly on Sunday at midnight") . "</li>" .
          "<li><code>0 0 1 * *</code> - " . $this->t("Monthly on the 1st at midnight") . "</li>" .
          "</ul>",
        ];

        // Common settings for both modes.
        $form["cron_schedule"]["common_settings"] = [
          "#type" => "fieldset",
          "#title" => $this->t("Additional Settings"),
        ];

        $form["cron_schedule"]["common_settings"]["max_executions"] = [
          "#type" => "number",
          "#title" => $this->t("Maximum Executions"),
          "#description" => $this->t("Maximum number of times to execute. Set to 0 for unlimited. The trigger will be disabled after reaching this limit."),
          "#default_value" => $cronSchedule["max_executions"] ?? 0,
          "#min" => 0,
        ];

        $form["cron_schedule"]["common_settings"]["timezone"] = [
          "#type" => "select",
          "#title" => $this->t("Timezone"),
          "#description" => $this->t("Timezone for schedule calculations. Leave empty to use site default."),
          "#options" => ["" => $this->t("- Use site default -")] + $this->getTimezoneOptions(),
          "#default_value" => $cronSchedule["timezone"] ?? "",
        ];

        break;

      default:
        // For unknown categories, show a generic message.
        $form["no_conditions"] = [
          "#type" => "markup",
          "#markup" => "<p><em>" . $this->t("Please select an event type to configure conditions.") . "</em></p>",
        ];
        break;
    }
  }

  /**
   * Gets the category for a given event type.
   *
   * @param string|null $eventType
   *   The event type plugin ID.
   *
   * @return string|null
   *   The event type category, or NULL if not found.
   */
  protected function getEventTypeCategory(?string $eventType): ?string {
    if (empty($eventType)) {
      return NULL;
    }

    $definition = $this->eventTypeManager->getDefinition($eventType, FALSE);
    if ($definition === NULL) {
      return NULL;
    }

    return EventCategory::toString($definition["category"] ?? "entity");
  }

}
