<?php

namespace PhotoSphereViewer\Includes;

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

class ViteAssets {
    private $plugin_dir;
    private $plugin_url;
    private $is_dev;

    /** Handles that must receive type="module" in production. */
    private const MODULE_HANDLES = ['psv-vite-client', 'psv-main'];

    public function __construct($plugin_dir, $plugin_url) {
        $this->plugin_dir = $plugin_dir;
        $this->plugin_url = $plugin_url;
        $this->is_dev     = $this->is_dev_server_running();
    }

    /**
     * Check whether the Vite dev server is reachable.
     *
     * The result is transient-cached to avoid an HTTP probe on every page load:
     *  - Not running (production): cached for 5 minutes.
     *  - Running (dev): cached for 30 seconds so restarts propagate quickly.
     *
     * Override entirely with the PSV_DEV_MODE constant when the probe is
     * undesirable (e.g. CI, staging, or when running behind a proxy that
     * causes false-positives).
     */
    private function is_dev_server_running(): bool {
        if (defined('PSV_DEV_MODE')) {
            return (bool) PSV_DEV_MODE;
        }

        $cache_key = 'psv_vite_dev_server_active';
        $cached    = get_transient($cache_key);
        if ($cached !== false) {
            return $cached === '1';
        }

        $context = stream_context_create([
            'http' => [
                'timeout'       => 1,
                'ignore_errors' => true,
            ],
        ]);

        $result  = @file_get_contents('http://localhost:5173', false, $context); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
        $running = ($result !== false);

        set_transient($cache_key, $running ? '1' : '0', $running ? 30 : 300);

        return $running;
    }

    public function enqueue_assets($handle_prefix = 'vite') {
        if ($this->is_dev) {
            wp_enqueue_script(
                $handle_prefix . '-vite-client',
                'http://localhost:5173/@vite/client',
                [],
                PSV_VER,
                true
            );

            wp_enqueue_script(
                $handle_prefix . '-main',
                'http://localhost:5173/src/frontend/index.js',
                [],
                PSV_VER,
                true
            );

            add_filter('script_loader_tag', [$this, 'add_module_type'], 10, 3);
            return;
        }

        // Production mode — load from built manifest.
        $manifest_path = $this->plugin_dir . '/assets/dist/.vite/manifest.json';

        if (! file_exists($manifest_path)) {
            return;
        }

        $manifest = json_decode(file_get_contents($manifest_path), true); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents

        if (! isset($manifest['src/frontend/index.js'])) {
            return;
        }

        $main_asset = $manifest['src/frontend/index.js'];

        wp_register_script(
            $handle_prefix . '-main',
            $this->plugin_url . 'assets/dist/' . $main_asset['file'],
            [],
            PSV_VER,
            true
        );

        add_filter('script_loader_tag', [$this, 'add_module_type'], 10, 3);

        if (! empty($main_asset['css'])) {
            foreach ($main_asset['css'] as $css_file) {
                wp_register_style(
                    $handle_prefix . '-style',
                    $this->plugin_url . 'assets/dist/' . $css_file,
                    [],
                    PSV_VER
                );
            }
        }
    }

    /**
     * Add type="module" only to the known Vite script handles.
     *
     * Intentionally does NOT match every `psv-*` handle — the AR model-viewer
     * script (psv-ar-model-viewer) has its own filter in the main plugin file.
     */
    public function add_module_type($tag, $handle, $src) {
        if (in_array($handle, self::MODULE_HANDLES, true)) {
            $tag = str_replace(' src=', ' type="module" src=', $tag);
        }
        return $tag;
    }
}
