<?php

/**
 * Copyright 2024-2025 Simply.IN Sp. z o.o.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the EUPL-1.2 or later.
 * You may not use this work except in compliance with the Licence.
 *
 * Copy of the Licence is available at:
 * https://joinup.ec.europa.eu/software/page/eupl
 * It is bundled with this package in the file LICENSE.txt
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Licence is distributed on an as is basis,
 * without warranties or conditions of any kind, either express or implied.
 * Check the Licence for the specific language governing permissions
 * and limitations under the License.
 *
 * @author   Simply.IN Sp. z o.o.
 * @copyright 2024-2025 Simply.IN Sp. z o.o.
 * @license   https://joinup.ec.europa.eu/software/page/eupl
 */

declare(strict_types=1);

namespace SimplyIn\Front;

use Configuration;
use FrontController;

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

final class AssetRegistrar
{
    private OpcDetector $opcDetector;

    public function __construct(OpcDetector $opcDetector)
    {
        $this->opcDetector = $opcDetector;
    }

    public function registerHeaderAssets(
        FrontController $controller,
        string $moduleName,
        string $moduleVersion,
    ): void {
        $base = 'modules/' . $moduleName . '/';

        if ($this->opcDetector->isOrderDetailController()) {
            if (Configuration::get('SIMPLYIN_PAYMENTS')) {
                $this->registerOrderRetryAssets($controller, $moduleName, $base, $moduleVersion);
            }

            return;
        }

        $controller->registerJavascript(
            'simplyin-phone-checkbox-manager',
            $base . 'views/js/dist/phone-checkbox-manager.js',
            ['position' => 'bottom', 'priority' => 149, 'server' => 'local', 'version' => $moduleVersion],
        );

        $controller->registerJavascript(
            'module-' . $moduleName . '-front',
            $base . 'views/js/dist/front.js',
            ['position' => 'bottom', 'priority' => 150, 'server' => 'local', 'version' => $moduleVersion],
        );

        $opc = $this->opcDetector->detect();
        $paymentsEnabled = (bool) Configuration::get('SIMPLYIN_PAYMENTS');

        if ($opc === OpcDetector::OPC_CLASSIC) {
            $this->registerClassicAssets($controller, $moduleName, $base, $moduleVersion);
        } elseif ($opc === OpcDetector::OPC_THECHECKOUT) {
            $this->registerTheCheckoutAssets($controller, $moduleName, $base, $moduleVersion, $paymentsEnabled);
        } elseif ($opc === OpcDetector::OPC_HUMMINGBIRD) {
            $this->registerHummingbirdAssets($controller, $moduleName, $base, $moduleVersion, $paymentsEnabled);
        }

        $controller->registerStylesheet(
            'module-' . $moduleName . '-front',
            $base . 'views/css/simplyin_front.css',
            ['media' => 'all', 'priority' => 150, 'server' => 'local', 'version' => $moduleVersion],
        );
    }

    /**
     * Assets for the pay-again surface on an order page.
     *
     * Only the paywall's own bundle and stylesheet, none of the checkout ones: the surface renders
     * the same paywall partial and needs its card, BLIK and method-selection behaviour, but there is
     * no checkout on this page for the rest to attach to. Which of the three checkout variants the
     * shop runs is irrelevant for the same reason - the order page is themed, not variant-specific.
     *
     * The general front stylesheet is deliberately NOT loaded here. It is by far the largest asset
     * the module has, and an order page needs a handful of rules out of it - so the pay-again card
     * carries its own geometry in the paywall stylesheet instead. That keeps this addition to two
     * files on a page where the module previously emitted nothing.
     */
    private function registerOrderRetryAssets(
        FrontController $controller,
        string $moduleName,
        string $base,
        string $moduleVersion,
    ): void {
        $this->registerPaymentAssets($controller, $moduleName, $base, $moduleVersion, 151);
    }

    /**
     * The paywall bundle and its stylesheet, shared by every surface that renders the paywall.
     *
     * Stated once because the handle, the path and the options have to agree across all of them: a
     * surface that registered a differently-named handle for the same file would load it twice, and
     * one that drifted on the path would render the paywall against a different bundle than the
     * checkout it shares a partial with. Only the JS priority differs, and it is the parameter.
     */
    private function registerPaymentAssets(
        FrontController $controller,
        string $moduleName,
        string $base,
        string $moduleVersion,
        int $jsPriority,
    ): void {
        $controller->registerJavascript(
            'module-' . $moduleName . '-front-payment',
            $base . 'views/js/dist/payment.js',
            ['position' => 'bottom', 'priority' => $jsPriority, 'server' => 'local', 'version' => $moduleVersion],
        );
        $controller->registerStylesheet(
            'module-' . $moduleName . '-front-payment-css',
            $base . 'views/css/simplyin_front_payment.css',
            ['media' => 'all', 'priority' => 150, 'server' => 'local', 'version' => $moduleVersion],
        );
    }

    private function registerClassicAssets(
        FrontController $controller,
        string $moduleName,
        string $base,
        string $moduleVersion,
    ): void {
        $this->registerPaymentAssets($controller, $moduleName, $base, $moduleVersion, 151);
    }

    private function registerTheCheckoutAssets(
        FrontController $controller,
        string $moduleName,
        string $base,
        string $moduleVersion,
        bool $paymentsEnabled,
    ): void {
        $controller->registerJavascript(
            'module-' . $moduleName . '-thecheckout',
            $base . 'views/js/dist/opc-thecheckout.js',
            ['position' => 'bottom', 'priority' => 151, 'server' => 'local', 'version' => $moduleVersion],
        );
        if (!$paymentsEnabled) {
            return;
        }
        $this->registerPaymentAssets($controller, $moduleName, $base, $moduleVersion, 152);
        $controller->registerJavascript(
            'module-' . $moduleName . '-front-payment-thecheckout',
            $base . 'views/js/dist/opc-payment-thecheckout.js',
            ['position' => 'bottom', 'priority' => 153, 'server' => 'local', 'version' => $moduleVersion],
        );
    }

    private function registerHummingbirdAssets(
        FrontController $controller,
        string $moduleName,
        string $base,
        string $moduleVersion,
        bool $paymentsEnabled,
    ): void {
        $controller->registerJavascript(
            'module-' . $moduleName . '-hummingbird',
            $base . 'views/js/dist/opc-hummingbird.js',
            ['position' => 'bottom', 'priority' => 151, 'server' => 'local', 'version' => $moduleVersion],
        );
        if (!$paymentsEnabled) {
            return;
        }
        $this->registerPaymentAssets($controller, $moduleName, $base, $moduleVersion, 152);
    }
}
