<?php

declare(strict_types=1);

namespace App\Framework\GraphQL\DataLoader;

/**
 * Registry for managing DataLoaders during GraphQL request
 *
 * Provides central access to all loaders and ensures proper dispatch
 */
final class DataLoaderRegistry
{
    /** @var array<string, DataLoader> */
    private array $loaders = [];

    /**
     * Register a DataLoader with a key
     */
    public function register(string $key, DataLoader $loader): void
    {
        $this->loaders[$key] = $loader;
    }

    /**
     * Get DataLoader by key
     */
    public function get(string $key): ?DataLoader
    {
        return $this->loaders[$key] ?? null;
    }

    /**
     * Get or create DataLoader
     *
     * @param \Closure(array): array $batchLoadFn
     */
    public function getOrCreate(string $key, \Closure $batchLoadFn): DataLoader
    {
        if (! isset($this->loaders[$key])) {
            $this->loaders[$key] = new DataLoader($batchLoadFn);
        }

        return $this->loaders[$key];
    }

    /**
     * Dispatch all registered loaders
     *
     * Call this after resolving all fields to execute batched loads
     */
    public function dispatchAll(): void
    {
        foreach ($this->loaders as $loader) {
            $loader->dispatch();
        }
    }

    /**
     * Clear all loaders
     */
    public function clearAll(): void
    {
        foreach ($this->loaders as $loader) {
            $loader->clear();
        }

        $this->loaders = [];
    }

    /**
     * Get statistics for all loaders
     */
    public function getStats(): array
    {
        $stats = [];

        foreach ($this->loaders as $key => $loader) {
            $stats[$key] = $loader->getStats();
        }

        return $stats;
    }
}
