<?php

/**
 * Admin Scripts Handler
 *
 * @package ProRank\SEO\Admin
 * @since   1.0.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Admin;

use ProRank\SEO\Plugin;

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


/**
 * AdminScripts class
 */


class AdminScripts {
    
    /**
     * Plugin instance
     *
     * @var Plugin
     */
    private Plugin $plugin;
    
    /**
     * Constructor
     *
     * @param Plugin $plugin Plugin instance.
     */
    public function __construct(Plugin $plugin) {
        $this->plugin = $plugin;
        $this->init();
    }
    
    /**
     * Initialize
     */
    private function init(): void {
        add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts']);
        add_filter('script_loader_tag', [$this, 'add_module_type'], 10, 3);
        // Import map must be in head BEFORE any module scripts load
        add_action('admin_head', [$this, 'add_import_map'], 1);
    }

    /**
     * Read packaged build metadata, with a deterministic fallback for local builds.
     */
    private function get_build_info(): array {
        $fallback_timestamp = (defined('PRORANK_PLUGIN_FILE') && file_exists(PRORANK_PLUGIN_FILE))
            ? (int) filemtime(PRORANK_PLUGIN_FILE)
            : 0;
        $default_info = [
            'fingerprint' => substr(hash('sha256', PRORANK_VERSION . '|' . $fallback_timestamp . '|' . PRORANK_PLUGIN_BASENAME), 0, 16),
            'timestamp' => $fallback_timestamp,
            'commit' => 'local-package',
        ];

        $build_file = PRORANK_PLUGIN_DIR . 'build-info.json';
        if (!file_exists($build_file)) {
            return $default_info;
        }

        $build_data = json_decode((string) file_get_contents($build_file), true);
        return is_array($build_data) ? array_merge($default_info, $build_data) : $default_info;
    }

