<?php

/**
 * LolaCore � Assets
 *
 * @package LolaCore
 * @license GPL-2.0-or-later
 */

declare(strict_types=1);

namespace LolaCore\Admin;

use LolaCore\Compat\DesktopMode;
use LolaCore\I18n\ChatUiStrings;
use LolaCore\I18n\PlaybooksUiStrings;
use LolaCore\I18n\SettingsUiStrings;

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Required for core functionality, dynamic queries, and performance. Validated inputs.

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class Assets
 *
 * Handles the conditional loading of CSS and JS in the WordPress admin area.
 */
class Assets
{
    /**
     * Register asset hooks.
     */
    public function register(): void
    {
        \add_action('admin_enqueue_scripts', [$this, 'enqueue']);
    }

    /**
     * Enqueue admin assets conditionally.
     *
     * @param string $hookSuffix The current admin page.
     */
    public function enqueue(string $hookSuffix): void
    {
        $pluginUrl = \plugin_dir_url(dirname(__DIR__));
        $pluginDir = \plugin_dir_path(dirname(__DIR__));
        // Use file modification time for cache busting — no stale assets during development
        $cssFile = $pluginDir . 'assets/css/lolacore-admin.css';

        // 1. lolacore-admin.css: ALL admin pages (for the floating widget + settings)
        \wp_enqueue_style(
            'lolacore-admin-style',
            $pluginUrl . 'assets/css/lolacore-admin.css',
            [],
            (string) @filemtime($cssFile)
        );

        // 2. The floating chat widget: ALL admin pages, except inside a Desktop
        // Mode window — the shell's parent page already carries it.
        if (!DesktopMode::isShellWindow()) {
            $this->enqueueChatWidget($pluginUrl, $pluginDir);
        }

        // 3. lolacore-settings.js: main settings + Skills manager
        if ($this->shouldEnqueueSettingsScript($hookSuffix)) {
            // Requires WordPress media uploader API for Avatar picker
            \wp_enqueue_media();

            $settingsJsFile = $pluginDir . 'assets/js/lolacore-settings.js';

            \wp_enqueue_script(
                'lolacore-settings-script',
                $pluginUrl . 'assets/js/lolacore-settings.js',
                ['jquery'],
                (string) @filemtime($settingsJsFile),
                true // Load in footer
            );

            $this->localizeScript('lolacore-settings-script');

            \wp_set_script_translations(
                'lolacore-settings-script',
                'lolacore',
                $pluginDir . 'languages'
            );

            \wp_localize_script(
                'lolacore-settings-script',
                'lolacore_settings_i18n',
                SettingsUiStrings::forScript()
            );
        }

        // 3b. lolacore-playbooks.js: Playbooks manager (own hook — WP suffix varies by install)
        if ($this->shouldEnqueuePlaybooksScript($hookSuffix)) {
            $playbooksJsFile = $pluginDir . 'assets/js/lolacore-playbooks.js';

            \wp_enqueue_script(
                'lolacore-playbooks-script',
                $pluginUrl . 'assets/js/lolacore-playbooks.js',
                ['jquery'],
                (string) @filemtime($playbooksJsFile),
                true
            );

            $this->localizeScript('lolacore-playbooks-script');

            \wp_set_script_translations(
                'lolacore-playbooks-script',
                'lolacore',
                $pluginDir . 'languages'
            );

            \wp_localize_script(
                'lolacore-playbooks-script',
                'lolacore_playbooks_i18n',
                PlaybooksUiStrings::forScript()
            );
        }

        // 4. lolacore-mcp.js and css: ONLY on the MCP Settings page
        if ($hookSuffix === 'lola_page_lolacore-mcp' || $hookSuffix === 'toplevel_page_lolacore-mcp') {
            $mcpCssFile = $pluginDir . 'assets/css/lolacore-mcp.css';
            \wp_enqueue_style(
                'lolacore-mcp-style',
                $pluginUrl . 'assets/css/lolacore-mcp.css',
                ['lolacore-admin-style'],
                (string) @filemtime($mcpCssFile)
            );

            $mcpJsFile = $pluginDir . 'assets/js/lolacore-mcp.js';
            \wp_enqueue_script(
                'lolacore-mcp-script',
                $pluginUrl . 'assets/js/lolacore-mcp.js',
                ['jquery'], // Uses jQuery IIFE wrapper
                (string) @filemtime($mcpJsFile),
                true // Load in footer
            );

            $this->localizeScript('lolacore-mcp-script');
        }
    }

