<?php

namespace Mtc\Plugins\BlockManager\Services;

/**
 * Maintains the frontend LESS aggregator that wires every element-variant
 * stylesheet into the site build.
 *
 * The element catalogue stores one stylesheet per variant at
 * plugins/BlockManager/elements/{type}/styles/{variant}.less. None of those
 * are reachable from sites/default/css/app.less on their own, so shipped
 * blocks would render unstyled. This service (re)generates
 * sites/default/css/block_manager_variants.less — a flat list of @import
 * lines — which includes.less imports once. Vite compiles the lot into
 * app.css with variables.less already in scope, so design tokens resolve.
 *
 * Regenerated on every publish (see VariantPublishService) and runnable
 * standalone for a one-time backfill. Output is sorted for deterministic,
 * churn-free diffs.
 */
class VariantStyleAggregator
{
    private const AGGREGATOR_RELATIVE = 'sites/default/css/block_manager_variants.less';

    /**
     * Scan the catalogue and rewrite the aggregator LESS file.
     *
     * @return string Absolute path to the (re)written aggregator file.
     */
    public function rebuild(): string
    {
        $elementsDir = base_path('plugins/BlockManager/elements');
        $aggregatorPath = base_path(self::AGGREGATOR_RELATIVE);

        $files = glob("{$elementsDir}/*/styles/*.less") ?: [];
        $files = array_values(array_filter($files, fn ($f) => !str_ends_with($f, '.bak')));
        sort($files);

        $lines = ['/* AUTO-GENERATED by VariantStyleAggregator — do not edit by hand. */'];
        foreach ($files as $file) {
            $lines[] = "@import '" . $this->relativeImportPath($file) . "';";
        }

        file_put_contents($aggregatorPath, implode("\n", $lines) . "\n");

        return $aggregatorPath;
    }

    /**
     * Path of a variant stylesheet relative to the aggregator's own location
     * (sites/default/css/). Climbs three levels (css → default → sites → root)
     * then re-enters via the project-relative path.
     */
    private function relativeImportPath(string $absoluteFile): string
    {
        $projectRelative = ltrim(str_replace(base_path(), '', $absoluteFile), '/');
        return '../../../' . $projectRelative;
    }
}
