<?php

namespace EasyLinkAutomations\Views;

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

use EasyLinkAutomations\Config;
use EasyLinkAutomations\Helpers\DateTimeHelper;
use EasyLinkAutomations\I18n;

/**
 * Enqueues scripts and styles for the plugin's admin pages.
 *
 * In development mode the Vite dev server is used for HMR. In production
 * the pre-built bundle from the assets folder is loaded instead.
 */
final class Head
{
    private const FONT_URL = 'https://fonts.googleapis.com/css2?family=Inter:wght@300..800&display=swap';

    /**
     * Enqueue plugin assets only on EasyLink Automations admin pages.
     */
    public function enqueueAssets(string $currentScreen): void
    {
        if (!str_contains($currentScreen, Config::SLUG)) {
            return;
        }

        $slug     = Config::SLUG;
        $version  = Config::VERSION;
        $codeName = Config::get('BUILD_CODE_NAME');

        // Google Fonts
        wp_enqueue_style($slug . '-googleapis-PRECONNECT', 'https://fonts.googleapis.com', [], $version);
        wp_enqueue_style($slug . '-gstatic-PRECONNECT-CROSSORIGIN', 'https://fonts.gstatic.com', [], $version);
        wp_enqueue_style($slug . '-font', self::FONT_URL, [], $version);

        if (Config::isDev()) {
            $devUrl    = Config::getEnv('DEV_URL');
            $devBase   = esc_url($devUrl . '/wp-content/plugins/' . Config::SLUG . '/frontend');
            $varPrefix = esc_js(Config::VAR_PREFIX);

            // In dev mode, we need to output scripts directly in the head in the correct order
            // WordPress's enqueue system puts scripts in footer which breaks the preamble timing
            add_action('admin_head', function () use ($devBase, $varPrefix) {
                $config = wp_json_encode(self::createFrontendConfig());
                // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript, WordPress.Security.EscapeOutput.OutputNotEscaped -- Dev-only Vite HMR; vars escaped above (esc_js, esc_url, wp_json_encode).
                echo '<script>window.' . $varPrefix . ' = ' . $config . ';</script>';
                echo '<script type="module">';
                echo 'import RefreshRuntime from "' . $devBase . '/@react-refresh";';
                echo 'RefreshRuntime.injectIntoGlobalHook(window);';
                echo 'window.$RefreshReg$ = () => {}; window.$RefreshSig$ = () => (type) => type;';
                echo 'window.__vite_plugin_react_preamble_installed__ = true;';
                echo '</script>';
                // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript, WordPress.Security.EscapeOutput.OutputNotEscaped -- Dev-only; $devBase is esc_url() above.
                echo '<script type="module" src="' . $devBase . '/@vite/client"></script>';
                // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript, WordPress.Security.EscapeOutput.OutputNotEscaped -- Dev-only; $devBase is esc_url() above.
                echo '<script type="module" src="' . $devBase . '/src/main.tsx"></script>';
            }, 99);
        } else {
            $assetUri = Config::get('ASSET_URI');
            wp_enqueue_script(
                $slug . '-index-MODULE',
                $assetUri . '/main-' . $codeName . '.js',
                [],
                $version,
                true
            );
            wp_enqueue_style($slug . '-styles', $assetUri . '/main-' . $slug . '-ba-assets-' . $codeName . '.css', null, $version, 'screen');
            wp_localize_script($slug . '-index-MODULE', Config::VAR_PREFIX, self::createFrontendConfig());
        }

        if (!wp_script_is('media-upload')) {
            wp_enqueue_media();
        }
    }

    /**
     * Build the config object passed to the React frontend via wp_localize_script.
     */
    public static function createFrontendConfig(): array
    {
        $config = [
            'nonce'          => wp_create_nonce(Config::withPrefix('nonce')),
            'restNonce'      => wp_create_nonce('wp_rest'),
            'rootURL'        => Config::get('ROOT_URI'),
            'siteURL'        => Config::get('SITE_URL'),
            'siteBaseURL'    => is_multisite() ? network_site_url() : site_url(),
            'assetsURL'      => Config::get('ASSET_URI'),
            'pluginAdminURL' => get_admin_url(null, 'admin.php?page=' . Config::SLUG . '#'),
            'ajaxURL'        => admin_url('admin-ajax.php'),
            'apiURL'         => Config::get('API_URL'),
            'routePrefix'    => Config::VAR_PREFIX,
            'settings'       => Config::getOption('settings'),
            'dateFormat'     => Config::getOption('date_format', false, true),
            'timeFormat'     => Config::getOption('time_format', false, true),
            'timeZone'       => DateTimeHelper::wp_timezone_string(),
            'pluginSlug'     => Config::SLUG,
            'pluginName'     => Config::title(),
            'version'        => Config::VERSION,
            'isPro'          => Config::isProActivated(),
            'isProInstalled' => Config::isProInstalled(),
            'upgradeURL'     => Config::get('PRO_UPGRADE_URL'),
            'lang'           => I18n::currentLocale(),
            'translations'   => I18n::frontendLocaleData(),
        ];

        $hook_name = Config::withPrefix('localized_script');
        // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound -- Hook is prefixed via Config::withPrefix().
        $config = apply_filters($hook_name, $config);

        return $config;
    }
}
