<?php

/**
 * Admin menu manager
 *
 * @package SlideMind
 * @since 2.0.0
 */
namespace SlideMind\Admin;

if ( !defined( 'ABSPATH' ) ) {
    exit;
}
class AdminMenu {
    /**
     * Main menu slug
     * @var string
     */
    private $menu_slug = 'slidemind';

    /**
     * Required capability to access the menu
     * @var string
     */
    private $capability = 'manage_slidemind_configs';

    /**
     * Admin pages
     */
    private $settings_page;

    private $configurations_page;

    /**
     * Constructor
     */
    public function __construct() {
        add_action( 'admin_menu', [$this, 'register_menu'] );
        add_action( 'admin_head', [$this, 'hide_internal_submenus'] );
        add_action( 'admin_enqueue_scripts', [$this, 'enqueue_menu_retarget_script'] );
        add_action( 'admin_enqueue_scripts', [$this, 'enqueue_assets'] );
        add_action( 'admin_init', [$this, 'redirect_legacy_slugs'] );
        add_filter( 'parent_file', [$this, 'fix_menu_highlighting'] );
    }

    /**
     * Redirects legacy slugs to their new equivalents
     */
    public function redirect_legacy_slugs() {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Admin page routing
        if ( !isset( $_GET['page'] ) ) {
            return;
        }
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Admin page routing
        $page = sanitize_text_field( wp_unslash( $_GET['page'] ) );
        // Legacy: slidemind-learners → slidemind-memory
        if ( $page === 'slidemind-learners' ) {
            wp_safe_redirect( admin_url( 'admin.php?page=slidemind-memory' ) );
            exit;
        }
        // Legacy: slidemind-formations → slidemind-courses
        if ( $page === 'slidemind-formations' ) {
            wp_safe_redirect( admin_url( 'admin.php?page=slidemind-courses' ) );
            exit;
        }
        // Legacy: slidemind-formation-edit → slidemind-course-edit
        if ( $page === 'slidemind-formation-edit' ) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Admin page routing
            $id = ( isset( $_GET['id'] ) ? absint( wp_unslash( $_GET['id'] ) ) : 0 );
            $url = admin_url( 'admin.php?page=slidemind-course-edit' );
            if ( $id ) {
                $url .= '&id=' . $id;
            }
            wp_safe_redirect( $url );
            exit;
        }
    }

    /**
     * Register the menu and submenus
     */
    private function get_menu_icon() : string {
        $svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 495.82 350.27">' . '<path d="M461.51,92.2C394.97,50.55,27.28-85.38,2.66,79.7c-24.62,165.08,127.45,263.56,228.01,270.23,100.56,6.67,247.27-86.05,260.16-146.19,12.89-60.14.09-93.14-29.31-111.54Z" fill="#93aa91"/>' . '</svg>';
        return 'data:image/svg+xml;base64,' . base64_encode( $svg );
    }

    public function register_menu() {
        // Main menu
        add_menu_page(
            'SlideMind',
            'SlideMind',
            $this->capability,
            $this->menu_slug,
            [$this, 'render_dashboard'],
            $this->get_menu_icon(),
            30
        );
        // Dashboard (replaces the main menu entry)
        add_submenu_page(
            $this->menu_slug,
            __( 'Dashboard', 'slidemind' ),
            __( 'Dashboard', 'slidemind' ),
            $this->capability,
            $this->menu_slug,
            [$this, 'render_dashboard']
        );
        // Slides (formerly Configurations)
        add_submenu_page(
            $this->menu_slug,
            __( 'Slides', 'slidemind' ),
            __( 'Slides', 'slidemind' ),
            $this->capability,
            $this->menu_slug . '-slides',
            [$this, 'render_slides']
        );
        // New slide (wizard)
        add_submenu_page(
            $this->menu_slug,
            __( 'New Slide', 'slidemind' ),
            __( 'Add New', 'slidemind' ),
            $this->capability,
            $this->menu_slug . '-new',
            [$this, 'render_new_slide']
        );
        // Memory — always visible.
        add_submenu_page(
            $this->menu_slug,
            __( 'Memory', 'slidemind' ),
            __( 'Memory', 'slidemind' ),
            $this->capability,
            $this->menu_slug . '-memory',
            [$this, 'render_memory']
        );
        // Sandbox
        add_submenu_page(
            $this->menu_slug,
            __( 'Sandbox', 'slidemind' ),
            __( 'Sandbox', 'slidemind' ),
            $this->capability,
            $this->menu_slug . '-sandbox',
            [$this, 'render_sandbox']
        );
        // Settings (admin only)
        add_submenu_page(
            $this->menu_slug,
            __( 'Settings', 'slidemind' ),
            __( 'Settings', 'slidemind' ),
            'manage_slidemind_settings',
            $this->menu_slug . '-settings',
            [$this, 'render_settings']
        );
        // Export data tool (data portability — available in free)
        $export_tool = \SlideMind\Plugin::instance()->get_export_tool_page();
        if ( $export_tool ) {
            $export_tool->register_submenu( $this->menu_slug, 'manage_slidemind_settings' );
        }
        add_submenu_page(
            $this->menu_slug,
            __( 'Edit Slide', 'slidemind' ),
            __( 'Edit Slide', 'slidemind' ),
            $this->capability,
            $this->menu_slug . '-slide-edit',
            [$this, 'render_slide_edit']
        );
    }

    /**
     * Removes internal pages (edit, detail) from the visible admin menu.
     * They are registered under the SlideMind parent so that WordPress
     * handles menu highlighting automatically, then hidden here.
     */
    public function hide_internal_submenus() {
        global $submenu;
        if ( empty( $submenu[$this->menu_slug] ) ) {
            return;
        }
        $hidden = [
            'slidemind-course-edit',
            'slidemind-module-edit',
            'slidemind-slide-edit',
            'slidemind-template-edit',
            'slidemind-learner-detail',
            'slidemind-pricing',
            // Freemius "Upgrade ▶" — always hidden, every upgrade CTA points to external slidemind.app/pricing/.
            'slidemind-export-tool',
        ];
        foreach ( $submenu[$this->menu_slug] as $key => $item ) {
            if ( in_array( $item[2], $hidden, true ) ) {
                unset($submenu[$this->menu_slug][$key]);
            }
        }
    }

    /**
     * Opens the external "Upgrade" link in a new tab so users do not lose
     * their admin session when checking pricing.
     *
     * Registered as a handle-less inline script (no echoed <script> tag) so it
     * runs on every admin page through the standard enqueue pipeline.
     *
     * WordPress routes the fifth `add_submenu_page()` argument through
     * `plugin_basename()`, which strips the trailing slash. The upgrade URL
     * is therefore compared slash-insensitively so the selector still hits.
     */
    public function enqueue_menu_retarget_script() : void {
    }

    /**
     * Keeps the SlideMind menu open and highlights the correct submenu
     * when the user is on a hidden edit page (course-edit, slide-edit, etc.).
     *
     * @param string $parent_file The current parent file.
     * @return string
     */
    public function fix_menu_highlighting( $parent_file ) {
        // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Required by WP menu highlighting API
        global $submenu_file, $plugin_page;
        $map = [
            'slidemind-course-edit'    => 'slidemind-courses',
            'slidemind-module-edit'    => 'slidemind-modules',
            'slidemind-slide-edit'     => 'slidemind-slides',
            'slidemind-template-edit'  => 'slidemind-templates',
            'slidemind-learner-detail' => 'slidemind-memory',
        ];
        if ( isset( $map[$plugin_page] ) ) {
            $submenu_file = $map[$plugin_page];
            // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
            return $this->menu_slug;
        }
        return $parent_file;
    }

    /**
     * Enqueue CSS/JS assets for admin
     *
     * @param string $hook The current admin page
     */
    public function enqueue_assets( $hook ) {
        // Check if we're on a plugin page
        if ( strpos( $hook, 'slidemind' ) === false ) {
            return;
        }
        $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' );
        // Freemius account CSS (embedded in Settings > License tab)
        if ( strpos( $hook, 'slidemind-settings' ) !== false && function_exists( 'fs_enqueue_local_style' ) ) {
            fs_enqueue_local_style( 'fs_account', '/admin/account.css' );
        }
        // Self-hosted fonts for pricing page (Epilogue, Plus Jakarta Sans, Gochi Hand).
        if ( strpos( $hook, 'slidemind-pricing' ) !== false ) {
            wp_enqueue_style(
                'slidemind-fonts',
                SLIDEMIND_PLUGIN_URL . 'admin/css/fonts.css',
                [],
                SLIDEMIND_VERSION
            );
        }
        // Global CSS
        wp_enqueue_style(
            'slidemind-admin-global',
            SLIDEMIND_PLUGIN_URL . "admin/css/admin-global{$suffix}.css",
            [],
            SLIDEMIND_VERSION
        );
        // Tribute.js (autocomplete @variable)
        wp_enqueue_style(
            'slidemind-tribute',
            SLIDEMIND_PLUGIN_URL . 'admin/css/vendor/tribute.css',
            [],
            '5.1.3'
        );
        wp_enqueue_script(
            'slidemind-tribute',
            SLIDEMIND_PLUGIN_URL . 'admin/js/vendor/tribute.min.js',
            [],
            '5.1.3',
            true
        );
        // Global JS
        wp_enqueue_script(
            'slidemind-admin-app',
            SLIDEMIND_PLUGIN_URL . "admin/js/admin-app{$suffix}.js",
            ['jquery', 'slidemind-tribute'],
            SLIDEMIND_VERSION,
            true
        );
        // Defaults from settings
        $settings = wp_parse_args( get_option( 'slidemind_settings', [] ), [
            'default_model'       => 'anthropic/claude-3.5-sonnet',
            'default_temperature' => 0.7,
            'default_max_tokens'  => 1024,
        ] );
        // LLM providers
        $providers = \SlideMind\Core\LLMProxy::get_providers();
        $providers_js = [];
        foreach ( $providers as $slug => $info ) {
            $providers_js[$slug] = [
                'label'   => $info['label'],
                'keyHint' => $info['key_hint'],
                'keyUrl'  => $info['key_url'],
            ];
        }
        // JS strings with placeholders — extracted to local variables so /* translators: */ comments survive the Freemius preprocessor (which strips comments from PHP array literals).
        /* translators: %d: number of linked modules */
        $str_cannotDeleteModulesLinked = __( 'Cannot delete: %d linked module(s)', 'slidemind' );
        /* translators: %d: number of linked slides */
        $str_cannotDeleteSlidesLinked = __( 'Cannot delete: %d linked slide(s)', 'slidemind' );
        /* translators: %s: variable name */
        $str_outputVarNameInvalid = __( 'Variable "%s": name must start with a lowercase letter and contain only letters, numbers, and underscores.', 'slidemind' );
        /* translators: %s: variable name */
        $str_outputVarDuplicate = __( 'Variable "%s" is a duplicate.', 'slidemind' );
        /* translators: %s: variable name */
        $str_outputVarEnumRequired = __( 'Variable "%s" (enum): values are required.', 'slidemind' );
        /* translators: %s: JSON parse error message */
        $str_invalidJson = __( 'Invalid JSON: %s', 'slidemind' );
        /* translators: %1$s: current page, %2$s: total pages, %3$s: total learners */
        $str_paginationInfo = __( 'Page %1$s of %2$s (%3$s learners)', 'slidemind' );
        /* translators: %s: estimated cost per interaction */
        $str_pricingPerInteraction = __( '~%s / interaction', 'slidemind' );
        /* translators: %s: module title */
        $str_apiKeyModule = __( 'Uses the key from module "%s".', 'slidemind' );
        /* translators: %s: course title */
        $str_apiKeyCourse = __( 'Uses the key from course "%s".', 'slidemind' );
        /* translators: %d: number of elements created */
        $str_import_created = __( '%d element(s) created', 'slidemind' );
        /* translators: %1$s: variable name, %2$s: slide title */
        $str_editorVarDuplicateWarning = __( 'Variable "%1$s" is already used by slide "%2$s". Each slide should use unique variable names to avoid conflicts in your e-learning project.', 'slidemind' );
        /* translators: %1$s: key name, %2$s: slide title */
        $str_saveKeyDuplicateWarning = __( 'Memory key "%1$s" is already used by slide "%2$s". Using the same key in the same scope will overwrite the saved value.', 'slidemind' );
        /* translators: %s: key name */
        $str_saveKeyMemVarCollision = __( 'Memory key "%s" collides with a capture variable on this slide. They will overwrite each other.', 'slidemind' );
        /* translators: %1$s: number of turns, %2$s: estimated cost */
        $str_costEstimated = __( 'Estimated cost for %1$s turns: ~%2$s', 'slidemind' );
        /* translators: %d: number of selected items */
        $str_memDefSelectedCount = __( '%d selected', 'slidemind' );
        /* translators: %s: variable name */
        $str_memVarNameInvalid = __( 'Variable "%s": name must start with a lowercase letter and contain only letters, numbers, and underscores.', 'slidemind' );
        /* translators: %s: variable name */
        $str_memVarDuplicate = __( 'Variable "%s" is a duplicate.', 'slidemind' );
        /* translators: %s: variable name */
        $str_memVarSourceRequired = __( 'Variable "%s": source authoring tool variable is required.', 'slidemind' );
        // Upgrade URL exists only in the premium build (FeatureGate is absent
        // from the free zip); the free admin JS receives an empty string.
        $upgrade_url = '';
        // JS variables
        $data = [
            'ajaxUrl'           => admin_url( 'admin-ajax.php' ),
            'restUrl'           => rest_url( 'slidemind/v2/' ),
            'siteUrl'           => home_url( '/' ),
            'nonce'             => wp_create_nonce( 'slidemind_admin_nonce' ),
            'restNonce'         => wp_create_nonce( 'wp_rest' ),
            'providers'         => $providers_js,
            'globalProvider'    => get_option( 'slidemind_global_provider', 'openrouter' ),
            'defaults'          => [
                'model'       => $settings['default_model'],
                'temperature' => (float) $settings['default_temperature'],
                'maxTokens'   => (int) $settings['default_max_tokens'],
                'editor'      => $settings['default_editor'] ?? 'storyline',
            ],
            'favoriteTemplates' => ( !empty( $settings['favorite_templates'] ) ? $settings['favorite_templates'] : [
                'quiz',
                'open-question',
                'formative-eval',
                'socratic',
                'roleplay',
                'guided-exploration'
            ] ),
            'hasApiKey'         => \SlideMind\Plugin::instance()->get_api_key_manager()->has_any_api_key(),
            'pluginUrl'         => SLIDEMIND_PLUGIN_URL,
            'version'           => SLIDEMIND_VERSION,
            'upgradeUrl'        => $upgrade_url,
            'strings'           => [
                'apiKeyRequired'                => __( 'API key required', 'slidemind' ),
                'apiKeyRequiredMessage'         => __( 'You need to configure an API key before creating slides.', 'slidemind' ),
                'apiKeyGoToSettings'            => __( 'Go to Settings', 'slidemind' ),
                'confirmDelete'                 => __( 'Are you sure you want to delete this item?', 'slidemind' ),
                'copied'                        => __( 'Copied!', 'slidemind' ),
                'error'                         => __( 'An error occurred', 'slidemind' ),
                'saving'                        => __( 'Saving...', 'slidemind' ),
                'saved'                         => __( 'Saved', 'slidemind' ),
                'saveButton'                    => __( 'Save', 'slidemind' ),
                'updateButton'                  => __( 'Update', 'slidemind' ),
                'cancelButton'                  => __( 'Cancel', 'slidemind' ),
                'loading'                       => __( 'Loading...', 'slidemind' ),
                'loadingVariables'              => __( 'Loading variables...', 'slidemind' ),
                'noVariableFound'               => __( 'No variable found', 'slidemind' ),
                'noVariableAvailable'           => __( 'No variable available', 'slidemind' ),
                'inserted'                      => __( 'inserted', 'slidemind' ),
                'variableNamePrompt'            => __( 'Variable name (without braces):', 'slidemind' ),
                'testing'                       => __( 'Testing...', 'slidemind' ),
                'testButton'                    => __( 'Test', 'slidemind' ),
                'validKey'                      => __( 'Valid API key', 'slidemind' ),
                'invalidKey'                    => __( 'Invalid API key', 'slidemind' ),
                'enterValidApiKey'              => __( 'Enter a valid API key', 'slidemind' ),
                'selectModelPlaceholder'        => __( 'Select a model...', 'slidemind' ),
                'noModelsEnterKey'              => __( 'Enter a valid API key to load models', 'slidemind' ),
                'confirmDeleteApiKey'           => __( 'Delete the dedicated API key? The global key will be used instead.', 'slidemind' ),
                'apiKeyWillBeCleared'           => __( 'The dedicated key will be deleted on save.', 'slidemind' ),
                'unsavedChanges'                => __( 'You have unsaved changes. Are you sure you want to leave this page?', 'slidemind' ),
                'confirmDeleteCourse'           => __( 'Are you sure you want to delete this course?', 'slidemind' ),
                'cannotDeleteModulesLinked'     => $str_cannotDeleteModulesLinked,
                'createCourse'                  => __( 'Create a course', 'slidemind' ),
                'selectCourse'                  => __( 'Select a course', 'slidemind' ),
                'createCourseFirst'             => __( 'Create a course first', 'slidemind' ),
                'confirmDeleteModule'           => __( 'Are you sure you want to delete this module?', 'slidemind' ),
                'cannotDeleteSlidesLinked'      => $str_cannotDeleteSlidesLinked,
                'createModule'                  => __( 'Create a module', 'slidemind' ),
                'selectModule'                  => __( 'Select a module', 'slidemind' ),
                'noModules'                     => __( 'No modules for this course', 'slidemind' ),
                'createModuleFirst'             => __( 'Create a module first', 'slidemind' ),
                'confirmDeleteSlide'            => __( 'Are you sure you want to delete this slide?', 'slidemind' ),
                'createSlide'                   => __( 'Create a slide', 'slidemind' ),
                'selectCourseFirst'             => __( 'Select a course first', 'slidemind' ),
                'noneCourseLevel'               => __( 'None (course-level slide)', 'slidemind' ),
                'hintBoolean'                   => __( 'Returns true or false', 'slidemind' ),
                'hintNumber'                    => __( 'Returns a number', 'slidemind' ),
                'typeText'                      => __( 'Text', 'slidemind' ),
                'typeNumber'                    => __( 'Number', 'slidemind' ),
                'typeBoolean'                   => __( 'Boolean', 'slidemind' ),
                'typeEnum'                      => __( 'Enum', 'slidemind' ),
                'placeholderDescOptional'       => __( 'Description (optional)', 'slidemind' ),
                'placeholderDescNumber'         => __( 'Description (e.g.: score out of 10)', 'slidemind' ),
                'placeholderDescBoolean'        => __( 'Condition to evaluate (e.g.: did they answer correctly?)', 'slidemind' ),
                'outputVarNameInvalid'          => $str_outputVarNameInvalid,
                'outputVarDuplicate'            => $str_outputVarDuplicate,
                'outputVarEnumRequired'         => $str_outputVarEnumRequired,
                'outputVarNameTitle'            => __( 'Lowercase letters, digits and underscores. Must start with a letter.', 'slidemind' ),
                'confirmDeleteTemplate'         => __( 'Are you sure you want to delete this template?', 'slidemind' ),
                'cannotDeleteDefault'           => __( 'Cannot delete a default template', 'slidemind' ),
                'templateExported'              => __( 'Template exported', 'slidemind' ),
                'templateImported'              => __( 'Template imported successfully', 'slidemind' ),
                'templateReset'                 => __( 'Template reset', 'slidemind' ),
                'confirmResetTemplate'          => __( 'Reset this template to its default values?', 'slidemind' ),
                'createTemplate'                => __( 'Create a template', 'slidemind' ),
                'addFavorite'                   => __( 'Add to favorites', 'slidemind' ),
                'removeFavorite'                => __( 'Remove from favorites', 'slidemind' ),
                'addedToFavorites'              => __( 'Added to favorites', 'slidemind' ),
                'removedFromFavorites'          => __( 'Removed from favorites', 'slidemind' ),
                'pasteJsonContent'              => __( 'Paste the template JSON content', 'slidemind' ),
                'invalidJson'                   => $str_invalidJson,
                'importing'                     => __( 'Importing...', 'slidemind' ),
                'importButton'                  => __( 'Import', 'slidemind' ),
                'confirmPurgeLearner'           => __( 'Are you sure you want to purge all data for this learner?', 'slidemind' ),
                'confirmDeleteVariable'         => __( 'Delete this variable?', 'slidemind' ),
                'paginationInfo'                => $str_paginationInfo,
                'prevPage'                      => __( 'Previous', 'slidemind' ),
                'nextPage'                      => __( 'Next', 'slidemind' ),
                'exportCsvDone'                 => __( 'CSV export completed', 'slidemind' ),
                'viewWpProfile'                 => __( 'View WordPress profile', 'slidemind' ),
                'colVariable'                   => __( 'Variable', 'slidemind' ),
                'colValue'                      => __( 'Value', 'slidemind' ),
                'colLastModified'               => __( 'Last modified', 'slidemind' ),
                'colActions'                    => __( 'Actions', 'slidemind' ),
                'anonymousSession'              => __( 'Anonymous', 'slidemind' ),
                'anonymousSessionTtlLabel'      => __( 'Anonymous session lifetime', 'slidemind' ),
                'anonymousSessionTtlHelp'       => __( 'Memory data from anonymous sessions is automatically deleted after this period of inactivity.', 'slidemind' ),
                'pgModalTitle'                  => __( 'Generate a prompt with AI', 'slidemind' ),
                'pgModelLabel'                  => __( 'Generation model', 'slidemind' ),
                'pgTypeLabel'                   => __( 'Interaction type', 'slidemind' ),
                'pgSelectPlaceholder'           => __( '— Select —', 'slidemind' ),
                'pgTypeSocratic'                => __( 'Socratic tutoring', 'slidemind' ),
                'pgTypeQuiz'                    => __( 'Interactive quiz', 'slidemind' ),
                'pgTypeFeedback'                => __( 'Personalized feedback', 'slidemind' ),
                'pgTypeRoleplay'                => __( 'Role-play / Simulation', 'slidemind' ),
                'pgTypeCaseStudy'               => __( 'Case study', 'slidemind' ),
                'pgTypeReformulation'           => __( 'Reformulation / Explanation', 'slidemind' ),
                'pgTypeFormative'               => __( 'Formative assessment', 'slidemind' ),
                'pgSubjectLabel'                => __( 'Subject', 'slidemind' ),
                'pgSubjectPlaceholder'          => __( 'E.g.: Leadership styles in remote teams', 'slidemind' ),
                'pgObjectiveLabel'              => __( 'Learning objective', 'slidemind' ),
                'pgObjectivePlaceholder'        => __( 'E.g.: Identify the 4 styles and their application contexts', 'slidemind' ),
                'pgToneLabel'                   => __( 'Tone', 'slidemind' ),
                'pgToneDefault'                 => __( '— Default —', 'slidemind' ),
                'pgToneBenevolent'              => __( 'Benevolent', 'slidemind' ),
                'pgToneProfessional'            => __( 'Professional', 'slidemind' ),
                'pgToneWarm'                    => __( 'Warm', 'slidemind' ),
                'pgToneStimulating'             => __( 'Stimulating', 'slidemind' ),
                'pgTonePlayful'                 => __( 'Playful', 'slidemind' ),
                'pgLevelLabel'                  => __( 'Level', 'slidemind' ),
                'pgLevelBeginner'               => __( 'Beginner', 'slidemind' ),
                'pgLevelIntermediate'           => __( 'Intermediate', 'slidemind' ),
                'pgLevelAdvanced'               => __( 'Advanced', 'slidemind' ),
                'pgLevelExpert'                 => __( 'Expert', 'slidemind' ),
                'pgVariablesLabel'              => __( 'Variables to include', 'slidemind' ),
                'pgGenerateButton'              => __( 'Generate', 'slidemind' ),
                'pgGenerating'                  => __( 'Generating...', 'slidemind' ),
                'pgErrorSelectType'             => __( 'Please select an interaction type.', 'slidemind' ),
                'pgErrorEnterSubject'           => __( 'Please enter a subject.', 'slidemind' ),
                'pgPromptGenerated'             => __( 'Prompt generated successfully', 'slidemind' ),
                'pgGenerationError'             => __( 'Error during generation', 'slidemind' ),
                'pgServerError'                 => __( 'Server error — check the console for more details.', 'slidemind' ),
                'pgSessionExpired'              => __( 'Session expired — reload the page and try again.', 'slidemind' ),
                'pgVarGroupSystem'              => __( 'System', 'slidemind' ),
                'pgVarGroupMemory'              => __( 'Memory', 'slidemind' ),
                'pgVarGroupProfile'             => __( 'Profile', 'slidemind' ),
                'pgVarGroupTemplate'            => __( 'Template', 'slidemind' ),
                'pgVarGroupCustom'              => __( 'Custom', 'slidemind' ),
                'sessionActive'                 => __( 'Session active', 'slidemind' ),
                'sessionInactive'               => __( 'Session inactive', 'slidemind' ),
                'conversationRestored'          => __( 'Conversation restored from your previous session.', 'slidemind' ),
                'conversationReset'             => __( 'Conversation reset.', 'slidemind' ),
                'debugSendMessage'              => __( 'Send a message to see debug information.', 'slidemind' ),
                'debugRequestInfo'              => __( 'Request information', 'slidemind' ),
                'debugModel'                    => __( 'Model', 'slidemind' ),
                'debugTokensInput'              => __( 'Tokens (input)', 'slidemind' ),
                'debugTokensOutput'             => __( 'Tokens (output)', 'slidemind' ),
                'debugTokensTotal'              => __( 'Tokens (total)', 'slidemind' ),
                'debugResponseTime'             => __( 'Response time', 'slidemind' ),
                'debugEstimatedCost'            => __( 'Estimated cost', 'slidemind' ),
                'debugSystemPrompt'             => __( 'System prompt', 'slidemind' ),
                'tabOriginal'                   => __( 'Original', 'slidemind' ),
                'tabRendered'                   => __( 'Rendered', 'slidemind' ),
                'debugVarsInjected'             => __( 'Injected variables:', 'slidemind' ),
                'debugVarsMissing'              => __( 'Missing variables:', 'slidemind' ),
                'debugStructuredResponse'       => __( 'Structured response', 'slidemind' ),
                'debugPartialParsing'           => __( 'Partial parsing', 'slidemind' ),
                'debugPartialParsingDesc'       => __( 'The response was not valid JSON.', 'slidemind' ),
                'selectConfigPrompt'            => __( 'Select a slide to view the prompt.', 'slidemind' ),
                'noVarsDetected'                => __( 'No <code>{{name}}</code> variable detected in the prompt.', 'slidemind' ),
                'errorPrefix'                   => __( 'Error: ', 'slidemind' ),
                'unknownError'                  => __( 'Unknown error', 'slidemind' ),
                'connectionError'               => __( 'Connection error', 'slidemind' ),
                'exportError'                   => __( 'Error during export', 'slidemind' ),
                'confirmApplyChanges'           => __( 'Apply changes to the slide? This will overwrite the current values.', 'slidemind' ),
                'changesApplied'                => __( 'Changes applied to the slide', 'slidemind' ),
                'saveError'                     => __( 'Error while saving', 'slidemind' ),
                'validateButton'                => __( 'Validate', 'slidemind' ),
                'hintBooleanShort'              => __( 'true / false', 'slidemind' ),
                'hintNumberShort'               => __( 'Number', 'slidemind' ),
                'placeholderDescCondition'      => __( 'Condition (e.g.: did they answer correctly?)', 'slidemind' ),
                'comparisonTitle'               => __( 'Multi-model comparison', 'slidemind' ),
                'comparisonRun'                 => __( 'Run comparison', 'slidemind' ),
                'comparisonRunning'             => __( 'Comparison in progress...', 'slidemind' ),
                'comparisonExport'              => __( 'Export JSON', 'slidemind' ),
                'comparisonModel'               => __( 'Model', 'slidemind' ),
                'comparisonSelectModel'         => __( 'Select a model...', 'slidemind' ),
                'comparisonAddModel'            => __( 'Add a model', 'slidemind' ),
                'comparisonMessage'             => __( 'Test message', 'slidemind' ),
                'comparisonMessagePlaceholder'  => __( 'Type the message to send to the models...', 'slidemind' ),
                'comparisonWaiting'             => __( 'Waiting for comparison...', 'slidemind' ),
                'comparisonSummary'             => __( 'Comparison summary', 'slidemind' ),
                'comparisonTokens'              => __( 'Tokens', 'slidemind' ),
                'comparisonFastest'             => __( 'Fastest', 'slidemind' ),
                'comparisonCheapest'            => __( 'Cheapest', 'slidemind' ),
                'comparisonCompareOthers'       => __( 'Compare with other models', 'slidemind' ),
                'comparisonPromptLabel'         => __( 'Prompt:', 'slidemind' ),
                'comparisonEnterMessage'        => __( 'Enter a test message', 'slidemind' ),
                'comparisonMinModels'           => __( 'Select at least 2 models', 'slidemind' ),
                'comparisonAbortConfirm'        => __( 'A comparison is in progress. Close anyway?', 'slidemind' ),
                'varAlreadyExists'              => __( 'A variable with this name already exists.', 'slidemind' ),
                'pricingPerInteraction'         => $str_pricingPerInteraction,
                'pricingFree'                   => __( 'Free', 'slidemind' ),
                'pricingEstimatedCost'          => __( 'Estimated cost:', 'slidemind' ),
                'titleRequired'                 => __( 'Title is required', 'slidemind' ),
                'selectModel'                   => __( 'Select a model', 'slidemind' ),
                'testError'                     => __( 'Error during test', 'slidemind' ),
                'creationError'                 => __( 'Error during creation', 'slidemind' ),
                'enterTestMessage'              => __( 'Enter a test message', 'slidemind' ),
                'creating'                      => __( 'Creating...', 'slidemind' ),
                'responseExample'               => __( 'Response example', 'slidemind' ),
                'responseExampleHelp'           => __( 'Define an example of the expected response format. It will be automatically appended to the system prompt.', 'slidemind' ),
                'labelCourse'                   => __( 'Course:', 'slidemind' ),
                'labelTheme'                    => __( 'Theme:', 'slidemind' ),
                'labelObjectives'               => __( 'Objectives:', 'slidemind' ),
                'labelModule'                   => __( 'Module:', 'slidemind' ),
                'labelContent'                  => __( 'Content:', 'slidemind' ),
                'labelResponseExample'          => __( 'Response example', 'slidemind' ),
                'labelVariables'                => __( 'Variables:', 'slidemind' ),
                'apiKeyGlobal'                  => __( 'Uses the default global key.', 'slidemind' ),
                'apiKeyModule'                  => $str_apiKeyModule,
                'apiKeyCourse'                  => $str_apiKeyCourse,
                'buttonDelete'                  => __( 'Delete', 'slidemind' ),
                'buttonEdit'                    => __( 'Edit', 'slidemind' ),
                'copyCode'                      => __( 'Copy code', 'slidemind' ),
                'buttonExpand'                  => __( 'Expand', 'slidemind' ),
                'export_course'                 => __( 'Export course', 'slidemind' ),
                'export_module'                 => __( 'Export module', 'slidemind' ),
                'export_slide'                  => __( 'Export slide', 'slidemind' ),
                'import_course'                 => __( 'Import course(s)', 'slidemind' ),
                'import_module'                 => __( 'Import module(s)', 'slidemind' ),
                'import_slide'                  => __( 'Import slide(s)', 'slidemind' ),
                'import_select_course'          => __( 'Select the target course', 'slidemind' ),
                'import_select_module'          => __( 'Select the target module', 'slidemind' ),
                'import_json_label'             => __( 'JSON file or paste content', 'slidemind' ),
                'import_success'                => __( 'Import successful', 'slidemind' ),
                'import_created'                => $str_import_created,
                'import_error_format'           => __( 'Invalid file format', 'slidemind' ),
                'exporting'                     => __( 'Exporting...', 'slidemind' ),
                'bulkExportSuccess'             => __( 'Export complete', 'slidemind' ),
                'bulkInvalidFormat'             => __( 'Invalid backup format. Please select a SlideMind full backup file.', 'slidemind' ),
                'bulkPreviewTitle'              => __( 'Backup contents', 'slidemind' ),
                'bulkPreviewCourses'            => __( 'Courses', 'slidemind' ),
                'bulkPreviewModules'            => __( 'Modules', 'slidemind' ),
                'bulkPreviewSlides'             => __( 'Slides', 'slidemind' ),
                'bulkPreviewTemplates'          => __( 'Templates', 'slidemind' ),
                'bulkPreviewMemory'             => __( 'Memory definitions', 'slidemind' ),
                'bulkPreviewDate'               => __( 'Date', 'slidemind' ),
                'bulkImportConfirm'             => __( 'Import this backup? New items will be created (existing data will not be overwritten).', 'slidemind' ),
                'bulkImportErrors'              => __( 'Errors', 'slidemind' ),
                'exportAll'                     => __( 'Export all', 'slidemind' ),
                'importAnalyze'                 => __( 'Analyze file', 'slidemind' ),
                'importAnalyzing'               => __( 'Analyzing…', 'slidemind' ),
                'importProvideFile'             => __( 'Provide a file or paste JSON before analyzing.', 'slidemind' ),
                'importSessionExpired'          => __( 'Import session expired. Please re-analyze the file.', 'slidemind' ),
                'importSource'                  => __( 'Source', 'slidemind' ),
                'importCollisionExists'         => __( 'Exists', 'slidemind' ),
                'importActionNew'               => __( 'Create', 'slidemind' ),
                'importActionDuplicate'         => __( 'Duplicate', 'slidemind' ),
                'importActionOverwrite'         => __( 'Overwrite', 'slidemind' ),
                'importActionSkip'              => __( 'Skip', 'slidemind' ),
                'importDefaultForMatches'       => __( 'Default action for matches', 'slidemind' ),
                'importApplySettingsLabel'      => __( 'Apply plugin settings from backup (API keys and license untouched)', 'slidemind' ),
                'importMemoryVariablesNotice'   => __( 'Archive-only section — not imported.', 'slidemind' ),
                'importNoSectionsSelected'      => __( 'Select at least one item before importing.', 'slidemind' ),
                'importHeldForScope'            => __( 'Other items in this file (not imported from this dialog)', 'slidemind' ),
                'importFilterPlaceholder'       => __( 'Filter by title…', 'slidemind' ),
                'importStart'                   => __( 'Import selected', 'slidemind' ),
                'importInProgress'              => __( 'Importing…', 'slidemind' ),
                'importReportCreated'           => __( 'Created', 'slidemind' ),
                'importReportOverwritten'       => __( 'Overwritten', 'slidemind' ),
                'importReportSkipped'           => __( 'Skipped', 'slidemind' ),
                'importReportHolders'           => __( 'Holder parents created', 'slidemind' ),
                'importReportMemoryVariables'   => __( 'Memory variables (not imported)', 'slidemind' ),
                'importReportMemoryDefinitions' => __( 'Memory definitions imported', 'slidemind' ),
                'importReportSettingsApplied'   => __( 'Settings applied', 'slidemind' ),
                'importReportErrors'            => __( 'Errors', 'slidemind' ),
                'importYes'                     => __( 'Yes', 'slidemind' ),
                'importNo'                      => __( 'No', 'slidemind' ),
                'importSectionCourses'          => __( 'Courses', 'slidemind' ),
                'importSectionModules'          => __( 'Modules', 'slidemind' ),
                'importSectionSlides'           => __( 'Slides', 'slidemind' ),
                'importSectionTemplates'        => __( 'Custom templates', 'slidemind' ),
                'importSectionMemoryDefs'       => __( 'Memory definitions', 'slidemind' ),
                'importSectionSettings'         => __( 'Plugin settings', 'slidemind' ),
                'resetToDefault'                => __( 'Reset to default', 'slidemind' ),
                'editorVarDuplicateWarning'     => $str_editorVarDuplicateWarning,
                'saveKeyDuplicateWarning'       => $str_saveKeyDuplicateWarning,
                'saveKeyMemVarCollision'        => $str_saveKeyMemVarCollision,
                'codeBetaWarning'               => __( 'This authoring tool integration is currently in <strong>beta</strong>. The generated code has not been fully tested. Please report any issues.', 'slidemind' ),
                'codeEditorWidget'              => __( 'Universal widget (iframe)', 'slidemind' ),
                'codeInstructionsStoryline'     => __( 'Paste into an <strong>Execute JavaScript</strong> trigger.', 'slidemind' ),
                'codeInstructionsCaptivate'     => __( 'Create the variables in Captivate, then paste into <strong>Execute JavaScript</strong>.', 'slidemind' ),
                'codeInstructionsLectora'       => __( 'Create the variables in Lectora, then add into <strong>Run JavaScript</strong>.', 'slidemind' ),
                'codeInstructionsDominknow'     => __( 'Add into an <strong>HTML Widget</strong>.', 'slidemind' ),
                'codeInstructionsIspring'       => __( 'Add into a <strong>Web Object</strong> or an <strong>Execute JavaScript</strong> trigger.', 'slidemind' ),
                'codeInstructionsWidget'        => __( 'Embed as a <strong>web object</strong> or <strong>iframe</strong> in your authoring tool.', 'slidemind' ),
                'costEstimated'                 => $str_costEstimated,
                'costCumulativeExplanation'     => __( 'Chat interactions are cumulative: each turn sends the full history, so costs grow quadratically.', 'slidemind' ),
                'costUnlimitedWarning'          => __( 'Warning: unlimited turns — costs will increase continuously.', 'slidemind' ),
                'memDefTabDefinitions'          => __( 'Definitions', 'slidemind' ),
                'memDefTabLearners'             => __( 'Learner Data', 'slidemind' ),
                'memDefAddVariable'             => __( 'Add a variable', 'slidemind' ),
                'memDefGenerateCode'            => __( 'Save to memory', 'slidemind' ),
                'memDefNoDefinitions'           => __( 'No memory variables defined yet.', 'slidemind' ),
                'memDefNoSlideVars'             => __( 'No slides have memory variables configured.', 'slidemind' ),
                'memDefConfirmDelete'           => __( 'Delete this variable definition?', 'slidemind' ),
                'memDefSelectEditor'            => __( 'Select authoring tool', 'slidemind' ),
                'memDefCodeCopied'              => __( 'Code copied to clipboard', 'slidemind' ),
                'memDefGenerateRetrieve'        => __( 'Load into authoring tool', 'slidemind' ),
                'memDefRetrieveMapping'         => __( 'Map each memory variable to the authoring tool variable that will receive its value.', 'slidemind' ),
                'memDefRetrieveComment'         => __( 'Retrieve memory variables', 'slidemind' ),
                'memDefRetrieveCodeCopied'      => __( 'Code copied to clipboard', 'slidemind' ),
                'memDefSelectedCount'           => $str_memDefSelectedCount,
                'memProfileTab'                 => __( 'Learner Profile', 'slidemind' ),
                'memProfileSave'                => __( 'Save profile settings', 'slidemind' ),
                'memProfileSaved'               => __( 'Profile settings saved', 'slidemind' ),
                'memProfileNoFields'            => __( 'No profile fields available.', 'slidemind' ),
                'memProfileRetrieveComment'     => __( 'Retrieve learner profile', 'slidemind' ),
                'memProfileCheckAll'            => __( 'Check all / Uncheck all', 'slidemind' ),
                'memProfileAliasPlaceholder'    => __( 'alias (e.g.: status)', 'slidemind' ),
                'memProfileEditAlias'           => __( 'Edit alias', 'slidemind' ),
                'memProfileGenerateRetrieve'    => __( 'Load into authoring tool', 'slidemind' ),
                'memProfileSelectFields'        => __( 'Check at least one profile field.', 'slidemind' ),
                'memProfileNotInstalled'        => __( 'Not installed', 'slidemind' ),
                'memoryAccordionTitle'          => __( 'Persistent memory', 'slidemind' ),
                'memSaveInteraction'            => __( 'Save exchange to memory', 'slidemind' ),
                'memSaveUserInput'              => __( 'Learner input', 'slidemind' ),
                'memSaveAiResponse'             => __( 'AI response', 'slidemind' ),
                'memVarTitle'                   => __( 'Capture a variable and add it to persistent memory.', 'slidemind' ),
                'memVarNamePlaceholder'         => __( 'memory_key', 'slidemind' ),
                'memVarSourcePlaceholder'       => __( 'Authoring tool variable (e.g. Learner_Profession)', 'slidemind' ),
                'memVarScopeModule'             => __( 'Module', 'slidemind' ),
                'memVarScopeCourse'             => __( 'Course', 'slidemind' ),
                'memVarScopeGlobal'             => __( 'Global', 'slidemind' ),
                'memVarNameInvalid'             => $str_memVarNameInvalid,
                'memVarDuplicate'               => $str_memVarDuplicate,
                'memVarSourceRequired'          => $str_memVarSourceRequired,
                'memVarNoVarsDefined'           => __( 'Add at least one memory variable to generate integration code.', 'slidemind' ),
                'memVarCaptureComment'          => __( 'Variable capture', 'slidemind' ),
                'memVarAddButton'               => __( 'Add a memory variable', 'slidemind' ),
                'memScopeHintGlobal'            => __( 'Accessible everywhere', 'slidemind' ),
                'memScopeHintCourse'            => __( 'Accessible in this course only', 'slidemind' ),
                'memScopeHintModule'            => __( 'Accessible in this module only', 'slidemind' ),
                'memScopeWarning'               => __( 'Choose Global if you may need this variable elsewhere.', 'slidemind' ),
                'modeCapture'                   => __( 'Capture', 'slidemind' ),
                'modeCaptureDesc'               => __( 'Data capture without AI', 'slidemind' ),
                'templateCustomName'            => __( 'Custom', 'slidemind' ),
                'templateCustomDesc'            => __( 'Write your own prompt', 'slidemind' ),
                'otherTemplates'                => __( 'Other templates', 'slidemind' ),
                'chooseTemplate'                => __( '— Choose a template —', 'slidemind' ),
            ],
        ];
        wp_localize_script( 'slidemind-admin-app', 'slidemindAdmin', $data );
        // Select2 for selectors
        wp_enqueue_style(
            'select2',
            SLIDEMIND_PLUGIN_URL . 'admin/css/vendor/select2.min.css',
            [],
            '4.1.0'
        );
        wp_enqueue_script(
            'select2',
            SLIDEMIND_PLUGIN_URL . 'admin/js/vendor/select2.min.js',
            ['jquery'],
            '4.1.0',
            true
        );
        // Wizard assets (new slide page)
        if ( strpos( $hook, 'slidemind-new' ) !== false ) {
            wp_enqueue_style(
                'slidemind-wizard',
                SLIDEMIND_PLUGIN_URL . "admin/css/wizard{$suffix}.css",
                ['slidemind-admin-global'],
                SLIDEMIND_VERSION
            );
            wp_enqueue_script(
                'slidemind-wizard',
                SLIDEMIND_PLUGIN_URL . "admin/js/wizard{$suffix}.js",
                ['jquery', 'slidemind-admin-app', 'select2'],
                SLIDEMIND_VERSION,
                true
            );
        }
        // Sandbox assets
        if ( strpos( $hook, 'slidemind-sandbox' ) !== false ) {
            wp_enqueue_style(
                'slidemind-sandbox',
                SLIDEMIND_PLUGIN_URL . "admin/css/sandbox{$suffix}.css",
                ['slidemind-admin-global'],
                SLIDEMIND_VERSION
            );
            wp_enqueue_script(
                'slidemind-sandbox',
                SLIDEMIND_PLUGIN_URL . "admin/js/sandbox{$suffix}.js",
                ['jquery', 'slidemind-admin-app'],
                SLIDEMIND_VERSION,
                true
            );
        }
    }

    /**
     * Render the dashboard
     */
    public function render_dashboard() {
        include SLIDEMIND_PLUGIN_PATH . 'admin/views/dashboard.php';
    }

    /**
     * Render the courses list
     */
    public function render_courses() {
    }

    /**
     * Render the course edit form
     */
    public function render_course_edit() {
    }

    /**
     * Render the modules list
     */
    public function render_modules() {
    }

    /**
     * Render the module edit form
     */
    public function render_module_edit() {
    }

    /**
     * Render the slides list
     */
    public function render_slides() {
        include SLIDEMIND_PLUGIN_PATH . 'admin/views/slides-list.php';
    }

    /**
     * Render the slide edit form
     */
    public function render_slide_edit() {
        include SLIDEMIND_PLUGIN_PATH . 'admin/views/slide-edit.php';
    }

    /**
     * Render the new slide wizard
     */
    public function render_new_slide() {
        // Gate: require at least one API key configured.
        $api_key_manager = \SlideMind\Plugin::instance()->get_api_key_manager();
        if ( !$api_key_manager->has_any_api_key() ) {
            include SLIDEMIND_PLUGIN_PATH . 'admin/views/partials/api-key-gate.php';
            return;
        }
        // Expert mode or wizard?
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Admin page routing
        $mode = ( isset( $_GET['mode'] ) ? sanitize_text_field( wp_unslash( $_GET['mode'] ) ) : 'wizard' );
        if ( $mode === 'expert' ) {
            include SLIDEMIND_PLUGIN_PATH . 'admin/views/slide-edit.php';
        } else {
            include SLIDEMIND_PLUGIN_PATH . 'admin/views/wizard/wizard.php';
        }
    }

    /**
     * Render the templates list
     */
    public function render_templates() {
    }

    /**
     * Render the template edit form
     */
    public function render_template_edit() {
    }

    /**
     * Render the sandbox
     */
    public function render_sandbox() {
        include SLIDEMIND_PLUGIN_PATH . 'admin/views/sandbox.php';
    }

    /**
     * Render the analytics page (Pro only).
     *
     * No-op in the free zip: the premium controller is stripped, so this
     * callback does nothing if reached unexpectedly.
     */
    public function render_analytics() {
    }

    /**
     * Render the settings page
     */
    public function render_settings() {
        include SLIDEMIND_PLUGIN_PATH . 'admin/views/settings.php';
    }

    /**
     * Render the Memory hub
     */
    public function render_memory() {
        include SLIDEMIND_PLUGIN_PATH . 'admin/views/memory-hub.php';
    }

    /**
     * Render the learner detail page (Pro only).
     *
     * No-op in the free zip: the premium controller is stripped.
     */
    public function render_learner_detail() {
    }

    public function render_memory_upsell() {
    }

    public function render_courses_upsell() {
    }

    public function render_modules_upsell() {
    }

    public function render_analytics_upsell() {
    }

    /**
     * Return the menu slug
     *
     * @return string
     */
    public function get_menu_slug() {
        return $this->menu_slug;
    }

}
