<?php

declare(strict_types=1);

namespace PpPhp\Core\Assets;

final class AssetManager
{
    public static function package(string $packageId): void
    {
        AssetRegistry::enable($packageId);
    }

    public static function renderHead(string $baseUrl = ''): string
    {
        return self::renderAssets('head', $baseUrl);
    }

    public static function renderFooter(string $baseUrl = ''): string
    {
        return self::renderAssets('footer', $baseUrl);
    }

    private static function renderAssets(string $location, string $baseUrl): string
    {
        $collection = self::resolveEnabledAssets();
        $html = [];

        foreach ($collection->byLocation($location) as $asset) {
            $url = self::assetUrl($baseUrl, $asset->path);

            if ($asset->type === 'css') {
                $html[] = '<link rel="stylesheet" href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '">';
                continue;
            }

            if ($asset->type === 'js') {
                $html[] = '<script src="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '"></script>';
            }
        }

        return implode(PHP_EOL, $html);
    }

    private static function resolveEnabledAssets(): AssetCollection
    {
        $resolved = [];
        $collection = new AssetCollection();

        foreach (AssetRegistry::enabled() as $packageId) {
            self::resolvePackage($packageId, $resolved, $collection);
        }

        return $collection;
    }

    private static function resolvePackage(
        string $packageId,
        array &$resolved,
        AssetCollection $collection
    ): void {
        if (isset($resolved[$packageId])) {
            return;
        }

        $package = AssetRegistry::get($packageId);

        if (!$package) {
            return;
        }

        foreach ($package->dependencies as $dependency) {
            self::resolvePackage($dependency, $resolved, $collection);
        }

        $collection->merge($package->assets);
        $resolved[$packageId] = true;
    }

    private static function assetUrl(string $baseUrl, string $path): string
    {
        return rtrim($baseUrl, '/') . '/' . ltrim($path, '/');
    }
}