    /**
     * Enqueue the floating chat widget's assets.
     *
     * Marked.js and DOMPurify are the chat script's Markdown renderer and are
     * used by nothing else, so they ship and stay behind the same guard.
     */
    private function enqueueChatWidget(string $pluginUrl, string $pluginDir): void
    {
        $chatJsFile = $pluginDir . 'assets/js/lolacore-chat.js';

        // Include Marked.js and DOMPurify for Chat Markdown rendering (bundled locally)
        \wp_enqueue_script(
            'lolacore-marked-js',
            $pluginUrl . 'assets/js/vendor/marked.min.js',
            [],
            '18.0.3',
            true
        );
        \wp_enqueue_script(
            'lolacore-dompurify-js',
            $pluginUrl . 'assets/js/vendor/purify.min.js',
            [],
            '3.4.2',
            true
        );

        // lolacore-chat.js — no jQuery dependency, uses native fetch()
        \wp_enqueue_script(
            'lolacore-chat-script',
            $pluginUrl . 'assets/js/lolacore-chat.js',
            ['lolacore-marked-js', 'lolacore-dompurify-js', 'wp-i18n'],
            (string) @filemtime($chatJsFile),
            true // Load in footer
        );

        \wp_set_script_translations(
            'lolacore-chat-script',
            'lolacore',
            $pluginDir . 'languages'
        );

        \wp_localize_script(
            'lolacore-chat-script',
            'lolacore_chat_i18n',
            ChatUiStrings::forScript()
        );

        // Localize AJAX config for all admin pages
        $this->localizeScript('lolacore-chat-script');

        // Inject widget state as inline script (once, for the chat script only).
        // Uses wp_add_inline_script instead of wp_localize_script because the latter
        // coerces all values to strings, breaking nested objects and booleans.
        if (\current_user_can('manage_options')) {
            $widget = new Widget();
            \wp_add_inline_script(
                'lolacore-chat-script',
                'window.lolacore_widget_state = ' . \wp_json_encode($widget->getWidgetState()) . ';',
                'before'
            );
        }
    }

    /**
     * Whether the current admin screen is the main settings page or Skills manager.
     */
    private function shouldEnqueueSettingsScript(string $hookSuffix): bool
    {
        if (in_array($hookSuffix, ['toplevel_page_lolacore', 'lola_page_lolacore'], true)) {
            return true;
        }

        return str_contains($hookSuffix, 'lolacore-skills');
    }

    /**
     * Whether the current admin screen is the Playbooks manager.
     *
     * WordPress builds $hook_suffix differently across versions and menu titles
     * (e.g. lolacore_page_lolacore-playbooks vs lola_page_lolacore-playbooks),
     * so we match on the stable submenu slug fragment.
     */
    private function shouldEnqueuePlaybooksScript(string $hookSuffix): bool
    {
        return str_contains($hookSuffix, 'lolacore-playbooks');
    }

    /**
     * Localize a script handle with the shared AJAX configuration.
     *
     * lolacore_ajax — URL, nonces, and default avatar URL.
     */
    private function localizeScript(string $handle): void
    {
        \wp_localize_script($handle, 'lolacore_ajax', [
            // Use relative scheme to prevent CORS issues on non-standard ports (Local by Flywheel)
            'ajax_url'           => \admin_url('admin-ajax.php', 'relative'),
            'nonce'              => \wp_create_nonce('lolacore_admin_nonce'),
            'chat_nonce'         => \wp_create_nonce('lolacore_chat'),
            'rest_url'           => \rest_url('lolacore/v1'),
            'rest_nonce'         => \wp_create_nonce('wp_rest'),
            'default_avatar_url' => \plugin_dir_url(dirname(__DIR__)) . 'assets/img/lola-default.png',
            'playbook_upload_max_chars' => \LolaCore\Playbooks\PlaybookDocumentReader::MAX_EXTRACTED_CHARS,
        ]);
    }
}