<?php

namespace EasyLinkAutomations\Triggers;

if (!defined('ABSPATH')) {
    exit;
}

use EasyLinkAutomations\Triggers\Contracts\TriggerInterface;

/**
 * Registry for managing available triggers.
 *
 * Triggers register themselves here so they can be discovered by the UI
 * and instantiated when automations are loaded.
 */
final class TriggerRegistry
{
    /**
     * @var array<string, class-string<TriggerInterface>>
     */
    private static array $triggers = [];

    /**
     * Register a trigger class.
     *
     * @param class-string<TriggerInterface> $triggerClass
     */
    public static function register(string $triggerClass): void
    {
        if (!is_subclass_of($triggerClass, TriggerInterface::class)) {
            return;
        }

        // Store ALL triggers regardless of availability so the UI can discover them.
        // Hook execution is filtered separately in all().
        $slug = $triggerClass::getSlug();
        self::$triggers[$slug] = $triggerClass;
    }

    /**
     * Get a trigger instance by slug.
     */
    public static function get(string $slug): ?TriggerInterface
    {
        if (!isset(self::$triggers[$slug])) {
            return null;
        }

        $class = self::$triggers[$slug];

        return new $class();
    }

    /**
     * Get all available trigger instances for hook execution.
     * Unavailable triggers (plugin not installed) are excluded.
     *
     * @return array<string, TriggerInterface>
     */
    public static function all(): array
    {
        $instances = [];

        foreach (self::$triggers as $slug => $class) {
            if ($class::isAvailable()) {
                $instances[$slug] = new $class();
            }
        }

        return $instances;
    }

    /**
     * Get all triggers as array (for API response).
     *
     * @return array<int, array>
     */
    public static function toArray(): array
    {
        $result = [];

        foreach (self::$triggers as $class) {
            $result[] = $class::toArray();
        }

        return $result;
    }

    /**
     * Get triggers grouped by category.
     *
     * @return array<string, array>
     */
    public static function groupedByCategory(): array
    {
        $grouped = [];

        foreach (self::$triggers as $class) {
            $category = $class::getCategory();
            $grouped[$category][] = $class::toArray();
        }

        return $grouped;
    }

    /**
     * Check if a trigger exists.
     */
    public static function has(string $slug): bool
    {
        return isset(self::$triggers[$slug]);
    }
}
