<?php
declare(strict_types=1);

namespace PpPhp\Core\Designer\Component;

final class DesignerComponentRegistry
{
    private array $definitions = [];
    private array $categories = [];

    public function registerCategory(DesignerComponentCategory $category): void
    {
        $this->categories[$category->categoryId()] = $category;
    }

    public function register(DesignerComponentDefinition $definition): void
    {
        $this->definitions[$definition->type()] = $definition;
    }

    public function has(string $type): bool { return isset($this->definitions[$type]); }
    public function get(string $type): ?DesignerComponentDefinition { return $this->definitions[$type] ?? null; }
    public function all(): array { return $this->definitions; }

    public function categories(): array
    {
        $categories = array_values($this->categories);
        usort($categories, static fn($a, $b) => $a->order() <=> $b->order());
        return $categories;
    }

    public function byCategory(string $category): array
    {
        return array_values(array_filter($this->definitions, static fn($d) => $d->category() === $category));
    }

    public function search(string $query): array
    {
        $query = strtolower(trim($query));
        return array_values(array_filter($this->definitions, static function($d) use ($query) {
            if ($query === '') return true;
            $row = $d->toArray();
            return str_contains(strtolower($row['type'].' '.$row['title'].' '.$row['description'].' '.implode(' ', $row['tags'])), $query);
        }));
    }

    public function toArray(): array
    {
        return [
            'categories' => array_map(static fn($c) => $c->toArray(), $this->categories()),
            'components' => array_map(static fn($d) => $d->toArray(), array_values($this->definitions)),
        ];
    }
}
