<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\Asset;

use Gls\GlsPoland\Asset\AssetManagerInterface;
use Symfony\Component\Asset\PathPackage;

final class FrontAssetManager extends AbstractAssetManager
{
    private $module;
    private $controller;
    private $filter;

    public function __construct(\Module $module, \FrontController $controller, ?AssetOptionsFilterInterface $filter = null)
    {
        parent::__construct($module);

        $this->module = $module;
        $this->controller = $controller;
        $this->filter = $filter ?? FrontAssetOptionsFilter::create();
    }

    public function registerJavaScript(string $path, array $options = []): AssetManagerInterface
    {
        $options = $this->resolveOptions($path, $options);
        $options = $this->filter->filterJavaScriptOptions($options);
        $this->controller->registerJavascript($options['id'], $path, $options);

        return $this;
    }

    public function registerStyleSheet(string $path, array $options = []): AssetManagerInterface
    {
        $options = $this->resolveOptions($path, $options);
        $options = $this->filter->filterStyleSheetOptions($options);
        $this->controller->registerStylesheet($options['id'], $path, $options);

        return $this;
    }

    private function resolveOptions(string &$path, array $options): array
    {
        $options['id'] = $options['id'] ?? $this->getAssetId($path);
        if ($this->isAbsoluteUrl($path)) {
            $options['server'] = $options['server'] ?? 'remote';
        } else {
            $package = $this->getPackage();
            $options['version'] = $options['version'] ?? $package->getVersion($path);
            if ('/' !== $path[0] && $package instanceof PathPackage) {
                $path = $this->getPackage()->getBasePath() . $path;
            }
        }

        return $options;
    }

    private function getAssetId(string $path): string
    {
        return sprintf('modules-%s-%s', $this->module->name, pathinfo($path, PATHINFO_FILENAME));
    }

    private function isAbsoluteUrl(string $url): bool
    {
        return str_contains($url, '://') || str_starts_with($url, '//');
    }
}
