<?php

declare(strict_types=1);

namespace Maestro\Core\DataTables;

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Resolves column definitions for registered {@see DataTableResource} classes
 * plus static definitions ({@see ExtraDatatableColumnDefinitions}) for list-only tables.
 */
final class DataTableColumnCatalog
{
    public function __construct(
        private readonly DataTableRegistry $registry,
    ) {}

    public function exists(string $resourceKey): bool
    {
        try {
            $this->registry->resolve($resourceKey);

            return true;
        } catch (NotFoundHttpException) {
            return ExtraDatatableColumnDefinitions::has($resourceKey);
        }
    }

    /**
     * B2CDataTable / user_table_states key for this resource (must match the {@code table-key} prop in Vue).
     */
    public function tableStateKeyForResource(string $resourceKey): string
    {
        return match ($resourceKey) {
            'users' => 'settings.users',
            'roles' => 'settings.roles',
            'activity-log' => 'settings.activity-log',
            'customers' => 'customers.index',
            'offers' => 'offers.index',
            'invoices' => 'invoices.index',
            default => str_contains($resourceKey, '.') ? $resourceKey : $resourceKey.'.index',
        };
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    public function definitions(string $resourceKey): array
    {
        try {
            return $this->registry->resolve($resourceKey)->columns();
        } catch (NotFoundHttpException) {
            if (ExtraDatatableColumnDefinitions::has($resourceKey)) {
                return ExtraDatatableColumnDefinitions::columns($resourceKey);
            }

            throw new NotFoundHttpException(sprintf('DataTable resource "%s" is not registered.', $resourceKey));
        }
    }

    /**
     * Resource keys for Superadmin + columns API (registry + extra-only slugs).
     *
     * @return list<string>
     */
    public function keysSorted(): array
    {
        $keys = array_values(array_unique(array_merge(
            $this->registry->keys(),
            ExtraDatatableColumnDefinitions::keys(),
        )));

        $order = ['users', 'roles', 'activity-log', 'customers', 'offers', 'invoices'];
        usort($keys, function (string $a, string $b) use ($order): int {
            $ia = array_search($a, $order, true);
            $ib = array_search($b, $order, true);
            $va = $ia === false ? 1000 : $ia;
            $vb = $ib === false ? 1000 : $ib;
            if ($va !== $vb) {
                return $va <=> $vb;
            }

            return strcmp($a, $b);
        });

        return $keys;
    }
}
