<?php

declare(strict_types=1);

namespace Drupal\flowdrop_trigger\Controller;

use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Url;
use Drupal\flowdrop_trigger\FlowDropTriggerConfigInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * List builder for FlowDrop Trigger Configuration entities.
 *
 * Provides an admin list of all trigger configurations with status,
 * event type, workflow reference, and action links.
 */
class TriggerConfigListBuilder extends ConfigEntityListBuilder {

  /**
   * The workflow entity storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected EntityStorageInterface $workflowStorage;

  /**
   * {@inheritdoc}
   */
  public static function createInstance(
    ContainerInterface $container,
    EntityTypeInterface $entity_type,
  ): static {
    $instance = parent::createInstance($container, $entity_type);
    $instance->workflowStorage = $container->get("entity_type.manager")
      ->getStorage("flowdrop_workflow");
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function buildHeader(): array {
    $header = [
      "label" => $this->t("Label"),
      "event_type" => $this->t("Event Type"),
      "workflow" => $this->t("Workflow"),
      "conditions" => $this->t("Conditions"),
      "status" => $this->t("Status"),
      "weight" => $this->t("Weight"),
    ];

    return $header + parent::buildHeader();
  }

  /**
   * {@inheritdoc}
   */
  public function buildRow(EntityInterface $entity): array {
    if (!$entity instanceof FlowDropTriggerConfigInterface) {
      return parent::buildRow($entity);
    }

    // Get workflow label.
    $workflowLabel = $this->getWorkflowLabel($entity->getWorkflowId());

    // Format conditions summary.
    $conditionsSummary = $this->formatConditions($entity->getConditions());

    $row = [
      "label" => [
        "data" => [
          "#markup" => $entity->label(),
        ],
      ],
      "event_type" => [
        "data" => [
          "#markup" => sprintf("<code>%s</code>", $entity->getEventType()),
        ],
      ],
      "workflow" => [
        "data" => $workflowLabel,
      ],
      "conditions" => [
        "data" => [
          "#markup" => $conditionsSummary,
        ],
      ],
      "status" => $this->buildStatusPill($entity->status()),
      "weight" => $entity->getWeight(),
    ];

    return $row + parent::buildRow($entity);
  }

  /**
   * Get workflow label with link.
   *
   * @param string $workflowId
   *   The workflow ID.
   *
   * @return array<string, mixed>
   *   Render array for workflow label.
   */
  protected function getWorkflowLabel(string $workflowId): array {
    $workflow = $this->workflowStorage->load($workflowId);

    if ($workflow === NULL) {
      return [
        "#markup" => sprintf(
          '<span class="color-error">%s (missing)</span>',
          $workflowId
        ),
      ];
    }

    return [
      "#type" => "link",
      "#title" => $workflow->label(),
      "#url" => Url::fromRoute("flowdrop.workflow.edit", [
        "flowdrop_workflow" => $workflowId,
      ]),
    ];
  }

  /**
   * Builds a status pill render array for table cell display.
   *
   * @param bool $isEnabled
   *   Whether the entity is enabled.
   *
   * @return array<string, mixed>
   *   A table cell render array containing the status pill component.
   */
  protected function buildStatusPill(bool $isEnabled): array {
    return [
      "data" => [
        "#type" => "component",
        "#component" => "flowdrop_ui_components:pill",
        "#props" => [
          "label" => $isEnabled ? (string) $this->t("Enabled") : (string) $this->t("Disabled"),
          "variant" => $isEnabled ? "success" : "neutral",
          "style" => "soft",
          "size" => "sm",
        ],
      ],
    ];
  }

  /**
   * Format conditions as a summary string.
   *
   * @param array<string, mixed> $conditions
   *   The conditions array.
   *
   * @return string
   *   Formatted summary.
   */
  protected function formatConditions(array $conditions): string {
    $parts = [];

    $entityTypes = $conditions["entity_types"] ?? [];
    if (!empty($entityTypes)) {
      $parts[] = sprintf("Types: %s", implode(", ", $entityTypes));
    }

    $bundles = $conditions["bundles"] ?? [];
    if (!empty($bundles)) {
      $parts[] = sprintf("Bundles: %s", implode(", ", $bundles));
    }

    $roles = $conditions["roles"] ?? [];
    if (!empty($roles)) {
      $parts[] = sprintf("Roles: %s", implode(", ", $roles));
    }

    if (empty($parts)) {
      return (string) $this->t("All");
    }

    return implode("; ", $parts);
  }

  /**
   * {@inheritdoc}
   */
  public function getDefaultOperations(EntityInterface $entity): array {
    $operations = parent::getDefaultOperations($entity);

    // Add view operation using the custom route.
    $operations["view"] = [
      "title" => $this->t("View"),
      "url" => Url::fromRoute("flowdrop.trigger.view", [
        "flowdrop_trigger_config" => $entity->id(),
      ]),
      "weight" => -10,
    ];

    return $operations;
  }

  /**
   * {@inheritdoc}
   */
  public function render(): array {
    $build = parent::render();

    // Add description.
    $build["description"] = [
      "#markup" => "<p>" . $this->t(
        "Trigger configurations define when workflows are executed in response to system events. Each trigger is linked to a specific node in a workflow."
      ) . "</p>",
      "#weight" => -10,
    ];

    // Add empty message.
    if (empty($this->load())) {
      $build["empty"] = [
        "#markup" => "<p>" . $this->t(
          "No trigger configurations found. Triggers are created automatically when you add a Trigger node to a workflow in the visual editor."
        ) . "</p>",
      ];
    }

    return $build;
  }

}
