<?php

declare(strict_types=1);

namespace Maestro\Core\DataTables;

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Maps resourceKey => {@see DataTableResource} class.
 */
final class DataTableRegistry
{
    /** @var array<string, class-string<DataTableResource>> */
    private array $map = [];

    /**
     * @param  class-string<DataTableResource>  $resourceClass
     */
    public function register(string $resourceClass, ?string $key = null): void
    {
        $instance = app($resourceClass);
        if (! $instance instanceof DataTableResource) {
            throw new \InvalidArgumentException(sprintf(
                'Class %s must implement %s',
                $resourceClass,
                DataTableResource::class
            ));
        }
        $key = $key ?? $instance->key();
        $this->map[$key] = $resourceClass;
    }

    public function resolve(string $resourceKey): DataTableResource
    {
        if (! isset($this->map[$resourceKey])) {
            throw new NotFoundHttpException(sprintf('DataTable resource "%s" is not registered.', $resourceKey));
        }

        $resource = app($this->map[$resourceKey]);
        if (! $resource instanceof DataTableResource) {
            throw new \RuntimeException(sprintf('Resolved class for "%s" does not implement DataTableResource.', $resourceKey));
        }

        return $resource;
    }

    /**
     * @return array<int, string>
     */
    public function keys(): array
    {
        return array_keys($this->map);
    }
}