    /**
     * Add import map for WordPress packages
     */
    public function add_import_map(): void {
        // Load on ProRank pages AND pages where ProRank scripts are loaded (post edit, media library)
        $needs_import_map = false;

        // ProRank admin pages
        $page = prorank_get_query_var('page');
        if ($page !== '' && strpos($page, 'prorank') !== false) {
            $needs_import_map = true;
        }

        // Check screen for ProRank pages or editor pages
        if (!$needs_import_map) {
            $screen = get_current_screen();
            if ($screen) {
                // ProRank pages
                if (strpos($screen->id, 'prorank') !== false || strpos($screen->base, 'prorank') !== false) {
                    $needs_import_map = true;
                }
                // Post edit pages (where meta-box loads)
                if (in_array($screen->base, ['post', 'page', 'edit'], true)) {
                    $needs_import_map = true;
                }
                // Media library pages
                if ($screen->base === 'upload' || $screen->id === 'attachment') {
                    $needs_import_map = true;
                }
            }
        }

        if (!$needs_import_map) {
            return;
        }

        // Enqueue WordPress scripts as regular scripts (non-module)
        // These must be loaded before our ES modules so the globals are available
        wp_enqueue_script('wp-element');
        wp_enqueue_script('wp-components');
        wp_enqueue_script('wp-i18n');
        wp_enqueue_script('wp-api-fetch');
        wp_enqueue_script('wp-data');
        wp_enqueue_script('wp-hooks');
        wp_enqueue_script('wp-plugins');
        wp_enqueue_script('wp-block-editor');
        wp_enqueue_script('wp-blocks');
        wp_enqueue_script('wp-compose');
        wp_enqueue_script('wp-date');
        wp_enqueue_script('wp-url');
        wp_enqueue_script('wp-dom-ready');
        wp_enqueue_script('wp-icons');

        // Map bare module specifiers to our shim files
        // Each WordPress package gets its own shim file
        $base_url = PRORANK_PLUGIN_URL . 'build/shims/';

        $imports = [
            // WordPress packages - individual shim files
            '@wordpress/dom-ready' => $base_url . 'wp-dom-ready.js',
            '@wordpress/element' => $base_url . 'wp-element.js',
            '@wordpress/components' => $base_url . 'wp-components.js',
            '@wordpress/i18n' => $base_url . 'wp-i18n.js',
            '@wordpress/api-fetch' => $base_url . 'wp-api-fetch.js',
            '@wordpress/data' => $base_url . 'wp-data.js',
            '@wordpress/hooks' => $base_url . 'wp-hooks.js',
            '@wordpress/icons' => $base_url . 'wp-icons.js',
            '@wordpress/compose' => $base_url . 'wp-compose.js',
            '@wordpress/date' => $base_url . 'wp-date.js',
            '@wordpress/block-editor' => $base_url . 'wp-block-editor.js',
            '@wordpress/url' => $base_url . 'wp-url.js',
            // These packages use the same generic shim for now
            '@wordpress/plugins' => $base_url . 'wp-data.js',
            '@wordpress/editor' => $base_url . 'wp-data.js',
            '@wordpress/blocks' => $base_url . 'wp-data.js',
            '@wordpress/edit-post' => $base_url . 'wp-data.js',
            '@wordpress/rich-text' => $base_url . 'wp-data.js',
            '@wordpress/server-side-render' => $base_url . 'wp-data.js',
            '@wordpress/notices' => $base_url . 'wp-data.js',
            '@wordpress/primitives' => $base_url . 'wp-data.js',
            // React packages
            'react' => $base_url . 'react.js',
            'react-dom' => $base_url . 'react-dom.js',
            'react/jsx-runtime' => $base_url . 'jsx-runtime.js',
        ];

        echo '<script type="importmap">' . "\n";
        echo json_encode(['imports' => $imports], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n";
        echo '</script>' . "\n";
    }

    /**
     * Add type="module" to ProRank scripts
     *
     * @param string $tag Script tag.
     * @param string $handle Script handle.
     * @param string $src Script source.
     * @return string Modified script tag.
     */
    public function add_module_type(string $tag, string $handle, string $src): string {
        if (!is_admin()) {
            return $tag;
        }

        if (stripos($tag, 'type="module"') !== false || stripos($tag, "type='module'") !== false) {
            return $tag;
        }

        // Add type="module" to ProRank scripts (required for Vite ES module output)
        if (strpos($handle, 'prorank-') === 0) {
            $tag = str_replace(' src=', ' type="module" src=', $tag);
        }
        return $tag;
    }
    
    /**
     * Enqueue admin scripts
     *
     * @param string $hook_suffix Current admin page.
     */
    public function enqueue_scripts(string $hook_suffix): void {
        // Get asset file
        $asset_file = PRORANK_PLUGIN_DIR . 'build/admin.asset.php';
        $asset_dependencies = [];
        if (file_exists($asset_file)) {
            $asset = require $asset_file;
            $asset_dependencies = $asset['dependencies'] ?? [];
        }

        // Ensure globals required by shimmed ES modules are ready before admin.js executes.
        // Missing wp-date/wp-data caused the SPA to crash on some admin screens.
        $required_dependencies = [
            'wp-element',
            'wp-components',
            'wp-i18n',
            'wp-api-fetch',
            'wp-data',
            'wp-hooks',
            'wp-plugins',
            'wp-block-editor',
            'wp-blocks',
            'wp-compose',
            'wp-date',
            'wp-url',
            'wp-dom-ready',
        ];
        $asset_dependencies = array_values(array_unique(array_merge($asset_dependencies, $required_dependencies)));

        // Only load admin.js on ProRank admin pages (not post edit pages)
        // Post edit pages use meta-box.js which handles its own loading via dynamic imports
        // Loading admin.js on post edit pages causes React Error #130 due to ES module
        // shim timing issues with @wordpress/components
        $page = prorank_get_query_var('page');
        $is_prorank_page = $page !== '' && strpos($page, 'prorank') !== false;
        $is_media_library = $hook_suffix === 'upload.php';

        if ($is_prorank_page || $is_media_library) {
            // Enqueue the main admin script
            // Force cache bust by using microtime
            wp_enqueue_script(
                'prorank-admin-js',
                PRORANK_PLUGIN_URL . 'build/admin.js',
                $asset_dependencies,
                microtime(),  // Force fresh load
                true
            );

        } else {
            // On other pages, just return early - we don't need admin.js
            // Media enhancements on post edit pages will work through
            // the ai-image-attributes.js module which is loaded separately
            return;
        }
        
        // Ensure modules are registered
        MediaModuleHelper::ensure_modules_registered();
        
        // Prepare localization data
        $modules = $this->plugin->modules();
        
        // Get media module status using helper
        $media_status = MediaModuleHelper::get_media_module_status();
        $build_info = $this->get_build_info();
        
        $localize_data = [
            'ajaxUrl' => admin_url('admin-ajax.php'),
            'restUrl' => rest_url(),
            'restNonce' => wp_create_nonce('wp_rest'),
            'nonce' => wp_create_nonce('wp_rest'),
            'pluginUrl' => PRORANK_PLUGIN_URL,
            'siteUrl' => home_url(),
            'modules' => $media_status,
            'debug' => defined('WP_DEBUG') && WP_DEBUG ? DebugModules::get_relevant_modules() : null,
            'version' => PRORANK_VERSION,
            'buildFingerprint' => defined('PRORANK_BUILD_FINGERPRINT') ? PRORANK_BUILD_FINGERPRINT : $build_info['fingerprint'],
            'buildTimestamp' => defined('PRORANK_BUILD_TIMESTAMP') ? PRORANK_BUILD_TIMESTAMP : $build_info['timestamp'],
            'buildCommit' => defined('PRORANK_BUILD_COMMIT') ? PRORANK_BUILD_COMMIT : $build_info['commit'],
            'siteSettings' => [
                'show_on_front' => get_option('show_on_front', 'posts'),
                'page_on_front' => (int) get_option('page_on_front', 0),
                'page_for_posts' => (int) get_option('page_for_posts', 0),
            ],
        ];
        
        // Add AI configuration status
        if ($media_status['ai-image-attributes']) {
            $settings = $this->plugin->settings();
            $ai_provider = $settings->get('ai_config_provider', '');
            
            // Check different possible key formats
            $ai_key = '';
            if ($ai_provider) {
                $ai_key = $settings->get("ai_config_{$ai_provider}_api_key", '');
                if (empty($ai_key)) {
                    $ai_key = $settings->get("ai_{$ai_provider}_api_key", '');
                }
            }
            
            $localize_data['ai'] = [
                'configured' => !empty($ai_provider) && !empty($ai_key),
                'provider' => $ai_provider,
            ];
        }
        
        // Apply filter to allow other components to add data
        $localize_data = apply_filters('prorank_seo_admin_data', $localize_data);
        
        // Localize the script
        wp_localize_script('prorank-admin-js', 'prorankSeo', $localize_data);

        // Also ensure media scripts are loaded on appropriate pages
        $media_pages = ['post.php', 'post-new.php', 'upload.php'];
        if (in_array($hook_suffix, $media_pages, true)) {
            wp_enqueue_media();
        }
    }
}
