<?php

namespace Mtc\Plugins\BlockManager\Services;

class ElementCatalogueService
{
    private string $elementsPath;

    public function __construct(?string $elementsPath = null)
    {
        $this->elementsPath = $elementsPath ?? __DIR__ . '/../elements';
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    public function list(): array
    {
        if (!is_dir($this->elementsPath)) {
            return [];
        }

        $manifests = [];
        foreach (glob($this->elementsPath . '/*/element.json') ?: [] as $path) {
            $decoded = $this->decode($path);
            if ($decoded !== null) {
                $manifests[] = $decoded;
            }
        }

        usort($manifests, fn ($a, $b) => strcmp($a['type'] ?? '', $b['type'] ?? ''));

        return $manifests;
    }

    /**
     * @return array<string, mixed>|null
     */
    public function get(string $type): ?array
    {
        if ($type === '' || !$this->isSafeType($type)) {
            return null;
        }

        $path = $this->elementsPath . '/' . $type . '/element.json';
        if (!is_file($path)) {
            return null;
        }

        return $this->decode($path);
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    public function variants(string $type): array
    {
        $manifest = $this->get($type);
        if (!is_array($manifest) || !isset($manifest['variants']) || !is_array($manifest['variants'])) {
            return [];
        }

        return $manifest['variants'];
    }

    private function decode(string $path): ?array
    {
        $raw = @file_get_contents($path);
        if ($raw === false) {
            return null;
        }

        $decoded = json_decode($raw, true);
        if (!is_array($decoded)) {
            return null;
        }

        return $decoded;
    }

    private function isSafeType(string $type): bool
    {
        return (bool) preg_match('/^[a-z0-9][a-z0-9_-]*$/i', $type);
    }
}
