<?php

namespace Mtc\Plugins\BlockManager\Services;

/**
 * Resolves Vite-built asset URLs from public/build/manifest.json.
 *
 * Shared by the admin shell (script/style of the block_manager_admin bundle)
 * and the Composer preview (the site `app` entry's CSS, which carries the
 * compiled element-variant styles for the live canvas).
 *
 * Falls back to a literal /public/build path when the manifest entry is
 * missing so routes stay usable during local dev before `npm run build`.
 */
class ViteAssetResolver
{
    /** @var array<string, mixed>|null */
    private ?array $manifest = null;

    /**
     * Hashed public URL for a JS entry (e.g. sites/default/js/app.js).
     */
    public function asset(string $key): string
    {
        $manifest = $this->manifest();
        if (isset($manifest[$key]['file'])) {
            return '/public/build/' . $manifest[$key]['file'];
        }
        return '/public/build/' . $key;
    }

    /**
     * CSS files emitted alongside a JS entry by Vite.
     *
     * @return string[]
     */
    public function css(string $key): array
    {
        $manifest = $this->manifest();
        $out = [];
        if (!empty($manifest[$key]['css']) && is_array($manifest[$key]['css'])) {
            foreach ($manifest[$key]['css'] as $css) {
                $out[] = '/public/build/' . $css;
            }
        }
        return $out;
    }

    /**
     * @return array<string, mixed>
     */
    private function manifest(): array
    {
        if ($this->manifest !== null) {
            return $this->manifest;
        }
        $path = defined('SITE_PATH')
            ? SITE_PATH . '/public/build/manifest.json'
            : base_path('public/build/manifest.json');
        if (!is_file($path)) {
            return $this->manifest = [];
        }
        $decoded = json_decode((string) file_get_contents($path), true);
        return $this->manifest = is_array($decoded) ? $decoded : [];
    }
}
