<?php
declare(strict_types=1);

namespace Ekesto\CacheInvalidator\Integrations\Forms;

use Ekesto\CacheInvalidator\Support\Debug;
use Ekesto\CacheInvalidator\InvalidatorRuntime;
use Ekesto\CacheInvalidator\Integrations\Forms\Adapters\ContactForm7Adapter;
use Ekesto\CacheInvalidator\Integrations\Forms\Adapters\GravityFormsAdapter;
use Ekesto\CacheInvalidator\Integrations\Forms\Adapters\NinjaFormsAdapter;
use Ekesto\CacheInvalidator\Integrations\Forms\Adapters\WPFormsAdapter;

/**
 * Registers forms adapters and forwards events to invalidation controller.
 */
final class FormsManager
{
    /**
     * Request-local guard to prevent duplicate hook registration.
     *
     * @var bool
     */
    private static bool $booted = false;

    private FormsInvalidationController $controller;

    /**
     * @var FormAdapterInterface[]
     */
    private array $adapters;

    /**
     * Register hooks for all available forms adapters.
     *
     * @return void
     */
    public static function registerHooks(): void
    {
        $manager = new self();
        $manager->boot();
    }

    /**
     * Build manager with default adapter registry.
     */
    public function __construct()
    {
        $this->controller = new FormsInvalidationController();
        $this->adapters = [
            new ContactForm7Adapter(),
            new WPFormsAdapter(),
            new GravityFormsAdapter(),
            new NinjaFormsAdapter(),
        ];
    }

    /**
     * Register form hooks when forms invalidation is enabled.
     *
     * @return void
     */
    public function boot(): void
    {
        if (self::$booted) {
            Debug::verbose('forms manager: boot skipped, already booted');
            return;
        }
        self::$booted = true;

        Debug::verbose('forms manager: boot started', ['adapters_total' => count($this->adapters)]);

        if (!InvalidatorRuntime::settingsRepository()->isInvalidationEnabled()) {
            Debug::verbose('forms manager: boot skipped, invalidation disabled');
            return;
        }

        $global = InvalidatorRuntime::settingsRepository()->getGlobalInvalidation();
        if (empty($global['forms_enabled'])) {
            Debug::verbose('forms manager: forms invalidation disabled');
            return;
        }

        $registeredAdapters = [];
        foreach ($this->adapters as $adapter) {
            if (!$adapter->isAvailable()) {
                continue;
            }

            $adapter->registerHooks(function (string $adapterKey, $formId, array $context = []) use ($adapter): void {
                if ($adapterKey !== $adapter->key()) {
                    return;
                }

                Debug::verbose(sprintf(
                    'forms manager: adapter event forwarded (%s) form_id=%s hook=%s event=%s',
                    $adapterKey,
                    (string) $formId,
                    (string) ($context['source_hook'] ?? 'unknown'),
                    (string) ($context['event'] ?? 'unknown')
                ));
                $this->controller->handleFormChanged($adapter, $formId, $context);
            });

            $registeredAdapters[] = $adapter->key();
        }

        Debug::verbose('forms manager: boot completed', [
            'adapters_registered' => $registeredAdapters,
            'registered_count' => count($registeredAdapters),
        ]);
    }
}
