<?php
/**
 * Copyright since 2025 InPost S.A.
 *
 * For the full license information, please view the LICENSE file bundled with the module.
 *
 * @author InPost S.A.
 * @copyright since 2025 InPost S.A.
 * @license MIT
 */

declare(strict_types=1);

namespace InPost\International\Asset;

use InPost\International\Asset\Filter\AssetOptionsFilterInterface;
use InPost\International\Asset\Filter\IdentityFilter;
use Symfony\Component\Asset\PathPackage;

if (!defined('_PS_VERSION_')) {
    exit;
}

final class FrontAssetManager extends AbstractAssetManager
{
    /**
     * @var \Context
     */
    private $context;

    /**
     * @var AssetOptionsFilterInterface
     */
    private $filter;

    public function __construct(\Module $module, \Context $context, AssetOptionsFilterInterface $filter = null)
    {
        parent::__construct($module);

        $this->context = $context;
        $this->filter = $filter ?? new IdentityFilter();
    }

    /**
     * {@inheritDoc}
     */
    protected function registerJavaScript(string $path, array $options = []): void
    {
        $options = $this->resolveOptions($path, $options);
        $options = $this->filter->filterJavaScriptOptions($options);

        $this->getController()->registerJavascript($options['id'], $path, $options);
    }

    /**
     * {@inheritDoc}
     */
    protected function registerStyleSheet(string $path, array $options = []): void
    {
        $options = $this->resolveOptions($path, $options);
        $options = $this->filter->filterStyleSheetOptions($options);

        $this->getController()->registerStylesheet($options['id'], $path, $options);
    }

    protected function getBasePath(): string
    {
        return sprintf('modules/%s/views', $this->module->name);
    }

    /**
     * @param array<string, mixed> $options
     *
     * @return array<string, mixed>
     */
    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 = $package->getBasePath() . $path;
            }
        }

        return $options;
    }

    private function getController(): \FrontController
    {
        return $this->context->controller;
    }

    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, '//');
    }
}
