<?php

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

class SEO_Fury_Admin
{

    private $core;

    public function __construct($core)
    {
        $this->core = $core;
        $this->init_hooks();
    }

    private function init_hooks()
    {
        // Buffer output during options.php processing to prevent
        // "headers already sent" when third-party notices fire before redirect.
        add_action('admin_init', array($this, 'maybe_buffer_options_save'), 1);

        add_action('admin_menu', array($this, 'add_admin_menu'));
        add_action('admin_head', array($this, 'admin_menu_icon_css'));

        add_action('admin_init', array($this, 'register_settings'));

        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets'));

        add_action('update_option_seo_fury_html_sitemap_slug', array($this, 'flush_on_slug_change'), 10, 2);
        add_action('update_option_seo_fury_sitemap_enabled', array($this, 'flush_on_sitemap_toggle'), 10, 2);

        add_action('update_option_seo_fury_sitemap_post_types', array($this, 'flush_on_post_types_change'), 10, 2);
        add_action('update_option_seo_fury_html_sitemap_post_types', array($this, 'flush_on_html_post_types_change'), 10, 2);

        // Uninstall dialog on plugins.php
        add_action('admin_enqueue_scripts', array($this, 'enqueue_uninstall_dialog'));
        add_action('wp_ajax_seo_fury_set_delete_preference', array($this, 'ajax_set_delete_preference'));

        // PRO upgrade notice (only when PRO addon is NOT active)
        if (!apply_filters('seo_fury_is_pro', false)) {
            add_action('admin_notices', array($this, 'maybe_show_pro_upgrade_notice'));
            add_action('wp_ajax_seo_fury_dismiss_pro_notice', array($this, 'ajax_dismiss_pro_notice'));
        }

        // Conflict detector: warn when another SEO plugin is active too
        add_action('admin_notices', array($this, 'maybe_show_conflict_notice'));
        add_action('wp_ajax_seo_fury_dismiss_conflict_notice', array($this, 'ajax_dismiss_conflict_notice'));

        // Allow PRO addon to register its own hooks
        do_action('seo_fury_admin_init_hooks', $this);
    }

    /**
     * Start output buffering when WordPress processes options.php saves.
     * This prevents third-party notices (e.g. WooCommerce textdomain warnings)
     * from breaking the redirect with "headers already sent" errors.
     */
    public function maybe_buffer_options_save()
    {
        global $pagenow;
        if ($pagenow === 'options.php') {
            ob_start();
        }
    }


    public function add_admin_menu()
    {
        $plugin_name = function_exists('seo_fury_get_brand_name') ? seo_fury_get_brand_name() : 'SEO Fury';

        $icon = 'data:image/svg+xml;base64,' . base64_encode('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"><path fill="#E53935" d="M165.1,85.6c7-7.4,4.6-17.1-4.2-17.1h-60c-2.8,0-2.3-3.9,0.6-4.9l36.8-12.4c5.6-1.9,10.8-6,14-11.1l16.1-25.6C173,7.4,169.8,0,162.3,0H85c-5.6,0-11.7,4.2-14.1,9.8l-40.4,95.5c-2.8,6.6,0.6,12.4,7.3,12.4H80l-30,75.7c-2.5,6.3,4.9,9.1,9.9,3.8L165.1,85.6z"/></svg>');
        add_menu_page($plugin_name, $plugin_name, 'manage_options', 'seo-fury', array($this, 'settings_page'), $icon, 30);
        add_submenu_page('seo-fury', __('Settings', 'seo-fury'), __('Settings', 'seo-fury'), 'manage_options', 'seo-fury', array($this, 'settings_page'));

        // "Get PRO" submenu item (only when PRO not active)
        if (!apply_filters('seo_fury_is_pro', false)) {
            add_submenu_page(
                'seo-fury',
                __('Get PRO', 'seo-fury'),
                '<span style="color:#F59E0B;">&#9889; ' . __('Get PRO', 'seo-fury') . '</span>',
                'manage_options',
                'seo-fury-get-pro',
                array($this, 'render_get_pro_page')
            );
        }
    }

    /**
     * Output CSS to show the colored SVG icon in the admin menu.
     * WordPress applies fill:currentColor to menu icons — this overrides it.
     */
    public function admin_menu_icon_css() {
        echo '<style>
            #adminmenu .toplevel_page_seo-fury .wp-menu-image.svg img {
                opacity: 1 !important;
                filter: none !important;
                -webkit-filter: none !important;
                max-width: 20px;
                padding-top: 7px !important;
            }
            #adminmenu .toplevel_page_seo-fury:hover .wp-menu-image.svg img,
            #adminmenu .toplevel_page_seo-fury.current .wp-menu-image.svg img,
            #adminmenu .toplevel_page_seo-fury.wp-has-current-submenu .wp-menu-image.svg img {
                opacity: 1 !important;
                filter: none !important;
                -webkit-filter: none !important;
            }
        </style>';
    }

    private function should_hide_branding() {
        return function_exists('seo_fury_hide_branding') ? seo_fury_hide_branding() : false;
    }

    public function enqueue_admin_assets($hook)
    {
        if ($hook !== 'toplevel_page_seo-fury') {
            return;
        }

        wp_enqueue_script('jquery');

        wp_enqueue_style(
            'seo-fury-admin',
            SEO_FURY_URL . 'assets/admin-style.css',
            array(),
            SEO_FURY_VERSION
        );

        // Migration Wizard assets
        wp_enqueue_style(
            'seo-fury-migration-wizard',
            SEO_FURY_URL . 'assets/migration-wizard.css',
            array(),
            SEO_FURY_VERSION
        );

        wp_enqueue_script(
            'seo-fury-migration-wizard',
            SEO_FURY_URL . 'assets/migration-wizard.js',
            array('jquery'),
            SEO_FURY_VERSION,
            true
        );

        wp_localize_script('seo-fury-migration-wizard', 'seoFuryWizard', array(
            'nonce'       => wp_create_nonce('seo_fury_migration_wizard'),
            'settingsUrl' => admin_url('admin.php?page=seo-fury'),
            'i18n'        => array(
                'title'              => __('SEO Data Migration', 'seo-fury'),
                'step1'              => __('Select', 'seo-fury'),
                'step2'              => __('Import', 'seo-fury'),
                'step3'              => __('Done', 'seo-fury'),
                'detecting'          => __('Detecting installed SEO plugins...', 'seo-fury'),
                'selectPlugin'       => __('Select the SEO plugin you want to import data from:', 'seo-fury'),
                'noPlugins'          => __('No SEO plugin data detected in your database.', 'seo-fury'),
                'detectError'        => __('Error detecting plugins. Please try again.', 'seo-fury'),
                'posts'              => __('posts with SEO data', 'seo-fury'),
                'settingsOnly'       => __('Global settings only', 'seo-fury'),
                'alsoSettings'       => __('Also import global settings (title separator, etc.)', 'seo-fury'),
                'noOverwrite'        => __('Your existing SEO Fury data will not be overwritten.', 'seo-fury'),
                'startImport'        => __('Start Import', 'seo-fury'),
                'startingMigration'  => __('Starting migration from', 'seo-fury'),
                /* translators: %d: number of posts migrated */
                'batchDone'          => __('%d posts migrated', 'seo-fury'),
                /* translators: %d: number of posts skipped */
                'batchSkipped'       => __('%d posts skipped (already have data)', 'seo-fury'),
                'batchError'         => __('Error processing batch', 'seo-fury'),
                'networkError'       => __('Network error. Please try again.', 'seo-fury'),
                'migratingSettings'  => __('Migrating global settings...', 'seo-fury'),
                'settingsMigrated'   => __('Settings migrated', 'seo-fury'),
                'noSettingsToMigrate' => __('No new settings to migrate', 'seo-fury'),
                'settingsError'      => __('Could not migrate settings', 'seo-fury'),
                'migrationComplete'  => __('Migration Complete!', 'seo-fury'),
                'migrated'           => __('Migrated', 'seo-fury'),
                'skipped'            => __('Skipped', 'seo-fury'),
                'errors'             => __('Errors', 'seo-fury'),
                'goToSettings'       => __('Go to Settings', 'seo-fury'),
                'close'              => __('Close', 'seo-fury'),
                /* translators: %s: plugin name */
                'deactivateHint'     => __('Running two SEO plugins simultaneously can cause conflicts and duplicate meta tags. We recommend deactivating %s now.', 'seo-fury'),
                /* translators: %s: plugin name */
                'deactivatePlugin'   => __('Deactivate %s', 'seo-fury'),
                'deactivating'       => __('Deactivating...', 'seo-fury'),
            ),
        ));

        // Determine the current tab for conditional script loading
        $current_tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : 'general';

        if ($current_tab === 'support') {
            wp_enqueue_script(
                'seo-fury-tickets',
                SEO_FURY_URL . 'assets/js/tickets.js',
                array('jquery'),
                SEO_FURY_VERSION,
                true
            );
            wp_localize_script('seo-fury-tickets', 'seoFuryTickets', array(
                'nonce'   => wp_create_nonce('seo_fury_tickets_nonce'),
                'ajaxUrl' => admin_url('admin-ajax.php'),
                'i18n'    => array(
                    'subject'           => __('Subject', 'seo-fury'),
                    'status'            => __('Status', 'seo-fury'),
                    'created'           => __('Created', 'seo-fury'),
                    'lastUpdate'        => __('Last Update', 'seo-fury'),
                    'noTickets'         => __('No tickets yet', 'seo-fury'),
                    'noTicketsHint'     => __('Click "New Ticket" if you need help!', 'seo-fury'),
                    'loadingTickets'    => __('Loading tickets...', 'seo-fury'),
                    'loadingTicket'     => __('Loading ticket...', 'seo-fury'),
                    'failedLoad'        => __('Failed to load tickets', 'seo-fury'),
                    'failedLoadTicket'  => __('Failed to load ticket', 'seo-fury'),
                    'connectionError'   => __('Connection Error', 'seo-fury'),
                    'connectionErrorMsg'=> __('Could not connect to support server. Please try again later.', 'seo-fury'),
                    'connectionRetry'   => __('Connection error. Please try again.', 'seo-fury'),
                    'sessionExpired'    => __('Your session has expired. Please re-activate your license key in the License tab.', 'seo-fury'),
                    'goToLicense'       => __('Go to License', 'seo-fury'),
                    'createAccount'     => __('Create Account', 'seo-fury'),
                    'checkLicense'      => __('Please check your license and internet connection.', 'seo-fury'),
                    'fillFields'        => __('Please fill in both subject and message.', 'seo-fury'),
                    'ticketSubmitted'   => __("Ticket submitted! We'll reply within 24 hours.", 'seo-fury'),
                    'ticketSent'        => __("Ticket sent to our support team. We'll reply within 24 hours.", 'seo-fury'),
                    'errorCreating'     => __('Error creating ticket', 'seo-fury'),
                    'errorEscalating'   => __('Error escalating ticket.', 'seo-fury'),
                    'thisHelped'        => __('This helped!', 'seo-fury'),
                    'gladHelped'        => __('Great! Glad we could help.', 'seo-fury'),
                    'backToTickets'     => __('Back to Tickets', 'seo-fury'),
                    'noMessages'        => __('No messages yet.', 'seo-fury'),
                    'enterReply'        => __('Please enter a reply.', 'seo-fury'),
                    'typeReply'         => __('Type your reply...', 'seo-fury'),
                    'sendReply'         => __('Send Reply', 'seo-fury'),
                    'sending'           => __('Sending...', 'seo-fury'),
                    'replySent'         => __('Reply sent!', 'seo-fury'),
                    'errorReply'        => __('Error sending reply', 'seo-fury'),
                    'closeTicket'       => __('Close Ticket', 'seo-fury'),
                    'closeConfirm'      => __('Close this ticket?', 'seo-fury'),
                    'ticketClosed'      => __('Ticket closed.', 'seo-fury'),
                    'ticketIsClosed'    => __('This ticket is closed.', 'seo-fury'),
                    'errorClosing'      => __('Error closing ticket', 'seo-fury'),
                    'statusOpen'        => __('Open', 'seo-fury'),
                    'statusAwaiting'    => __('Awaiting Reply', 'seo-fury'),
                    'statusResolved'    => __('Resolved', 'seo-fury'),
                    'statusClosed'      => __('Closed', 'seo-fury'),
                ),
            ));
        }

        if ($current_tab === 'redirects') {
            wp_enqueue_script(
                'seo-fury-redirects',
                SEO_FURY_URL . 'assets/redirects.js',
                array('jquery'),
                SEO_FURY_VERSION,
                true
            );

            wp_localize_script('seo-fury-redirects', 'seoRedirects', array(
                'ajax_url' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('seo_redirects_nonce'),
                'i18n' => array(
                    'loading' => __('Loading...', 'seo-fury'),
                    'noRedirectsFound' => __('No redirects found', 'seo-fury'),
                    'active' => __('Active', 'seo-fury'),
                    'inactive' => __('Inactive', 'seo-fury'),
                    'activate' => __('Activate', 'seo-fury'),
                    'deactivate' => __('Deactivate', 'seo-fury'),
                    'edit' => __('Edit', 'seo-fury'),
                    'delete' => __('Delete', 'seo-fury'),
                    'adding' => __('Adding...', 'seo-fury'),
                    'deleting' => __('Deleting...', 'seo-fury'),
                    'saving' => __('Saving...', 'seo-fury'),
                    'updating' => __('Updating...', 'seo-fury'),
                    'fillAllFields' => __('Please fill all fields', 'seo-fury'),
                    'redirectAdded' => __('Redirect added successfully!', 'seo-fury'),
                    'redirectDeleted' => __('Redirect deleted!', 'seo-fury'),
                    'redirectUpdated' => __('Redirect updated!', 'seo-fury'),
                    'confirmDelete' => __('Are you sure you want to delete this redirect?', 'seo-fury'),
                    'errorLoading' => __('Error loading redirects', 'seo-fury'),
                    'errorLoadingData' => __('Error loading data', 'seo-fury'),
                    'errorAdding' => __('Error adding redirect', 'seo-fury'),
                    'errorDeleting' => __('Error deleting redirect', 'seo-fury'),
                    'errorUpdating' => __('Error updating redirect', 'seo-fury'),
                    'errorUpdatingStatus' => __('Error updating status', 'seo-fury'),
                    'selectCsvFile' => __('Please select a CSV file.', 'seo-fury'),
                    'csvImportCompleted' => __('CSV import completed.', 'seo-fury'),
                    'imported' => __('Imported', 'seo-fury'),
                    'updated' => __('Updated', 'seo-fury'),
                    'skipped' => __('Skipped', 'seo-fury'),
                    'uploadFailed' => __('Upload failed.', 'seo-fury'),
                    'error' => __('Error', 'seo-fury'),
                    'anErrorOccurred' => __('An error occurred', 'seo-fury'),
                    'errorPrefix' => __('Error:', 'seo-fury'),
                    'testing' => __('Testing...', 'seo-fury'),
                    'testEnterUrl' => __('Enter a URL or path to test.', 'seo-fury'),
                    'testExactMatch' => __('Exact match', 'seo-fury'),
                    'testRegexMatch' => __('Regex match', 'seo-fury'),
                    'testNoMatch' => __('No redirect rule matches this URL — it would load normally.', 'seo-fury'),
                    'testWouldRedirect' => __('Would redirect to', 'seo-fury'),
                    'testStatus' => __('Status', 'seo-fury'),
                    'testRule' => __('Matched rule', 'seo-fury'),
                ),
            ));
        }

        if ($current_tab === 'indexing') {
            wp_enqueue_script(
                'seo-fury-indexnow',
                SEO_FURY_URL . 'assets/indexnow.js',
                array('jquery'),
                SEO_FURY_VERSION,
                true
            );

            wp_localize_script('seo-fury-indexnow', 'seoIndexNow', array(
                'ajax_url' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('seo_indexnow_nonce'),
                'i18n' => array(
                    'enterUrl' => __('Please enter at least one URL', 'seo-fury'),
                    'noValidUrls' => __('No valid URLs found', 'seo-fury'),
                    'maxUrls' => __('Maximum 10,000 URLs per request. You have:', 'seo-fury'),
                    'sending' => __('Sending...', 'seo-fury'),
                    'sendingBatches' => __('Sending in batches...', 'seo-fury'),
                    'saving' => __('Saving...', 'seo-fury'),
                    'generating' => __('Generating...', 'seo-fury'),
                    'checking' => __('Checking...', 'seo-fury'),
                    'success' => __('Success!', 'seo-fury'),
                    'urlsSent' => __('URLs sent:', 'seo-fury'),
                    'error' => __('Error!', 'seo-fury'),
                    'unknownError' => __('Unknown error', 'seo-fury'),
                    'serverError' => __('Server connection error', 'seo-fury'),
                    'settingsSaved' => __('Settings saved', 'seo-fury'),
                    'saveError' => __('Save error', 'seo-fury'),
                    'keyGenerated' => __('Key generated!', 'seo-fury'),
                    'verifyKey' => __('Verify key', 'seo-fury'),
                    'noHistoryYet' => __('No history yet', 'seo-fury'),
                    'confirmClearHistory' => __('Are you sure you want to clear the entire history?', 'seo-fury'),
                    'historyCleared' => __('History cleared', 'seo-fury'),
                    'clearFailed' => __('Clear failed', 'seo-fury'),
                    'sendingBatch' => __('Sending batch', 'seo-fury'),
                    'of' => __('of', 'seo-fury'),
                    'allBatchesSent' => __('All batches sent successfully!', 'seo-fury'),
                    'totalUrls' => __('Total URLs:', 'seo-fury'),
                    'batches' => __('Batches:', 'seo-fury'),
                    'completedWithErrors' => __('Completed with errors', 'seo-fury'),
                    'errors' => __('Errors:', 'seo-fury'),
                    'auto' => __('AUTO', 'seo-fury'),
                    'manual' => __('MANUAL', 'seo-fury'),
                    'notAvailable' => __('N/A', 'seo-fury'),
                ),
            ));
        }

        if ($current_tab === 'log404') {
            wp_enqueue_script(
                'seo-fury-404',
                SEO_FURY_URL . 'assets/404-monitor.js',
                array('jquery'),
                SEO_FURY_VERSION,
                true
            );
        }

        if ($current_tab === 'log404') {
            wp_localize_script('seo-fury-404', 'seo404Monitor', array(
                'ajax_url' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('seo_404_nonce'),
                'i18n' => array(
                    'loading' => __('Loading...', 'seo-fury'),
                    'loadError' => __('Load error', 'seo-fury'),
                    'serverError' => __('Server connection error', 'seo-fury'),
                    'no404Found' => __('No 404 errors found', 'seo-fury'),
                    'resolved' => __('Resolved', 'seo-fury'),
                    'active' => __('Active', 'seo-fury'),
                    'find' => __('Find', 'seo-fury'),
                    'redirect' => __('Redirect', 'seo-fury'),
                    'resolve' => __('Resolve', 'seo-fury'),
                    'delete' => __('Delete', 'seo-fury'),
                    'confirmClearAll' => __('Are you sure? All 404 logs will be deleted!', 'seo-fury'),
                    'logsCleared' => __('Logs cleared', 'seo-fury'),
                    'searchingSimilar' => __('Searching for similar pages...', 'seo-fury'),
                    /* translators: %d: number of similar pages found */
                    'foundSimilar' => __('Found %d similar pages:', 'seo-fury'),
                    'useThisUrl' => __('Use this URL', 'seo-fury'),
                    'noSimilarFound' => __('No similar pages found', 'seo-fury'),
                    'provideTargetUrl' => __('Please provide a target URL', 'seo-fury'),
                    'creating' => __('Creating...', 'seo-fury'),
                    'redirectCreated' => __('Redirect created successfully!', 'seo-fury'),
                    'errorCreatingRedirect' => __('Error creating redirect', 'seo-fury'),
                    'confirmDeleteEntry' => __('Delete this entry?', 'seo-fury'),
                ),
            ));
        }

        // Enqueue meta titles preview JS when on the meta_titles tab
        if ($current_tab === 'meta_titles') {
            wp_enqueue_script(
                'seo-fury-meta-preview',
                SEO_FURY_URL . 'assets/meta-titles-preview.js',
                array('jquery'),
                SEO_FURY_VERSION,
                true
            );

            wp_localize_script('seo-fury-meta-preview', 'seoFuryPreview', array(
                'siteName'             => get_bloginfo('name'),
                'siteDesc'             => get_bloginfo('description'),
                'separator'            => get_option('seo_fury_title_separator', '-'),
                'siteUrl'              => home_url('/'),
                'exampleTitle'         => __('Example Post Title', 'seo-fury'),
                'exampleExcerpt'       => __('This is an example meta description that shows how your page will appear in search results. It should be compelling and informative.', 'seo-fury'),
                'currentDate'          => date_i18n(get_option('date_format')),
                'authorName'           => wp_get_current_user()->display_name,
                'exampleCategory'      => __('Category', 'seo-fury'),
                'exampleTag'           => __('Tag', 'seo-fury'),
                'exampleTerm'          => __('Term', 'seo-fury'),
                'exampleTermDesc'      => __('Term description text', 'seo-fury'),
                'exampleSearch'        => __('example search', 'seo-fury'),
                'ajax_url'             => admin_url('admin-ajax.php'),
                'nonce'                => wp_create_nonce('seo_fury_meta_titles_nonce'),
                'schemaTemplatesNonce' => wp_create_nonce('seo_fury_schema_templates_nonce'),
                'i18n'                 => array(
                    /* translators: %s: post type name */
                    'confirmDeleteSchema'  => __('Are you sure you want to delete Schema from ALL "%s" posts? This cannot be undone.', 'seo-fury'),
                    /* translators: %s: schema template name */
                    'confirmApplyTemplate' => __('Apply Schema template "%s" to ALL posts of this type? Existing per-post Schema will be overwritten.', 'seo-fury'),
                    'selectTemplate'       => __('Please select a saved Schema template first.', 'seo-fury'),
                    'deleting'             => __('Deleting…', 'seo-fury'),
                    'applying'             => __('Applying…', 'seo-fury'),
                    'error'                => __('An error occurred. Please try again.', 'seo-fury'),
                    'deleteSchemaBtn'      => __('Delete Schema from all posts', 'seo-fury'),
                    'applyTemplateBtn'     => __('Apply to all posts', 'seo-fury'),
                    'noTemplates'          => __('No saved Schema templates found.', 'seo-fury'),
                ),
            ));
        }

        if ($current_tab === 'general') {
            wp_enqueue_script('seo-fury-import-export', SEO_FURY_URL . 'assets/import-export.js', array('jquery'), SEO_FURY_VERSION, true);
            wp_localize_script('seo-fury-import-export', 'seoFuryIE', array(
                'ajax_url' => admin_url('admin-ajax.php'),
                'nonce'    => wp_create_nonce('seo_fury_import_export_nonce'),
                'i18n'     => array(
                    'exporting'    => __('Exporting...', 'seo-fury'),
                    'importing'    => __('Importing...', 'seo-fury'),
                    'exportSuccess' => __('Settings exported successfully!', 'seo-fury'),
                    'confirmImport' => __('This will overwrite your current settings. Continue?', 'seo-fury'),
                    'networkError'  => __('Network error', 'seo-fury'),
                    'invalidFile'   => __('Please select a JSON file', 'seo-fury'),
                    'exportBtn'     => __('Export Settings', 'seo-fury'),
                    'importBtn'     => __('Import Settings', 'seo-fury'),
                ),
            ));
        }

        if ($current_tab === 'page_speed') {
            wp_enqueue_style('seo-fury-page-speed', SEO_FURY_URL . 'assets/page-speed.css', array(), SEO_FURY_VERSION);
            wp_enqueue_script('seo-fury-page-speed', SEO_FURY_URL . 'assets/page-speed.js', array('jquery'), SEO_FURY_VERSION, true);
            wp_localize_script('seo-fury-page-speed', 'seoFuryPageSpeed', array(
                'ajax_url' => admin_url('admin-ajax.php'),
                'nonce'    => wp_create_nonce('seo_fury_page_speed_nonce'),
                'i18n'     => array(
                    'checking'        => __('...', 'seo-fury'),
                    'checkBtn'        => __('Check', 'seo-fury'),
                    'good'            => __('Good', 'seo-fury'),
                    'needsImprovement' => __('Needs Improvement', 'seo-fury'),
                    'poor'            => __('Poor', 'seo-fury'),
                    'cached'          => __('cached', 'seo-fury'),
                    'savings'         => __('save', 'seo-fury'),
                    'opportunities'   => __('Opportunities', 'seo-fury'),
                    'networkError'    => __('Network error', 'seo-fury'),
                    'lastCheck'       => __('Last check', 'seo-fury'),
                ),
            ));
        }

        if ($current_tab === 'htaccess') {
            // Enqueue WordPress CodeMirror
            $cm_settings = array(
                'type' => 'text/x-httpd-conf',
            );

            if (function_exists('wp_enqueue_code_editor')) {
                $editor_settings = wp_enqueue_code_editor($cm_settings);
                if ($editor_settings !== false) {
                    wp_add_inline_script('code-editor', sprintf(
                        'jQuery(function() { wp.codeEditor.defaultSettings = %s; });',
                        wp_json_encode($editor_settings)
                    ));
                }
            }

            wp_enqueue_script(
                'seo-fury-htaccess',
                SEO_FURY_URL . 'assets/htaccess.js',
                array('jquery', 'wp-theme-plugin-editor'),
                SEO_FURY_VERSION,
                true
            );

            // Pass presets code to JS
            $presets_code = array();
            foreach (SEO_Fury_Htaccess::get_presets() as $key => $preset) {
                $presets_code[$key] = $preset['code'];
            }

            wp_localize_script('seo-fury-htaccess', 'seoFuryHtaccess', array(
                'ajax_url' => admin_url('admin-ajax.php'),
                'nonce'    => wp_create_nonce('seo_fury_htaccess_nonce'),
                'presets'  => $presets_code,
                'i18n'     => array(
                    'saving'         => __('Saving...', 'seo-fury'),
                    'restoring'      => __('Restoring...', 'seo-fury'),
                    'saveFailed'     => __('Save failed', 'seo-fury'),
                    'connectionError'=> __('Connection error', 'seo-fury'),
                    'confirmRestore' => __('Are you sure you want to restore the backup? Current content will be overwritten.', 'seo-fury'),
                    'restoreBackup'  => __('Restore Backup', 'seo-fury'),
                ),
            ));
        }

        // Google Indexing JS is only available in PRO addon
        // (PRO enqueues it via seo_fury_enqueue_admin_assets action)

        // Allow PRO addon to enqueue its own assets
        do_action('seo_fury_enqueue_admin_assets', $current_tab, $hook);
    }


    public function register_settings()
    {
        if ($this->core) {
            $this->core->get_robots()->register_settings();
            $this->core->get_sitemap()->register_settings();
            $this->core->get_indexnow()->register_settings();
            $this->core->get_general()->register_settings();
            $this->core->get_meta_titles()->register_settings();
            if ($this->core->get_breadcrumbs()) {
                $this->core->get_breadcrumbs()->register_settings();
            }
            if ($this->core->get_local_seo()) {
                $this->core->get_local_seo()->register_settings();
            }

            if ($this->core->get_404_monitor()) {
                $this->core->get_404_monitor()->register_settings();
            }

            if ($this->core->get_image_seo_basic()) {
                $this->core->get_image_seo_basic()->register_settings();
            }

            if ($this->core->get_woocommerce() && method_exists($this->core->get_woocommerce(), 'register_settings')) {
                $this->core->get_woocommerce()->register_settings();
            }

            if ($this->core->get_google_indexing() && method_exists($this->core->get_google_indexing(), 'register_settings')) {
                $this->core->get_google_indexing()->register_settings();
            }

            if ($this->core->get_llms_txt() && method_exists($this->core->get_llms_txt(), 'register_settings')) {
                $this->core->get_llms_txt()->register_settings();
            }

            if ($this->core->get_yasr_integration() && method_exists($this->core->get_yasr_integration(), 'register_settings')) {
                $this->core->get_yasr_integration()->register_settings();
            }
        }

        // Allow PRO addon to register its own settings
        do_action('seo_fury_register_settings');
    }

    /**
     * Dashboard landing screen: KPI hero + site-health + Search Console.
     */
    public function render_dashboard_tab()
    {
        global $wpdb;

        // Avg SEO score across scored posts
        $score_row = $wpdb->get_row( "SELECT AVG(meta_value+0) AS avg, COUNT(*) AS cnt FROM {$wpdb->postmeta} WHERE meta_key = '_seo_fury_seo_score'" );
        $avg_score = ( $score_row && (int) $score_row->cnt > 0 ) ? (int) round( $score_row->avg ) : null;

        // Redirects + 404 counts (tables created on activation)
        $redirects_tbl = $wpdb->prefix . 'seo_redirects';
        $log404_tbl    = $wpdb->prefix . 'seo_404_log';
        $redirects = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$redirects_tbl} WHERE active = 1" );
        $errors404 = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$log404_tbl} WHERE resolved = 0" );

        // Images missing alt
        $alt_q = new WP_Query( array(
            'post_type' => 'attachment', 'post_status' => 'inherit', 'post_mime_type' => 'image',
            'posts_per_page' => 1, 'fields' => 'ids', 'no_found_rows' => false,
            'update_post_meta_cache' => false, 'update_post_term_cache' => false,
            'meta_query' => array( 'relation' => 'OR',
                array( 'key' => '_wp_attachment_image_alt', 'compare' => 'NOT EXISTS' ),
                array( 'key' => '_wp_attachment_image_alt', 'value' => '', 'compare' => '=' ),
            ),
        ) );
        $missing_alt = (int) $alt_q->found_posts;

        // GSC connection
        $gsc = ( $this->core && method_exists( $this->core, 'get_google_search_console' ) ) ? $this->core->get_google_search_console() : null;
        $gsc_connected = ( $gsc && method_exists( $gsc, 'is_connected' ) ) ? $gsc->is_connected() : false;

        // Health checks
        $conflicts = method_exists( $this, 'get_conflicting_seo_plugins' ) ? $this->get_conflicting_seo_plugins() : array();
        $health = array(
            array( 'ok' => (bool) get_option( 'seo_fury_sitemap_enabled', 0 ), 'label' => __( 'XML sitemap enabled', 'seo-fury' ), 'tab' => 'sitemap' ),
            array( 'ok' => (bool) get_option( 'seo_fury_robots_enabled', 1 ), 'label' => __( 'robots.txt managed', 'seo-fury' ), 'tab' => 'robots' ),
            array( 'ok' => is_ssl(), 'label' => __( 'Site served over HTTPS', 'seo-fury' ), 'tab' => 'security' ),
            array( 'ok' => $gsc_connected, 'label' => __( 'Search Console connected', 'seo-fury' ), 'tab' => 'webmasters' ),
            array( 'ok' => empty( $conflicts ), 'label' => empty( $conflicts ) ? __( 'No conflicting SEO plugin', 'seo-fury' ) : sprintf( __( 'Conflicting plugin: %s', 'seo-fury' ), implode( ', ', $conflicts ) ), 'tab' => '' ),
        );

        $score_color = $avg_score === null ? 'var(--sf-gray-400)' : ( $avg_score >= 80 ? 'var(--sf-success)' : ( $avg_score >= 50 ? 'var(--sf-warning)' : 'var(--sf-danger)' ) );
        $score_pct   = $avg_score === null ? 0 : $avg_score;
        $base_url     = admin_url( 'admin.php?page=seo-fury&tab=' );
        ?>
        <div class="sf-dash-grid">
            <div class="seo-card sf-dash-kpi sf-dash-featured">
                <div class="sf-dash-gauge" style="--p:<?php echo (int) $score_pct; ?>; --gc:<?php echo esc_attr( $score_color ); ?>;">
                    <span><?php echo $avg_score === null ? '&mdash;' : (int) $avg_score; ?></span>
                </div>
                <div class="sf-dash-kpi-label"><?php esc_html_e( 'Average SEO score', 'seo-fury' ); ?></div>
                <div class="sf-dash-kpi-sub">
                    <?php
                    if ( $avg_score === null ) {
                        esc_html_e( 'Open posts in the editor to calculate scores.', 'seo-fury' );
                    } else {
                        printf( esc_html__( 'across %d scored items', 'seo-fury' ), (int) $score_row->cnt );
                    }
                    ?>
                </div>
            </div>

            <a class="seo-card sf-dash-kpi" href="<?php echo esc_url( $base_url . 'redirects' ); ?>">
                <div class="sf-dash-kpi-val"><?php echo esc_html( number_format_i18n( $redirects ) ); ?></div>
                <div class="sf-dash-kpi-label"><?php esc_html_e( 'Active redirects', 'seo-fury' ); ?></div>
            </a>

            <a class="seo-card sf-dash-kpi" href="<?php echo esc_url( $base_url . 'log404' ); ?>">
                <div class="sf-dash-kpi-val" style="color:<?php echo $errors404 > 0 ? 'var(--sf-danger)' : 'inherit'; ?>"><?php echo esc_html( number_format_i18n( $errors404 ) ); ?></div>
                <div class="sf-dash-kpi-label"><?php esc_html_e( 'Unresolved 404s', 'seo-fury' ); ?></div>
            </a>

            <a class="seo-card sf-dash-kpi" href="<?php echo esc_url( $base_url . 'seo_images' ); ?>">
                <div class="sf-dash-kpi-val" style="color:<?php echo $missing_alt > 0 ? 'var(--sf-warning)' : 'inherit'; ?>"><?php echo esc_html( number_format_i18n( $missing_alt ) ); ?></div>
                <div class="sf-dash-kpi-label"><?php esc_html_e( 'Images without alt', 'seo-fury' ); ?></div>
            </a>
        </div>

        <div class="sf-dash-cards">
            <div class="seo-card">
                <h3 class="sf-dash-card-title"><?php esc_html_e( 'Search performance (28 days)', 'seo-fury' ); ?></h3>
                <div class="sf-dash-card-body" id="sf-dash-gsc">
                    <?php if ( $gsc_connected ) : ?>
                        <div id="sf-dash-gsc-body" data-nonce="<?php echo esc_attr( wp_create_nonce( 'seo_fury_gsc_nonce' ) ); ?>"><p class="description"><?php esc_html_e( 'Loading…', 'seo-fury' ); ?></p></div>
                        <script>
                        (function($){
                            var $b=$('#sf-dash-gsc-body'); if(!$b.length)return;
                            $.post(ajaxurl,{action:'seo_fury_gsc_comparison',nonce:$b.data('nonce'),range:'28d'},function(r){
                                if(!r||!r.success){$b.html('<p class="description"><?php echo esc_js( __( 'Could not load Search Console data.', 'seo-fury' ) ); ?></p>');return;}
                                var c=r.data.current,p=r.data.previous;
                                function d(cur,prev,inv){cur=+cur||0;prev=+prev||0;if(!prev)return '';var pc=Math.round((cur-prev)/prev*100);var up=inv?(cur<prev):(cur>prev);return ' <span style="color:'+(up?'var(--sf-success)':(cur===prev?'var(--sf-gray-400)':'var(--sf-danger)'))+';font-weight:600;font-size:12px;">'+(cur>prev?'▲':(cur<prev?'▼':'→'))+' '+Math.abs(pc)+'%</span>';}
                                $b.html('<div class="sf-dash-mini">'+
                                    '<div><span class="v">'+(+c.clicks).toLocaleString()+d(c.clicks,p.clicks)+'</span><span class="l"><?php echo esc_js( __( 'Clicks', 'seo-fury' ) ); ?></span></div>'+
                                    '<div><span class="v">'+(+c.impressions).toLocaleString()+d(c.impressions,p.impressions)+'</span><span class="l"><?php echo esc_js( __( 'Impressions', 'seo-fury' ) ); ?></span></div>'+
                                    '<div><span class="v">'+(c.ctr*100).toFixed(1)+'%</span><span class="l"><?php echo esc_js( __( 'CTR', 'seo-fury' ) ); ?></span></div>'+
                                    '<div><span class="v">'+c.position.toFixed(1)+d(c.position,p.position,true)+'</span><span class="l"><?php echo esc_js( __( 'Position', 'seo-fury' ) ); ?></span></div>'+
                                    '</div>');
                            });
                        })(jQuery);
                        </script>
                    <?php else : ?>
                        <p class="description"><?php esc_html_e( 'Connect Google Search Console to see clicks, impressions and positions here.', 'seo-fury' ); ?></p>
                        <a class="button button-primary" href="<?php echo esc_url( $base_url . 'webmasters' ); ?>"><?php esc_html_e( 'Connect Search Console', 'seo-fury' ); ?></a>
                    <?php endif; ?>
                </div>
            </div>

            <div class="seo-card">
                <h3 class="sf-dash-card-title"><?php esc_html_e( 'Site health', 'seo-fury' ); ?></h3>
                <div class="sf-dash-card-body">
                    <?php foreach ( $health as $h ) : ?>
                        <div class="sf-dash-check">
                            <span class="sf-dash-dot <?php echo $h['ok'] ? 'g' : 'w'; ?>"></span>
                            <span><?php echo esc_html( $h['label'] ); ?></span>
                            <?php if ( ! $h['ok'] && ! empty( $h['tab'] ) ) : ?>
                                <a class="sf-dash-fix" href="<?php echo esc_url( $base_url . $h['tab'] ); ?>"><?php esc_html_e( 'Fix', 'seo-fury' ); ?></a>
                            <?php endif; ?>
                        </div>
                    <?php endforeach; ?>
                </div>
            </div>
        </div>
        <?php
    }

    public function settings_page()
    {
        ob_start();
        // --- Group: Overview ---
        $tabs = array(
            'dashboard' => array(
                'title' => __('Dashboard', 'seo-fury'),
                'icon' => 'dashicons-dashboard',
                'group' => __('Overview', 'seo-fury'),
                'description' => __('An at-a-glance overview of your site\'s SEO health and search performance.', 'seo-fury'),
            ),
            'general' => array(
                'title' => __('General Settings', 'seo-fury'),
                'icon' => 'dashicons-admin-settings',
                'group' => __('General', 'seo-fury'),
                'description' => __('Core plugin settings: title separator, URL transliteration, plugin language, and global SEO defaults for your site.', 'seo-fury'),
            ),
            'meta_titles' => array(
                'title' => __('Meta Titles', 'seo-fury'),
                'icon' => 'dashicons-editor-textcolor',
                'description' => __('Configure default title and description templates for all page types. Use dynamic variables to automate SEO metadata across your site.', 'seo-fury'),
            ),
            'local_seo' => array(
                'title' => __('Local SEO', 'seo-fury'),
                'icon' => 'dashicons-location-alt',
                'description' => __('Add Organization or LocalBusiness structured data to help your site appear in local search results and Google Maps.', 'seo-fury'),
            ),
            'breadcrumbs' => array(
                'title' => __('Breadcrumbs', 'seo-fury'),
                'icon' => 'dashicons-editor-ol',
                'description' => __('SEO-friendly breadcrumb navigation with JSON-LD markup. Helps search engines understand your site structure and improves user navigation.', 'seo-fury'),
            ),
        );

        // --- Group: Content & Links ---
        $tabs['seo_images'] = array(
            'group' => __('Content & Links', 'seo-fury'),
            'title' => __('SEO Images', 'seo-fury'),
            'icon' => 'dashicons-format-image',
            'description' => __('Bulk optimize image alt text, titles, and filenames for SEO. Generate descriptive alt tags automatically based on post context.', 'seo-fury'),
        );
        $tabs['schema_templates'] = array(
            'title' => __('Schema Templates', 'seo-fury'),
            'icon' => 'dashicons-database-view',
            'description' => __('Create and manage reusable schema markup templates. Apply them to posts in bulk or per-post via the schema editor.', 'seo-fury'),
        );

        if (class_exists('WooCommerce')) {
            $tabs['woocommerce'] = array(
                'title' => __('WooCommerce SEO', 'seo-fury'),
                'icon' => 'dashicons-cart',
                'group' => __('WooCommerce', 'seo-fury'),
                'description' => __('SEO templates and Product schema markup for your WooCommerce store. Optimize product pages, categories, and tags for better visibility in search.', 'seo-fury'),
            );
        }

        // --- Group: Technical SEO ---
        $tabs['robots'] = array(
            'title' => __('Robots.txt', 'seo-fury'),
            'icon' => 'dashicons-admin-generic',
            'group' => __('Technical SEO', 'seo-fury'),
            'description' => __('Virtual robots.txt editor with dynamic variables and per-bot presets. Control what search engine crawlers can access on your site.', 'seo-fury'),
        );
        $tabs['sitemap'] = array(
            'title' => __('Sitemap', 'seo-fury'),
            'icon' => 'dashicons-networking',
            'description' => __('XML and HTML sitemaps with image support, news and video sitemaps. Automatically notify search engines when content is updated.', 'seo-fury'),
        );
        $tabs['htaccess'] = array(
            'title' => __('.htaccess', 'seo-fury'),
            'icon' => 'dashicons-media-code',
            'description' => __('Visual .htaccess editor with syntax highlighting. Automatic backup before changes and one-click restore for safe server-level configuration.', 'seo-fury'),
        );
        $tabs['ssl'] = array(
            'title' => __('SSL & Security', 'seo-fury'),
            'icon' => 'dashicons-shield',
            'description' => __('Force HTTPS, fix mixed content, enable HSTS and security headers. Protect your site and boost rankings with proper SSL configuration.', 'seo-fury'),
        );
        $tabs['llms_txt'] = array(
            'title' => __('LLMs.txt', 'seo-fury'),
            'icon' => 'dashicons-buddicons-replies',
            'description' => __('Serve /llms.txt and /llms-full.txt files to control how AI language models discover and access your content — like robots.txt for AI.', 'seo-fury'),
        );
        $tabs['redirects'] = array(
            'title' => __('Redirects', 'seo-fury'),
            'icon' => 'dashicons-randomize',
            'description' => __('Create and manage 301, 302, and 307 redirects with hit tracking. Import and export via CSV for bulk redirect management.', 'seo-fury'),
        );
        $tabs['log404'] = array(
            'title' => __('404 & Link Health', 'seo-fury'),
            'icon' => 'dashicons-warning',
            'description' => __('Track 404 errors with referrer and IP logging, and scan your site for broken links. Find broken URLs and convert them to redirects with one click.', 'seo-fury'),
        );

        // --- Group: Indexing & Analytics ---
        $tabs['indexing'] = array(
            'title' => __('Indexing', 'seo-fury'),
            'icon' => 'dashicons-cloud-upload',
            'group' => __('Indexing & Analytics', 'seo-fury'),
            'description' => __('Submit URLs to Google via Indexing API and to other search engines via IndexNow. Get your content indexed faster after publishing or updating.', 'seo-fury'),
        );
        $tabs['webmasters'] = array(
            'title' => __('Webmasters', 'seo-fury'),
            'icon' => 'dashicons-yes-alt',
            'description' => __('Verify site ownership with search engines and connect Google Search Console to view search performance data.', 'seo-fury'),
        );
        $tabs['hreflang'] = array(
            'title' => __('Hreflang', 'seo-fury'),
            'icon' => 'dashicons-translation',
            'description' => __('Manage hreflang tags for multilingual sites. Auto-detect translations from WPML, Polylang, TranslatePress or manually set alternate language URLs.', 'seo-fury'),
        );
        $tabs['page_speed'] = array(
            'title' => __('Page Speed', 'seo-fury'),
            'icon' => 'dashicons-performance',
            'description' => __('Analyze pages with Google PageSpeed Insights API. View Core Web Vitals scores, performance metrics, and optimization recommendations.', 'seo-fury'),
        );

        // --- Group: System ---
        $tabs['support'] = array(
            'title' => __('Support', 'seo-fury'),
            'icon' => 'dashicons-sos',
            'group' => __('System', 'seo-fury'),
            'description' => __('Get help and create support tickets. Browse FAQ articles or contact our team directly.', 'seo-fury'),
        );

        // Allow PRO addon to register additional tabs
        $tabs = apply_filters('seo_fury_admin_tabs', $tabs);

        $current_tab = (isset($_GET['tab']) && isset($tabs[$_GET['tab']])) ? sanitize_text_field($_GET['tab']) : 'dashboard';

?>
        <div class="wrap seo-plugin-wrap" id="seo-fury-app" data-theme="auto">
            <script>
            /* Apply the saved theme as early as possible to avoid a flash. */
            (function(){
                try{
                    var t = localStorage.getItem('seoFuryTheme') || 'auto';
                    var el = document.getElementById('seo-fury-app');
                    if(el){ el.setAttribute('data-theme', t); }
                }catch(e){}
            })();
            </script>
            <?php $brand = function_exists('seo_fury_get_brand_name') ? seo_fury_get_brand_name() : 'SEO Fury'; ?>
            <?php $hide_branding = $this->should_hide_branding(); ?>
            <h1 class="seo-plugin-title">
                <?php if (!$hide_branding): ?>
                    <a href="https://seo-fury.com" target="_blank" style="text-decoration:none;display:inline-flex;align-items:center;">
                        <img src="<?php echo esc_url(SEO_FURY_URL . 'assets/logo.png'); ?>" alt="<?php echo esc_attr($brand); ?>" height="28" style="display:block;">
                    </a>
                <?php else: ?>
                    <?php echo esc_html($brand); ?>
                <?php endif; ?>
            </h1>

            <?php settings_errors(); ?>

            <div class="seo-plugin-container">
                <!-- Left sidebar menu -->
                <div class="seo-sidebar">
                    <nav class="seo-sidebar-nav">
                        <?php foreach ($tabs as $tab_key => $tab_data): ?>
                            <?php if (!empty($tab_data['group'])): ?>
                                <div class="seo-sidebar-group"><?php echo esc_html($tab_data['group']); ?></div>
                            <?php endif; ?>
                            <a href="?page=seo-fury&tab=<?php echo esc_attr($tab_key); ?>"
                                class="seo-sidebar-item <?php echo esc_attr( ($current_tab === $tab_key) ? 'active' : '' ); ?>">
                                <span class="dashicons <?php echo esc_attr($tab_data['icon']); ?>"></span>
                                <span class="seo-sidebar-item-text"><?php echo esc_html($tab_data['title']); ?></span>
                            </a>
                        <?php endforeach; ?>
                    </nav>

                    <?php if (!$hide_branding): ?>
                        <div class="seo-sidebar-footer">
                            <p><strong><?php echo esc_html($brand); ?></strong></p>
                            <p>
                                <?php
                                /* translators: %s: plugin version number */
                                printf(esc_html__('Free: %s', 'seo-fury'), esc_html(SEO_FURY_VERSION));
                                ?>
                                <?php if (defined('SEO_FURY_PRO_VERSION')) : ?>
                                    <br>
                                    <?php
                                    /* translators: %s: PRO plugin version number */
                                    printf(esc_html__('PRO: %s', 'seo-fury'), esc_html(SEO_FURY_PRO_VERSION));
                                    ?>
                                <?php endif; ?>
                            </p>
                        </div>
                    <?php endif; ?>
                </div>

                <!-- Right content -->
                <div class="seo-content">
                    <div class="seo-topbar">
                        <div class="seo-topbar-search">
                            <span class="dashicons dashicons-search"></span>
                            <span><?php esc_html_e('Search settings…', 'seo-fury'); ?></span>
                        </div>
                        <div class="seo-topbar-actions">
                            <button type="button" class="seo-theme-toggle" id="seo-fury-theme-toggle" title="<?php esc_attr_e('Toggle light / dark theme', 'seo-fury'); ?>" aria-label="<?php esc_attr_e('Toggle light / dark theme', 'seo-fury'); ?>">◐</button>
                        </div>
                    </div>
                    <script>
                    (function(){
                        var btn = document.getElementById('seo-fury-theme-toggle');
                        var app = document.getElementById('seo-fury-app');
                        if(!btn || !app){ return; }
                        function effective(){
                            var t = app.getAttribute('data-theme') || 'auto';
                            if(t === 'auto'){
                                return (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';
                            }
                            return t;
                        }
                        btn.addEventListener('click', function(){
                            // Always flip the *currently visible* theme, so every
                            // click produces a visible change (no dead first click
                            // when "auto" already resolves to the OS theme).
                            var next = effective() === 'dark' ? 'light' : 'dark';
                            app.setAttribute('data-theme', next);
                            try{ localStorage.setItem('seoFuryTheme', next); }catch(e){}
                        });
                    })();
                    </script>
                    <div class="seo-content-header">
                        <h2>
                            <span class="dashicons <?php echo esc_attr($tabs[$current_tab]['icon']); ?>"></span>
                            <?php echo esc_html($tabs[$current_tab]['title']); ?>
                        </h2>
                        <?php if (!empty($tabs[$current_tab]['description'])): ?>
                            <p class="seo-content-description"><?php echo esc_html($tabs[$current_tab]['description']); ?></p>
                        <?php endif; ?>
                    </div>

                    <div class="seo-content-body">
                        <?php
                        switch ($current_tab) {
                            case 'dashboard':
                                $this->render_dashboard_tab();
                                break;
                            case 'general':
                                $this->render_general_tab();
                                break;
                            case 'robots':
                                $this->render_robots_tab();
                                break;
                            case 'sitemap':
                                $this->render_sitemap_tab();
                                break;
                            case 'breadcrumbs':
                                $this->render_breadcrumbs_tab();
                                break;
                            case 'local_seo':
                                $this->render_local_seo_tab();
                                break;
                            case 'ssl':
                                $this->render_ssl_tab();
                                break;
                            case 'redirects':
                                $this->render_redirects_tab();
                                break;
                            case 'log404':
                                $this->render_404_tab();
                                break;
                            case 'indexing':
                                $this->render_indexing_tab();
                                break;
                            case 'meta_titles':
                                $this->render_meta_titles_tab();
                                break;
                            case 'woocommerce':
                                $this->render_woocommerce_tab();
                                break;
                            case 'seo_images':
                                $this->render_seo_images_tab();
                                break;
                            case 'schema_templates':
                                $this->render_schema_templates_tab();
                                break;
                            case 'page_speed':
                                $this->render_page_speed_tab();
                                break;
                            case 'llms_txt':
                                $this->render_llms_txt_tab();
                                break;
                            case 'webmasters':
                                $this->render_webmasters_tab();
                                break;
                            case 'hreflang':
                                $this->render_hreflang_tab();
                                break;
                            case 'htaccess':
                                $this->render_htaccess_tab();
                                break;
                            case 'support':
                                SEO_Fury_Tickets::get_instance()->render_support_tab();
                                break;
                            default:
                                // Allow PRO addon to render its own tabs
                                do_action('seo_fury_render_admin_tab_' . $current_tab, $this->core);
                                break;
                        }
                        ?>
                    </div>
                </div>
            </div>
        </div>
    <?php
        $output = ob_get_clean();
        echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output is built from escaped parts above
    }

    private function render_general_tab()
    {
        $core = SEO_Fury_Core::get_instance();
        $pro = $core->get_pro_features();
        $is_pro = $pro && $pro->is_pro();
        $hide_branding = $this->should_hide_branding();
    ?>
        <form method="post" action="options.php">
            <?php
            settings_fields('seo_fury_general_settings');
            do_settings_sections('seo_fury_general_settings');
            submit_button();
            ?>
        </form>

        <div class="seo-card" style="margin-top: 20px;">
            <h3 style="margin-top: 0;"><?php echo '🔗 ' . esc_html__('Internal Linking', 'seo-fury'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji, text is escaped ?></h3>
            <p style="color: var(--sf-gray-500); font-size: 13px; margin-bottom: 12px;">
                <?php esc_html_e('Scan your posts and pages for internal linking opportunities. The module analyzes your content and suggests relevant links to other published pages based on keyword and title matching.', 'seo-fury'); ?>
            </p>
            <?php
            // Allow PRO addon to render the internal linking status
            do_action('seo_fury_internal_linking_status', $is_pro, $hide_branding);
            if (!$is_pro && apply_filters('seo_fury_show_upgrade_prompts', true)):
            ?>
                <div class="sf-info-box">
                    <span style="font-size: 20px;">🔒</span>
                    <div>
                        <?php echo wp_kses_post(apply_filters('seo_fury_pro_badge_html', '<span class="seo-fury-pro-badge">PRO</span>', 'internal_linking')); ?>
                        <?php esc_html_e('Available in all PRO plans. Upgrade to unlock smart internal linking suggestions in the post editor.', 'seo-fury'); ?>
                        <?php if (!$hide_branding): ?>
                            <a href="https://seo-fury.com/#pricing" target="_blank" style="font-weight: 600;"><?php esc_html_e('Upgrade', 'seo-fury'); ?> &rarr;</a>
                        <?php endif; ?>
                    </div>
                </div>
            <?php endif; ?>
        </div>

        <div class="seo-card" style="margin-top: 20px;">
            <h3 style="margin-top: 0;"><?php echo '🔄 ' . esc_html__('SEO Data Migration', 'seo-fury'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji, text is escaped ?></h3>
            <div class="sfmw-settings-card">
                <span class="sfmw-settings-card-icon">📥</span>
                <div class="sfmw-settings-card-info">
                    <h4><?php esc_html_e('Import from other SEO plugins', 'seo-fury'); ?></h4>
                    <p><?php esc_html_e('Transfer your SEO titles, descriptions, and settings from Yoast SEO, Rank Math, All in One SEO, or SEOPress.', 'seo-fury'); ?></p>
                </div>
                <button type="button" class="button seo-fury-open-wizard"><?php esc_html_e('Run Migration Wizard', 'seo-fury'); ?></button>
            </div>
        </div>

        <?php
        $ie = $core->get_import_export();
        if ($ie) { $ie->render_section(); }
    ?>
    <?php
    }

    private function render_robots_tab()
    {
    ?>
        <form method="post" action="options.php">
            <?php
            settings_fields('seo_fury_robots_group');
            do_settings_sections('seo_fury_robots_group');
            submit_button();
            ?>
        </form>
    <?php
    }

    private function render_sitemap_tab()
    {
    ?>
        <form method="post" action="options.php">
            <?php
            settings_fields('seo_fury_sitemap_group');
            do_settings_sections('seo_fury_sitemap_group');
            submit_button();
            ?>
        </form>

        <?php
        $sitemap_enabled = get_option('seo_fury_sitemap_enabled', 1);
        if ($sitemap_enabled) {
        ?>
            <div class="seo-sitemap-links">
                <h2><?php esc_html_e('Sitemap Links', 'seo-fury'); ?></h2>
                <p>
                    <strong><?php esc_html_e('Index XML Sitemap:', 'seo-fury'); ?></strong><br>
                    <a href="<?php echo esc_url(home_url('/sitemap.xml')); ?>" target="_blank" style="font-size: 14px;">
                        <?php echo esc_html(home_url('/sitemap.xml')); ?>
                    </a>
                </p>

                <?php
                $html_slug = get_option('seo_fury_html_sitemap_slug', 'html-sitemap');
                ?>
                <p>
                    <strong><?php esc_html_e('HTML Sitemap:', 'seo-fury'); ?></strong><br>
                    <a href="<?php echo esc_url(home_url('/' . $html_slug . '/')); ?>" target="_blank" style="font-size: 14px;">
                        <?php echo esc_html(home_url('/' . $html_slug . '/')); ?>
                    </a>
                </p>

                <p class="description">
                    <?php
                    /* translators: %s: shortcode tag */
                    printf(esc_html__('You can also use the %s shortcode to display the HTML sitemap on any page.', 'seo-fury'), '<code>[seo_fury_html_sitemap]</code>'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML wrapper is hardcoded, text is escaped with esc_html__() ?>
                </p>
            </div>
        <?php
        }
    }

    private function render_breadcrumbs_tab()
    {
        $breadcrumbs = $this->core->get_breadcrumbs();
        if ($breadcrumbs) {
            $breadcrumbs->render_settings_page();
        }
    }

    private function render_local_seo_tab()
    {
        $local_seo = $this->core->get_local_seo();
        if ($local_seo) {
            $local_seo->render_settings_page();
        }
    }


    private function render_redirects_tab()
    {
        ?>
        <div class="seo-redirects-container">

<?php
$core = SEO_Fury_Core::get_instance();
$pro = $core->get_pro_features();

if (!$pro->is_pro()) {
    global $wpdb;
    $redirects_table = $wpdb->prefix . 'seo_redirects';
    $current_count = $wpdb->get_var("SELECT COUNT(*) FROM {$redirects_table}"); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table name is constructed from $wpdb->prefix, not user input
    $limit = $pro->get_limit('max_redirects');
    $percentage = $limit > 0 ? ($current_count / $limit) * 100 : 0;

    $bar_class = '';
    if ($percentage > 80) {
        $bar_class = 'danger';
    } elseif ($percentage > 60) {
        $bar_class = 'warning';
    }
    ?>
    <div class="seo-fury-usage-indicator">
        <div class="usage-header">
            <span class="usage-label"><?php
                /* translators: %1$s: current redirect count, %2$s: maximum redirect limit */
                echo wp_kses_post( '📊 ' . sprintf( __('Redirects used: %1$s of %2$s', 'seo-fury'), '<strong>' . esc_html($current_count) . '</strong>', '<strong>' . esc_html($limit) . '</strong>' ) ); ?></span>
        </div>
        <div class="usage-progress">
            <div class="usage-progress-bar <?php echo esc_attr($bar_class); ?>" style="width: <?php echo esc_attr(min($percentage, 100)); ?>%;"></div>
        </div>
        <?php if ($percentage > 80 && !$this->should_hide_branding() && apply_filters('seo_fury_show_upgrade_prompts', true)): ?>
            <div class="seo-fury-upgrade-notice" style="margin-top: 15px;">
                <strong><?php echo '⚠️ ' . esc_html__('You are nearing the FREE plan limit.', 'seo-fury'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji, text is escaped ?></strong>
                <?php esc_html_e('PRO provides unlimited redirects.', 'seo-fury'); ?>
                <a href="https://seo-fury.com/#pricing" target="_blank" style="color: white; text-decoration: underline;"><?php esc_html_e('Upgrade to PRO', 'seo-fury'); ?> →</a>
            </div>
        <?php endif; ?>
    </div>
    <?php
}

global $wpdb;
$sf_rt      = $wpdb->prefix . 'seo_redirects';
$sf_r_total = (int) $wpdb->get_var("SELECT COUNT(*) FROM {$sf_rt}"); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$sf_r_active = (int) $wpdb->get_var("SELECT COUNT(*) FROM {$sf_rt} WHERE active = 1"); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
?>
            <div class="sf-stats">
                <div class="sf-stat"><div class="sf-stat-val"><?php echo esc_html(number_format_i18n($sf_r_total)); ?></div><div class="sf-stat-lbl"><?php esc_html_e('Total redirects', 'seo-fury'); ?></div></div>
                <div class="sf-stat"><div class="sf-stat-val" style="color:var(--sf-success);"><?php echo esc_html(number_format_i18n($sf_r_active)); ?></div><div class="sf-stat-lbl"><?php esc_html_e('Active', 'seo-fury'); ?></div></div>
                <div class="sf-stat"><div class="sf-stat-val" style="color:var(--sf-gray-400);"><?php echo esc_html(number_format_i18n($sf_r_total - $sf_r_active)); ?></div><div class="sf-stat-lbl"><?php esc_html_e('Inactive', 'seo-fury'); ?></div></div>
            </div>

            <div class="seo-card">
                <h3><?php esc_html_e('Add a new redirect', 'seo-fury'); ?></h3>
                <table class="form-table">
                    <tr>
                        <th scope="row">
                            <label for="redirect-source"><?php esc_html_e('Source URL', 'seo-fury'); ?></label>
                        </th>
                        <td>
                            <input type="text" id="redirect-source" class="regular-text" placeholder="<?php esc_attr_e('/old-page', 'seo-fury'); ?>">
                            <p class="description"><?php
                            /* translators: %s: example URL path */
                            printf(esc_html__('Relative path, e.g. %s', 'seo-fury'), '<code>/old-page</code>'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML wrapper is hardcoded ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="redirect-target"><?php esc_html_e('Target URL', 'seo-fury'); ?></label>
                        </th>
                        <td>
                            <input type="text" id="redirect-target" class="regular-text" placeholder="<?php esc_attr_e('/new-page', 'seo-fury'); ?>">
                            <p class="description"><?php esc_html_e('Full URL or relative path', 'seo-fury'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="redirect-type"><?php esc_html_e('Redirect Type', 'seo-fury'); ?></label>
                        </th>
                        <td>
                            <select id="redirect-type">
                                <option value="301"><?php esc_html_e('301 (Permanent)', 'seo-fury'); ?></option>
                                <option value="302"><?php esc_html_e('302 (Temporary)', 'seo-fury'); ?></option>
                                <option value="307"><?php esc_html_e('307 (Temporary, preserves method)', 'seo-fury'); ?></option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="redirect-is-regex"><?php esc_html_e('Regex', 'seo-fury'); ?></label>
                        </th>
                        <td>
                            <label>
                                <input type="checkbox" id="redirect-is-regex" value="1">
                                <?php esc_html_e('Use regular expression matching', 'seo-fury'); ?>
                            </label>
                            <p class="description"><?php
                            /* translators: %1$s: regex capture group example, %2$s: backreference example */
                            printf(esc_html__('Source will be treated as a regex pattern. Use %1$s for capture groups and %2$s in target for backreferences.', 'seo-fury'), '<code>(.*)</code>', '<code>$1</code>'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML wrappers are hardcoded ?></p>
                        </td>
                    </tr>
                </table>
                <p>
                    <button type="button" id="add-redirect-btn" class="button button-primary"><?php esc_html_e('Add Redirect', 'seo-fury'); ?></button>
                </p>
            </div>

            <div class="seo-card">
                <h3><?php esc_html_e('Test a Redirect', 'seo-fury'); ?></h3>
                <p class="description"><?php esc_html_e('Enter a URL or path to see which rule (if any) would fire — including regex rules and the final target. Nothing is redirected and no hit is counted.', 'seo-fury'); ?></p>
                <p>
                    <input type="text" id="seo-test-redirect-url" class="regular-text" placeholder="<?php esc_attr_e('/old-page or https://example.com/old-page', 'seo-fury'); ?>" style="min-width:320px;">
                    <button type="button" id="seo-test-redirect-btn" class="button button-secondary"><?php esc_html_e('Test', 'seo-fury'); ?></button>
                </p>
                <div id="seo-test-redirect-result"></div>
            </div>

            <div class="seo-card">
                <h3><?php esc_html_e('Import / Export CSV', 'seo-fury'); ?></h3>
                <p class="description"><?php
                /* translators: %s: CSV column names */
                printf(esc_html__('Export all redirects or import a CSV with columns: %s.', 'seo-fury'), '<code>source_url,target_url,redirect_type,active</code>'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML wrapper is hardcoded ?></p>
                <p>
                    <button type="button" id="seo-export-redirects" class="button button-secondary"><?php esc_html_e('Export CSV', 'seo-fury'); ?></button>
                </p>
                <p>
                    <input type="file" id="seo-import-redirects-file" accept=".csv" />
                    <button type="button" id="seo-import-redirects" class="button button-primary"><?php esc_html_e('Import CSV', 'seo-fury'); ?></button>
                </p>
                <div id="seo-import-redirects-result"></div>
            </div>

            <div class="seo-card">
                <h3><?php esc_html_e('Redirects List', 'seo-fury'); ?></h3>
                <table class="wp-list-table widefat fixed striped" id="redirects-table">
                    <thead>
                        <tr>
                            <th style="width: 50px;"><?php esc_html_e('ID', 'seo-fury'); ?></th>
                            <th><?php esc_html_e('Source', 'seo-fury'); ?></th>
                            <th><?php esc_html_e('Target', 'seo-fury'); ?></th>
                            <th style="width: 80px;"><?php esc_html_e('Type', 'seo-fury'); ?></th>
                            <th style="width: 100px;" title="<?php esc_attr_e('Number of times this redirect has been triggered (a visitor or bot hit the source URL and was redirected to the target).', 'seo-fury'); ?>"><?php esc_html_e('Hits', 'seo-fury'); ?></th>
                            <th style="width: 150px;"><?php esc_html_e('Created', 'seo-fury'); ?></th>
                            <th style="width: 100px;"><?php esc_html_e('Status', 'seo-fury'); ?></th>
                            <th style="width: 180px;"><?php esc_html_e('Actions', 'seo-fury'); ?></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td colspan="8" style="text-align: center;"><?php esc_html_e('Loading...', 'seo-fury'); ?></td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>

        <!-- Edit modal -->
        <div id="edit-redirect-modal" class="seo-modal">
            <div class="seo-modal-content">
                <span class="seo-modal-close">&times;</span>
                <h2><?php esc_html_e('Edit Redirect', 'seo-fury'); ?></h2>
                <input type="hidden" id="edit-redirect-id">
                <table class="form-table">
                    <tr>
                        <th scope="row">
                            <label for="edit-redirect-source"><?php esc_html_e('Source', 'seo-fury'); ?></label>
                        </th>
                        <td>
                            <input type="text" id="edit-redirect-source" class="regular-text">
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="edit-redirect-target"><?php esc_html_e('Target', 'seo-fury'); ?></label>
                        </th>
                        <td>
                            <input type="text" id="edit-redirect-target" class="regular-text">
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="edit-redirect-type"><?php esc_html_e('Type', 'seo-fury'); ?></label>
                        </th>
                        <td>
                            <select id="edit-redirect-type">
                                <option value="301">301</option>
                                <option value="302">302</option>
                                <option value="307">307</option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="edit-redirect-is-regex"><?php esc_html_e('Regex', 'seo-fury'); ?></label>
                        </th>
                        <td>
                            <label>
                                <input type="checkbox" id="edit-redirect-is-regex" value="1">
                                <?php esc_html_e('Use regular expression matching', 'seo-fury'); ?>
                            </label>
                        </td>
                    </tr>
                </table>
                <p>
                    <button type="button" id="update-redirect-btn" class="button button-primary"><?php esc_html_e('Save Changes', 'seo-fury'); ?></button>
                </p>
            </div>
        </div>
    <?php
    }

    public function flush_on_slug_change($old_value, $new_value)
    {
        if ($old_value !== $new_value) {
            flush_rewrite_rules();
        }
    }

    public function flush_on_sitemap_toggle($old_value, $new_value)
    {
        if ($old_value !== $new_value) {
            flush_rewrite_rules();
        }
    }

    public function flush_on_post_types_change($old_value, $new_value)
    {
        if ($old_value !== $new_value) {
            flush_rewrite_rules();
        }
    }

    public function flush_on_html_post_types_change($old_value, $new_value)
    {
        if ($old_value !== $new_value) {
            flush_rewrite_rules();
        }
    }

    private function render_indexing_tab()
    {
        $current_sub = isset($_GET['subtab']) ? sanitize_text_field($_GET['subtab']) : 'google';
    ?>
        <div class="seo-fury-indexing-wrap">
            <!-- Sub-tab navigation -->
            <nav class="nav-tab-wrapper" style="margin-bottom: 20px;">
                <a href="?page=seo-fury&tab=indexing&subtab=google"
                   class="nav-tab <?php echo esc_attr( ($current_sub === 'google') ? 'nav-tab-active' : '' ); ?>">
                    <span class="dashicons dashicons-google" style="vertical-align: middle;"></span>
                    <?php esc_html_e('Google Indexing API', 'seo-fury'); ?>
                </a>
                <a href="?page=seo-fury&tab=indexing&subtab=indexnow"
                   class="nav-tab <?php echo esc_attr( ($current_sub === 'indexnow') ? 'nav-tab-active' : '' ); ?>">
                    <span class="dashicons dashicons-update" style="vertical-align: middle;"></span>
                    <?php esc_html_e('IndexNow', 'seo-fury'); ?>
                </a>
                <a href="?page=seo-fury&tab=indexing&subtab=history"
                   class="nav-tab <?php echo esc_attr( ($current_sub === 'history') ? 'nav-tab-active' : '' ); ?>">
                    <span class="dashicons dashicons-backup" style="vertical-align: middle;"></span>
                    <?php esc_html_e('History', 'seo-fury'); ?>
                </a>
            </nav>

            <?php
            switch ($current_sub) {
                case 'indexnow':
                    $this->render_indexnow_subtab();
                    break;
                case 'history':
                    $this->render_indexing_history_subtab();
                    break;
                case 'google':
                default:
                    $this->render_google_indexing_subtab();
                    break;
            }
            ?>
        </div>
    <?php
    }

    private function render_google_indexing_subtab()
    {
        if ($this->core->get_google_indexing()) {
            $this->core->get_google_indexing()->render_settings_page();
        } else {
            $this->render_pro_feature_upsell(
                __('Google Indexing API', 'seo-fury'),
                __('Submit URLs directly to Google via the Indexing API for instant crawling. Supports bulk submissions, daily quotas, and submission history.', 'seo-fury')
            );
        }
    }

    private function render_indexnow_subtab()
    {
    ?>
        <div class="seo-indexnow-container">
            <p><?php esc_html_e('Submit URLs directly to the IndexNow API for instant indexing.', 'seo-fury'); ?> <a href="https://www.indexnow.org" target="_blank"><?php esc_html_e('Learn more', 'seo-fury'); ?></a></p>

            <div class="seo-card">
                <h3><?php esc_html_e('Submit URLs', 'seo-fury'); ?></h3>
                <table class="form-table">
                    <tr>
                        <th scope="row">
                            <label for="indexnow-urls"><?php esc_html_e('URLs to submit', 'seo-fury'); ?></label>
                        </th>
                        <td>
                            <textarea id="indexnow-urls" rows="10" class="large-text" placeholder="<?php esc_attr_e('Enter one URL per line...', 'seo-fury'); ?>"></textarea>
                            <p class="description"><?php esc_html_e('Enter one URL per line. You can submit up to 10,000 URLs at once.', 'seo-fury'); ?></p>
                        </td>
                    </tr>
                </table>
                <p>
                    <button type="button" id="submit-indexnow-btn" class="button button-primary button-large"><?php esc_html_e('Submit to IndexNow', 'seo-fury'); ?></button>
                    <button type="button" id="submit-indexnow-sitemap-btn" class="button button-secondary button-large"><?php esc_html_e('Submit all URLs from sitemap', 'seo-fury'); ?></button>
                </p>
                <p class="description"><?php esc_html_e('“Submit all URLs from sitemap” loads every published URL from your sitemap post types and submits them in batches.', 'seo-fury'); ?></p>

                <div id="indexnow-progress" style="display: none; margin-top: 20px;">
                    <div style="background: var(--sf-gray-100, #f0f0f1); border-radius: 4px; height: 30px; position: relative; overflow: hidden;">
                        <div id="indexnow-progress-bar" style="background: #2271b1; height: 100%; width: 0; transition: width 0.3s;"></div>
                        <div id="indexnow-progress-text" style="position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-weight: 600; color: var(--sf-gray-900, #1d2327);"></div>
                    </div>
                    <div id="indexnow-progress-status" style="margin-top: 10px; text-align: center; font-size: 14px;"></div>
                </div>

                <div id="indexnow-submit-result"></div>
            </div>

            <div class="seo-card" style="margin-top:25px;padding:20px;">
                <details>
                    <summary style="cursor:pointer;font-weight:600;font-size:13px;color:var(--sf-gray-900, #23282d);">
                        <span class="dashicons dashicons-admin-generic" style="vertical-align:middle;margin-right:4px;font-size:16px;width:16px;height:16px;"></span>
                        <?php esc_html_e( 'IndexNow Settings', 'seo-fury' ); ?>
                    </summary>
                    <div style="margin-top:12px;">
                        <form method="post" action="options.php">
                            <?php
                            settings_fields('seo_fury_indexnow_group');
                            do_settings_sections('seo_fury_indexnow_group');
                            submit_button(__('Save Settings', 'seo-fury'));
                            ?>
                        </form>
                    </div>
                </details>
            </div>
        </div>
    <?php
    }

    private function render_indexing_history_subtab()
    {
        global $wpdb;
        $table = $wpdb->prefix . 'seo_indexnow_log';

        // Get all history from both systems
        $rows = $wpdb->get_results(
            "SELECT * FROM {$table} ORDER BY submitted_at DESC LIMIT 100"
        );
        ?>
        <div class="seo-card">
            <h3><?php esc_html_e('Submission History', 'seo-fury'); ?></h3>
            <p><?php esc_html_e('Combined history from Google Indexing API and IndexNow submissions.', 'seo-fury'); ?></p>
            <p>
                <button type="button" id="clear-indexnow-history-btn" class="button" style="color: #d63638;">
                    <?php esc_html_e('Clear History', 'seo-fury'); ?>
                </button>
            </p>

            <table class="wp-list-table widefat fixed striped" style="margin-top: 10px;">
                <thead>
                    <tr>
                        <th style="width: 160px;"><?php esc_html_e('Time', 'seo-fury'); ?></th>
                        <th><?php esc_html_e('URL', 'seo-fury'); ?></th>
                        <th style="width: 80px;"><?php esc_html_e('Status', 'seo-fury'); ?></th>
                        <th style="width: 140px;"><?php esc_html_e('Method', 'seo-fury'); ?></th>
                        <th style="width: 90px;"><?php esc_html_e('System', 'seo-fury'); ?></th>
                    </tr>
                </thead>
                <tbody>
                <?php if (empty($rows)) : ?>
                    <tr>
                        <td colspan="5" style="text-align: center;"><?php esc_html_e('No submissions yet.', 'seo-fury'); ?></td>
                    </tr>
                <?php else : ?>
                    <?php foreach ($rows as $row) :
                        $is_google = (strpos($row->method, 'google_api_') === 0);
                        $system_label = $is_google ? 'Google API' : 'IndexNow';
                        $system_color = $is_google ? '#4285F4' : '#00a32a';
                        $status_class = ($row->response_code >= 200 && $row->response_code < 300) ? 'color:#00a32a' : 'color:#d63638';
                        $method_display = $is_google ? str_replace('google_api_', '', $row->method) : $row->method;
                    ?>
                        <tr>
                            <td><?php echo esc_html($row->submitted_at); ?></td>
                            <td style="word-break: break-all;"><?php echo esc_html($row->url); ?></td>
                            <td><span style="<?php echo esc_attr($status_class); ?>"><?php echo esc_html($row->response_code); ?></span></td>
                            <td><?php echo esc_html($method_display); ?></td>
                            <td><span style="color:<?php echo esc_attr($system_color); ?>;font-weight:600;"><?php echo esc_html($system_label); ?></span></td>
                        </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
                </tbody>
            </table>
        </div>
    <?php
    }

    private function render_meta_titles_tab()
    {
        if (!current_user_can('manage_options')) {
            return;
        }
    ?>
        <?php
        $meta_titles = $this->core->get_meta_titles();
        if ($meta_titles && method_exists($meta_titles, 'render_settings_page')) {
            $meta_titles->render_settings_page();
        } else {
            ?>
            <form method="post" action="options.php">
                <?php
                settings_fields('seo_fury_meta_group');
                do_settings_sections('seo_fury_meta_group');
                submit_button();
                ?>
            </form>
            <?php
        }
        ?>
    <?php
    }

    private function render_404_tab()
    {
        // Subtab navigation for combined 404 & Link Health tab.
        // Uses JavaScript switching to avoid WAF issues with URL parameters.
        $subtab = isset($_GET['subtab']) ? sanitize_text_field($_GET['subtab']) : '404_monitor';
        ?>
        <nav class="nav-tab-wrapper" style="margin-bottom: 20px;">
            <a href="#" class="nav-tab seo-fury-subtab-nav<?php echo esc_attr( $subtab === '404_monitor' ? ' nav-tab-active' : '' ); ?>" data-subtab="404_monitor">
                <span class="dashicons dashicons-warning" style="vertical-align: middle;"></span>
                <?php esc_html_e('404 Monitor', 'seo-fury'); ?>
            </a>
            <a href="#" class="nav-tab seo-fury-subtab-nav<?php echo esc_attr( $subtab === 'links' ? ' nav-tab-active' : '' ); ?>" data-subtab="links">
                <span class="dashicons dashicons-admin-links" style="vertical-align: middle;"></span>
                <?php esc_html_e('Link Scanner', 'seo-fury'); ?>
            </a>
        </nav>

        <!-- Link Scanner subtab content -->
        <div id="seo-fury-subtab-links" class="seo-fury-subtab-content" style="display:<?php echo esc_attr( $subtab === 'links' ? 'block' : 'none' ); ?>;">
            <?php
            $bl = class_exists('SEO_Fury_Broken_Links') ? SEO_Fury_Broken_Links::get_instance() : null;
            if ($bl) {
                $bl->render_tab();
            } else {
                $this->render_pro_feature_upsell(
                    __('Link Scanner', 'seo-fury'),
                    __('Scan your site for broken links, redirects, and link issues. Find and fix problems that hurt your SEO and user experience.', 'seo-fury')
                );
            }
            ?>
        </div>

        <!-- 404 Monitor subtab content -->
        <div id="seo-fury-subtab-404_monitor" class="seo-fury-subtab-content" style="display:<?php echo esc_attr( $subtab !== 'links' ? 'block' : 'none' ); ?>;">

    <?php
    $core = SEO_Fury_Core::get_instance();
    $pro = $core->get_pro_features();

    if ($pro && !$pro->is_pro()) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'seo_404_log';
        $current_count = $wpdb->get_var("SELECT COUNT(*) FROM {$table_name}"); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table name is constructed from $wpdb->prefix, not user input
        $limit = $pro->get_limit('max_404_logs');
        $percentage = $limit > 0 ? ($current_count / $limit) * 100 : 0;

        $bar_class = '';
        if ($percentage > 80) {
            $bar_class = 'danger';
        } elseif ($percentage > 60) {
            $bar_class = 'warning';
        }
        ?>
        <div class="seo-fury-usage-indicator">
            <div class="usage-header">
                <span class="usage-label"><?php
                    /* translators: %1$s: current 404 log count, %2$s: maximum log limit */
                    echo wp_kses_post( '📊 ' . sprintf( __('404 logs used: %1$s of %2$s', 'seo-fury'), '<strong>' . esc_html($current_count) . '</strong>', '<strong>' . esc_html($limit) . '</strong>' ) ); ?></span>
            </div>
            <div class="usage-progress">
                <div class="usage-progress-bar <?php echo esc_attr($bar_class); ?>" style="width: <?php echo esc_attr(min($percentage, 100)); ?>%;"></div>
            </div>
            <?php if ($percentage > 80 && !$this->should_hide_branding() && apply_filters('seo_fury_show_upgrade_prompts', true)): ?>
                <div class="seo-fury-upgrade-notice" style="margin-top: 15px;">
                    <strong><?php echo '⚠️ ' . esc_html__('You are nearing the FREE plan limit.', 'seo-fury'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji, text is escaped ?></strong>
                    <?php esc_html_e('PRO removes limits for 404 logging.', 'seo-fury'); ?>
                    <a href="https://seo-fury.com/#pricing" target="_blank" style="color: white; text-decoration: underline;"><?php esc_html_e('Upgrade to PRO', 'seo-fury'); ?> &rarr;</a>
                </div>
            <?php endif; ?>
        </div>
        <?php
    }
    ?>

        <div class="seo-404-container">

            <div class="seo-card">
                <h3><?php esc_html_e('404 Statistics', 'seo-fury'); ?></h3>
                <div id="404-stats" style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; margin-bottom: 20px;">
                    <div style="background: var(--sf-gray-100, #f6f7f7); padding: 15px; border-radius: 4px; text-align: center;">
                        <div style="font-size: 24px; font-weight: 600; color: #2271b1;" id="stat-total">0</div>
                    <div style="font-size: 12px; color: var(--sf-gray-500, #646970); margin-top: 5px;"><?php esc_html_e('Total URLs', 'seo-fury'); ?></div>
                    </div>
                    <div style="background: #fcf0f1; padding: 15px; border-radius: 4px; text-align: center;">
                        <div style="font-size: 24px; font-weight: 600; color: #d63638;" id="stat-active">0</div>
                        <div style="font-size: 12px; color: var(--sf-gray-500, #646970); margin-top: 5px;"><?php esc_html_e('Active', 'seo-fury'); ?></div>
                    </div>
                    <div style="background: #edfaef; padding: 15px; border-radius: 4px; text-align: center;">
                        <div style="font-size: 24px; font-weight: 600; color: #00a32a;" id="stat-resolved">0</div>
                        <div style="font-size: 12px; color: var(--sf-gray-500, #646970); margin-top: 5px;"><?php esc_html_e('Resolved', 'seo-fury'); ?></div>
                    </div>
                    <div style="background: var(--sf-primary-light, #f0f6fc); padding: 15px; border-radius: 4px; text-align: center;" title="<?php esc_attr_e('Total number of requests that returned 404 across all logged URLs. One “hit” = one HTTP request (visitor, direct URL entry, bot or crawler). Not mouse clicks.', 'seo-fury'); ?>">
                        <div style="font-size: 24px; font-weight: 600; color: #2271b1;" id="stat-hits">0</div>
                        <div style="font-size: 12px; color: var(--sf-gray-500, #646970); margin-top: 5px; cursor: help; border-bottom: 1px dotted var(--sf-gray-400, #646970); display: inline-block;"><?php esc_html_e('Total Hits', 'seo-fury'); ?></div>
                    </div>
                </div>

                <p>
                    <button type="button" id="refresh-404-log" class="button"><?php echo '🔄 ' . esc_html__('Refresh', 'seo-fury'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji, text is escaped ?></button>
                    <button type="button" id="seo-export-404-logs" class="button"><?php echo '📥 ' . esc_html__('Export CSV', 'seo-fury'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji, text is escaped ?></button>
                    <button type="button" id="clear-404-log" class="button" style="color: #d63638;"><?php echo '🗑️ ' . esc_html__('Clear All', 'seo-fury'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji, text is escaped ?></button>
                </p>

                <table class="wp-list-table widefat fixed striped" id="log-404-table">
                    <thead>
                        <tr>
                            <th style="width: 40px;"><?php esc_html_e('ID', 'seo-fury'); ?></th>
                            <th style="width: 35%;"><?php esc_html_e('URL', 'seo-fury'); ?></th>
                            <th style="width: 70px;" title="<?php esc_attr_e('Number of times this URL was requested and returned 404 (any source: visitor, direct URL entry, bot or crawler). Not mouse clicks.', 'seo-fury'); ?>"><?php esc_html_e('Hits', 'seo-fury'); ?></th>
                            <th style="width: 130px;"><?php esc_html_e('First Seen', 'seo-fury'); ?></th>
                            <th style="width: 130px;"><?php esc_html_e('Last Seen', 'seo-fury'); ?></th>
                            <th style="width: 90px;"><?php esc_html_e('Status', 'seo-fury'); ?></th>
                            <th style="width: 200px;"><?php esc_html_e('Actions', 'seo-fury'); ?></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td colspan="7" style="text-align: center;"><?php esc_html_e('Loading...', 'seo-fury'); ?></td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <!-- 404 table styles -->
            <style>
                #log-404-table td code {
                    word-break: break-word !important;
                    white-space: normal !important;
                    display: block;
                    max-width: 100%;
                }

                #log-404-table .error-404-actions {
                    white-space: nowrap;
                }

                #log-404-table .error-404-actions .button {
                    margin-bottom: 3px;
                }
            </style>

        </div>

        <div class="seo-card" style="margin-top:25px;padding:20px;">
            <details>
                <summary style="cursor:pointer;font-weight:600;font-size:13px;color:var(--sf-gray-900, #23282d);">
                    <span class="dashicons dashicons-admin-generic" style="vertical-align:middle;margin-right:4px;font-size:16px;width:16px;height:16px;"></span>
                    <?php esc_html_e( '404 Monitor Settings', 'seo-fury' ); ?>
                </summary>
                <div style="margin-top:12px;">
                    <form method="post" action="options.php">
                        <?php
                        settings_fields('seo_fury_404_group');
                        do_settings_sections('seo_fury_404_group');
                        submit_button();
                        ?>
                    </form>
                </div>
            </details>
        </div>

        <!-- Similar pages modal -->
        <div id="find-similar-modal" class="seo-modal">
            <div class="seo-modal-content">
                <span class="seo-modal-close">&times;</span>
                <h2><?php esc_html_e('Find a Similar Page', 'seo-fury'); ?></h2>
                <input type="hidden" id="similar-404-id">
                <input type="hidden" id="similar-source-url">

                <p><strong><?php esc_html_e('404 URL:', 'seo-fury'); ?></strong> <code id="similar-url-display"></code></p>

                <div id="similar-pages-results" style="margin: 20px 0;">
                    <p><?php esc_html_e('Loading...', 'seo-fury'); ?></p>
                </div>
            </div>
        </div>

        <!-- Create redirect modal -->
        <div id="create-redirect-modal" class="seo-modal">
            <div class="seo-modal-content">
                <span class="seo-modal-close">&times;</span>
                <h2><?php esc_html_e('Create Redirect', 'seo-fury'); ?></h2>
                <input type="hidden" id="redirect-404-id">

                <table class="form-table">
                    <tr>
                        <th scope="row"><label for="error-404-redirect-source"><?php esc_html_e('Source (404 URL)', 'seo-fury'); ?></label></th>
                        <td>
                            <input type="text" id="error-404-redirect-source" class="regular-text" readonly>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="error-404-redirect-target"><?php esc_html_e('Target (Target URL)', 'seo-fury'); ?></label></th>
                        <td>
                            <input type="text" id="error-404-redirect-target" class="regular-text" placeholder="https://">
                            <p class="description"><?php esc_html_e('Full URL or relative path', 'seo-fury'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="redirect-type-modal"><?php esc_html_e('Redirect Type', 'seo-fury'); ?></label></th>
                        <td>
                            <select id="redirect-type-modal">
                                <option value="301"><?php esc_html_e('301 (Permanent)', 'seo-fury'); ?></option>
                                <option value="302"><?php esc_html_e('302 (Temporary)', 'seo-fury'); ?></option>
                                <option value="307"><?php esc_html_e('307 (Temporary, preserves method)', 'seo-fury'); ?></option>
                            </select>
                        </td>
                    </tr>
                </table>

                <p>
                    <button type="button" id="save-redirect-btn" class="button button-primary"><?php echo '💾 ' . esc_html__('Create Redirect', 'seo-fury'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji, text is escaped ?></button>
                </p>
            </div>
        </div>

        </div><!-- /.seo-fury-subtab-content #seo-fury-subtab-404_monitor -->

        <script>
        jQuery(function($) {
            $(document).on('click', '.seo-fury-subtab-nav', function(e) {
                e.preventDefault();
                var subtab = $(this).data('subtab');
                // Switch active tab
                $('.seo-fury-subtab-nav').removeClass('active nav-tab-active');
                $(this).addClass('active nav-tab-active');
                // Show/hide content
                $('.seo-fury-subtab-content').hide();
                $('#seo-fury-subtab-' + subtab).show();
                // Update URL without reload (for bookmarking)
                if (window.history && window.history.replaceState) {
                    var url = new URL(window.location);
                    url.searchParams.set('subtab', subtab);
                    window.history.replaceState({}, '', url);
                }
            });
        });
        </script>
    <?php
    }

    private function render_woocommerce_tab()
    {
        $woocommerce = $this->core->get_woocommerce();
        if ($woocommerce) {
            $woocommerce->render_settings_page();
        }
    }


    private function render_seo_images_tab()
    {
        $seo_images = $this->core->get_seo_images();
        if ($seo_images) {
            $seo_images->render_settings_page();
        } else {
            // Show free Basic Image SEO settings
            $image_seo_basic = $this->core->get_image_seo_basic();
            if ($image_seo_basic) {
                $image_seo_basic->render_settings_page();
            }

            // Show PRO upsell for advanced AI features
            echo '<hr style="margin:30px 0;border:none;border-top:1px solid var(--sf-gray-200,#e2e8f0);">';
            $this->render_pro_feature_upsell(
                __('AI Image Optimization', 'seo-fury'),
                __('Bulk optimize image alt text, titles, and filenames for SEO. Automatically generate descriptive alt tags using AI based on post context.', 'seo-fury')
            );
        }
    }

    /**
     * Render the Schema Templates management tab.
     *
     * Loads templates via AJAX, renders a table with edit/delete actions.
     * Add/Edit links go to the existing hidden editor page.
     */
    private function render_schema_templates_tab()
    {
        $nonce = wp_create_nonce('seo_fury_schema_templates_nonce');
        ?>
        <div class="seo-schema-tpl-wrap">
            <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;">
                <p style="margin:0; color:var(--sf-gray-500);">
                    <?php esc_html_e('Schema templates let you save schema configurations and apply them to posts in bulk or per-post.', 'seo-fury'); ?>
                </p>
                <button type="button" id="seo-tpl-add-new-btn" class="button button-primary" style="background:var(--sf-primary);border-color:var(--sf-primary);white-space:nowrap;">
                    <span class="dashicons dashicons-plus-alt2" style="font-size:16px;width:16px;height:16px;margin-top:4px;vertical-align:middle;"></span>
                    <?php esc_html_e('Add New Template', 'seo-fury'); ?>
                </button>
            </div>

            <div id="seo-tpl-loading" style="text-align:center; padding:40px 0;">
                <span class="spinner is-active" style="float:none;"></span>
                <p><?php esc_html_e('Loading templates...', 'seo-fury'); ?></p>
            </div>

            <div id="seo-tpl-empty" style="display:none; text-align:center; padding:60px 20px; background:var(--sf-gray-50); border-radius:var(--sf-radius-sm); border:1px dashed var(--sf-gray-200);">
                <span style="font-size:48px; display:block; margin-bottom:24px;">📋</span>
                <h3 style="margin:0 0 8px;"><?php esc_html_e('No Schema Templates Yet', 'seo-fury'); ?></h3>
                <p style="color:var(--sf-gray-500); margin:0 0 16px;"><?php esc_html_e('Create your first template to quickly apply consistent schema markup across your site.', 'seo-fury'); ?></p>
                <button type="button" class="seo-tpl-add-new-btn button button-primary" style="background:var(--sf-primary);border-color:var(--sf-primary);">
                    <?php esc_html_e('Create Template', 'seo-fury'); ?>
                </button>
            </div>

            <table id="seo-tpl-table" class="widefat striped" style="display:none;">
                <thead>
                    <tr>
                        <th style="width:35%;"><?php esc_html_e('Name', 'seo-fury'); ?></th>
                        <th style="width:20%;"><?php esc_html_e('Schema Type', 'seo-fury'); ?></th>
                        <th style="width:15%;"><?php esc_html_e('Mode', 'seo-fury'); ?></th>
                        <th style="width:15%;"><?php esc_html_e('Date', 'seo-fury'); ?></th>
                        <th style="width:15%; text-align:right;"><?php esc_html_e('Actions', 'seo-fury'); ?></th>
                    </tr>
                </thead>
                <tbody id="seo-tpl-body"></tbody>
            </table>
        </div>

        <!-- Hidden inputs and notices required by schema-template-editor.js in inline mode -->
        <div id="sf-template-editor-notices"></div>
        <input type="hidden" id="seo_fury_schema_items" value="[]">
        <input type="hidden" id="seo_fury_schema_active" value="">
        <input type="hidden" id="sf-template-name-input" value="">

        <?php
        // Render the schema generator modal (empty — data loaded dynamically via AJAX)
        if (class_exists('SEO_Fury_Post_Meta_Schema')) {
            $schema_handler = new SEO_Fury_Post_Meta_Schema();
            $schema_handler->render_template_generator_html(array());
        }
        ?>

        <script>
        jQuery(function($) {
            var nonce = '<?php echo esc_js($nonce); ?>';
            var modeLabels = {
                'generator': '<?php echo esc_js(__('Generator', 'seo-fury')); ?>',
                'custom': '<?php echo esc_js(__('Custom JSON-LD', 'seo-fury')); ?>',
                'custom_builder': '<?php echo esc_js(__('Constructor', 'seo-fury')); ?>'
            };

            function loadTemplates() {
                $.post(ajaxurl, {
                    action: 'seo_fury_get_schema_templates',
                    nonce: nonce
                }, function(res) {
                    $('#seo-tpl-loading').hide();

                    var tpls = (res.data && res.data.templates) ? res.data.templates : [];
                    if (!res.success || tpls.length === 0) {
                        $('#seo-tpl-empty').show();
                        return;
                    }

                    var rows = '';
                    $.each(tpls, function(i, tpl) {
                        var type = tpl.type || '—';
                        var mode = modeLabels[tpl.mode] || tpl.mode || '—';
                        var name = $('<div>').text(tpl.name).html();
                        var typeLabel = type.charAt(0).toUpperCase() + type.slice(1);

                        rows += '<tr data-id="' + tpl.id + '">' +
                            '<td><strong><button type="button" class="button-link seo-tpl-edit-btn" data-id="' + tpl.id + '">' + name + '</button></strong></td>' +
                            '<td><span style="display:inline-block;padding:2px 8px;background:var(--sf-gray-100);border-radius:10px;font-size:12px;">' + $('<div>').text(typeLabel).html() + '</span></td>' +
                            '<td>' + $('<div>').text(mode).html() + '</td>' +
                            '<td style="color:var(--sf-gray-500);">' + (tpl.date || '—') + '</td>' +
                            '<td style="text-align:right;">' +
                                '<button type="button" class="button button-small seo-tpl-edit-btn" data-id="' + tpl.id + '"><?php echo esc_js(__('Edit', 'seo-fury')); ?></button> ' +
                                '<button type="button" class="button button-small seo-tpl-delete" data-id="' + tpl.id + '" data-name="' + name + '" style="color:#b32d2e;border-color:#b32d2e;"><?php echo esc_js(__('Delete', 'seo-fury')); ?></button>' +
                            '</td>' +
                        '</tr>';
                    });

                    $('#seo-tpl-body').html(rows);
                    $('#seo-tpl-table').show();
                });
            }

            $(document).on('click', '.seo-tpl-delete', function() {
                var id = $(this).data('id');
                var name = $(this).data('name');
                if (!confirm('<?php echo esc_js(__('Delete template', 'seo-fury')); ?> "' + name + '"?')) {
                    return;
                }
                var $row = $(this).closest('tr');
                $row.css('opacity', '0.5');

                $.post(ajaxurl, {
                    action: 'seo_fury_delete_schema_template',
                    nonce: nonce,
                    template_id: id
                }, function(res) {
                    if (res.success) {
                        $row.fadeOut(300, function() {
                            $(this).remove();
                            if ($('#seo-tpl-body tr').length === 0) {
                                $('#seo-tpl-table').hide();
                                $('#seo-tpl-empty').show();
                            }
                        });
                    } else {
                        $row.css('opacity', '1');
                        alert('<?php echo esc_js(__('Failed to delete template.', 'seo-fury')); ?>');
                    }
                });
            });

            // Refresh the list when inline editor saves a template
            $(document).on('seo-fury:template-list-refresh', function() {
                $('#seo-tpl-loading').show();
                $('#seo-tpl-table').hide();
                $('#seo-tpl-empty').hide();
                $('#seo-tpl-body').html('');
                loadTemplates();
            });

            loadTemplates();
        });
        </script>
        <?php
    }


    private function render_page_speed_tab() {
        $core = SEO_Fury_Core::get_instance();
        $ps = $core->get_page_speed();
        if ($ps) { $ps->render_admin_tab(); }
    }

    private function render_llms_txt_tab() {
        $core = SEO_Fury_Core::get_instance();
        $llms = $core->get_llms_txt();
        if ($llms) {
            $llms->render_admin_tab();
        }
    }


    private function render_webmasters_tab() {
        $current_sub = isset($_GET['subtab']) ? sanitize_text_field($_GET['subtab']) : 'verification';
    ?>
        <div class="seo-fury-webmasters-wrap">
            <!-- Sub-tab navigation -->
            <nav class="nav-tab-wrapper" style="margin-bottom: 20px;">
                <a href="?page=seo-fury&tab=webmasters&subtab=verification"
                   class="nav-tab <?php echo esc_attr( ($current_sub === 'verification') ? 'nav-tab-active' : '' ); ?>">
                    <span class="dashicons dashicons-yes-alt" style="vertical-align: middle;"></span>
                    <?php esc_html_e('Site Verification', 'seo-fury'); ?>
                </a>
                <a href="?page=seo-fury&tab=webmasters&subtab=gsc"
                   class="nav-tab <?php echo esc_attr( ($current_sub === 'gsc') ? 'nav-tab-active' : '' ); ?>">
                    <span class="dashicons dashicons-google" style="vertical-align: middle;"></span>
                    <?php esc_html_e('Google Search Console', 'seo-fury'); ?>
                    <?php
                    $pro = $this->core ? $this->core->get_pro_features() : null;
                    if ($pro && !$pro->has_feature('google_search_console')) {
                        echo wp_kses_post(apply_filters('seo_fury_pro_badge_html', '<span class="seo-fury-pro-badge" style="margin-left: 5px; font-size: 10px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: #fff; padding: 2px 6px; border-radius: 3px; vertical-align: middle;">PRO</span>', 'google_search_console'));
                    }
                    ?>
                </a>
            </nav>

            <?php
            switch ($current_sub) {
                case 'gsc':
                    $this->render_gsc_subtab();
                    break;
                case 'verification':
                default:
                    $this->render_verification_subtab();
                    break;
            }
            ?>
        </div>
    <?php
    }

    private function render_verification_subtab() {
        $sv = $this->core->get_site_verification();
        if ($sv) {
            $sv->render_admin_tab();
        } else {
            echo '<p>' . esc_html__('Site Verification module is not available.', 'seo-fury') . '</p>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded HTML, text is escaped
        }
    }

    private function render_gsc_subtab() {
        $gsc = $this->core->get_google_search_console();
        if ($gsc) {
            $gsc->render_admin_tab();
        } else {
            $this->render_pro_feature_upsell(
                __('Google Search Console', 'seo-fury'),
                __('Connect Google Search Console to view search performance, indexing status, and keyword data directly in your WordPress dashboard.', 'seo-fury')
            );
        }
    }








    private function render_hreflang_tab() {
        $hl = $this->core->get_hreflang();
        if ($hl) {
            $hl->render_admin_tab();
        } else {
            echo '<p>' . esc_html__('Hreflang module is not available.', 'seo-fury') . '</p>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded HTML, text is escaped
        }
    }



    private function render_htaccess_tab()
    {
        $htaccess = $this->core->get_htaccess();
        if ($htaccess) {
            $htaccess->render_settings_page();
        }
    }

    private function render_ssl_tab()
    {
        $general = $this->core->get_general();
        ?>
        <div class="seo-card" style="margin-bottom: 20px;">
            <?php
            $has_ssl = is_ssl();
            $force_https = get_option('seo_fury_force_https', 0);
            $fix_mixed = get_option('seo_fury_fix_mixed_content', 0);
            $hsts = get_option('seo_fury_enable_hsts', 0);
            $www_redirect = get_option('seo_fury_www_redirect', '');

            // Check SSL certificate details
            $ssl_expiry = '';
            $ssl_issuer = '';
            $ssl_days_left = null;
            if ($has_ssl) {
                $home_host = wp_parse_url(home_url(), PHP_URL_HOST);
                if ($home_host) {
                    $context = stream_context_create(array('ssl' => array('capture_peer_cert' => true, 'verify_peer' => false)));
                    $stream = @stream_socket_client('ssl://' . $home_host . ':443', $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $context);
                    if ($stream) {
                        $params = stream_context_get_params($stream);
                        if (!empty($params['options']['ssl']['peer_certificate'])) {
                            $cert_info = openssl_x509_parse($params['options']['ssl']['peer_certificate']);
                            if ($cert_info) {
                                if (!empty($cert_info['validTo_time_t'])) {
                                    $ssl_days_left = (int) floor(($cert_info['validTo_time_t'] - time()) / 86400);
                                    $ssl_expiry = date_i18n(get_option('date_format'), $cert_info['validTo_time_t']);
                                }
                                if (!empty($cert_info['issuer']['O'])) {
                                    $ssl_issuer = $cert_info['issuer']['O'];
                                } elseif (!empty($cert_info['issuer']['CN'])) {
                                    $ssl_issuer = $cert_info['issuer']['CN'];
                                }
                            }
                        }
                        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
                        fclose($stream);
                    }
                }
            }

            $ssl_expiry_color = '#ECFDF5';
            $ssl_expiry_icon = '✅';
            if ($ssl_days_left !== null && $ssl_days_left <= 14) {
                $ssl_expiry_color = '#FEF2F2';
                $ssl_expiry_icon = '🔴';
            } elseif ($ssl_days_left !== null && $ssl_days_left <= 30) {
                $ssl_expiry_color = '#FEF3C7';
                $ssl_expiry_icon = '🟡';
            }
            ?>

            <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin-bottom: 25px;">
                <div style="background: <?php echo esc_attr( $has_ssl ? '#ECFDF5' : '#FEF2F2' ); ?>; border-radius: 10px; padding: 16px; text-align: center;">
                    <div style="font-size: 28px;"><?php echo $has_ssl ? '✅' : '❌'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji strings ?></div>
                    <div style="font-weight: 600; margin-top: 5px; font-size: 13px;"><?php esc_html_e('SSL Certificate', 'seo-fury'); ?></div>
                    <div style="font-size: 11px; color: var(--sf-gray-500, #64748b); margin-top: 2px;">
                        <?php
                        if ($has_ssl && $ssl_issuer) {
                            echo esc_html($ssl_issuer);
                        } elseif ($has_ssl) {
                            esc_html_e('Active', 'seo-fury');
                        } else {
                            esc_html_e('Not detected', 'seo-fury');
                        }
                        ?>
                    </div>
                </div>
                <?php if ($has_ssl && $ssl_days_left !== null): ?>
                <div style="background: <?php echo esc_attr($ssl_expiry_color); ?>; border-radius: 10px; padding: 16px; text-align: center;">
                    <div style="font-size: 28px;"><?php echo esc_html($ssl_expiry_icon); ?></div>
                    <div style="font-weight: 600; margin-top: 5px; font-size: 13px;"><?php esc_html_e('Expires', 'seo-fury'); ?></div>
                    <div style="font-size: 11px; color: var(--sf-gray-500, #64748b); margin-top: 2px;">
                        <?php
                        if ($ssl_days_left <= 0) {
                            echo '<strong style="color: #DC2626;">' . esc_html__('Expired!', 'seo-fury') . '</strong>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML wrapper is hardcoded, text is escaped with esc_html__()
                        } else {
                            /* translators: %1$s: date, %2$d: number of days */
                            printf(esc_html__('%1$s (%2$d days)', 'seo-fury'), esc_html($ssl_expiry), intval($ssl_days_left));
                        }
                        ?>
                    </div>
                </div>
                <?php endif; ?>
                <div style="background: <?php echo esc_attr( $force_https ? '#ECFDF5' : '#FEF3C7' ); ?>; border-radius: 10px; padding: 16px; text-align: center;">
                    <div style="font-size: 28px;"><?php echo $force_https ? '✅' : '⚠️'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji strings ?></div>
                    <div style="font-weight: 600; margin-top: 5px; font-size: 13px;"><?php esc_html_e('HTTPS Redirect', 'seo-fury'); ?></div>
                    <div style="font-size: 11px; color: var(--sf-gray-500, #64748b); margin-top: 2px;"><?php echo $force_https ? esc_html__('Enabled', 'seo-fury') : esc_html__('Disabled', 'seo-fury'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- both branches are escaped with esc_html__() ?></div>
                </div>
                <div style="background: <?php echo esc_attr( $fix_mixed ? '#ECFDF5' : '#F1F5F9' ); ?>; border-radius: 10px; padding: 16px; text-align: center;">
                    <div style="font-size: 28px;"><?php echo $fix_mixed ? '✅' : '➖'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji strings ?></div>
                    <div style="font-weight: 600; margin-top: 5px; font-size: 13px;"><?php esc_html_e('Mixed Content', 'seo-fury'); ?></div>
                    <div style="font-size: 11px; color: var(--sf-gray-500, #64748b); margin-top: 2px;"><?php echo $fix_mixed ? esc_html__('Auto-fix on', 'seo-fury') : esc_html__('Not active', 'seo-fury'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- both branches are escaped with esc_html__() ?></div>
                </div>
                <div style="background: <?php echo esc_attr( $hsts ? '#ECFDF5' : '#F1F5F9' ); ?>; border-radius: 10px; padding: 16px; text-align: center;">
                    <div style="font-size: 28px;"><?php echo $hsts ? '✅' : '➖'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded emoji strings ?></div>
                    <div style="font-weight: 600; margin-top: 5px; font-size: 13px;"><?php esc_html_e('HSTS Header', 'seo-fury'); ?></div>
                    <div style="font-size: 11px; color: var(--sf-gray-500, #64748b); margin-top: 2px;"><?php echo $hsts ? esc_html__('Active', 'seo-fury') : esc_html__('Not active', 'seo-fury'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- both branches are escaped with esc_html__() ?></div>
                </div>
            </div>

            <?php if (!$has_ssl): ?>
            <div class="sf-info-box sf-info-box--danger" style="align-items: flex-start; margin-bottom: 20px;">
                <span style="font-size: 22px;">🔓</span>
                <div>
                    <strong class="sf-info-box-title"><?php esc_html_e('SSL certificate not detected', 'seo-fury'); ?></strong>
                    <p style="margin: 4px 0 0; font-size: 13px;">
                        <?php esc_html_e('Your site is currently accessed via HTTP. To enable HTTPS features, you need to install an SSL certificate. Most hosting providers offer free SSL via Let\'s Encrypt. Contact your hosting provider for assistance.', 'seo-fury'); ?>
                    </p>
                </div>
            </div>
            <?php endif; ?>

            <?php if ($has_ssl && $ssl_days_left !== null && $ssl_days_left <= 14 && $ssl_days_left > 0): ?>
            <div class="sf-info-box" style="align-items: flex-start; margin-bottom: 20px;">
                <span style="font-size: 22px;">⚠️</span>
                <div>
                    <strong class="sf-info-box-title"><?php esc_html_e('SSL certificate expiring soon!', 'seo-fury'); ?></strong>
                    <p style="margin: 4px 0 0; font-size: 13px;">
                        <?php
                        printf(
                            /* translators: %d: number of days until SSL certificate expires */
                            esc_html__('Your SSL certificate will expire in %d days. Please renew it to avoid security warnings for your visitors.', 'seo-fury'),
                            intval($ssl_days_left)
                        );
                        ?>
                    </p>
                </div>
            </div>
            <?php endif; ?>

            <?php if ($has_ssl && $ssl_days_left !== null && $ssl_days_left <= 0): ?>
            <div class="sf-info-box sf-info-box--danger" style="align-items: flex-start; margin-bottom: 20px;">
                <span style="font-size: 22px;">🔴</span>
                <div>
                    <strong class="sf-info-box-title"><?php esc_html_e('SSL certificate has expired!', 'seo-fury'); ?></strong>
                    <p style="margin: 4px 0 0; font-size: 13px;">
                        <?php esc_html_e('Your SSL certificate has expired. Visitors will see security warnings in their browser. Please renew your SSL certificate immediately.', 'seo-fury'); ?>
                    </p>
                </div>
            </div>
            <?php endif; ?>
        </div>

        <form method="post" action="options.php">
            <?php
            settings_fields('seo_fury_ssl_settings');
            do_settings_sections('seo_fury_ssl_settings');
            submit_button(__('Save Security Settings', 'seo-fury'));
            ?>
        </form>
        <?php
    }

    private function render_changelog_tab()
    {
        $changelog_data = $this->get_changelog_data();
    ?>
        <div class="seo-changelog-container">
            <div class="seo-card">
                <div style="display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-bottom: 20px;">
                    <a href="<?php echo esc_url(add_query_arg('refresh_changelog', '1')); ?>" class="button" title="<?php esc_attr_e('Refresh changelog from server', 'seo-fury'); ?>">
                        <span class="dashicons dashicons-update" style="vertical-align: middle;"></span>
                    </a>
                    <div style="background: var(--sf-primary-light, #f0f6fc); padding: 10px 15px; border-radius: 6px; border: 1px solid #2271b1;">
                        <div style="font-size: 12px; color: var(--sf-gray-500, #646970); margin-bottom: 3px;"><?php esc_html_e('Current version', 'seo-fury'); ?></div>
                        <div style="font-size: 20px; font-weight: 600; color: #2271b1;"><?php echo esc_html(SEO_FURY_VERSION); ?></div>
                    </div>
                </div>

                <?php if (empty($changelog_data)): ?>
                    <div style="text-align: center; padding: 40px 20px; color: var(--sf-gray-500, #646970);">
                        <span class="dashicons dashicons-warning" style="font-size: 40px; width: 40px; height: 40px; margin-bottom: 10px;"></span>
                        <p><?php esc_html_e('Unable to load changelog. Please check your internet connection.', 'seo-fury'); ?></p>
                        <button type="button" class="button" onclick="location.reload();"><?php esc_html_e('Retry', 'seo-fury'); ?></button>
                    </div>
                <?php else: ?>
                    <?php foreach ($changelog_data as $version => $data): ?>
                        <div class="changelog-version" style="margin-bottom: 30px; padding: 20px; background: var(--sf-gray-100, #f6f7f7); border-left: 4px solid #2271b1; border-radius: 4px;">
                            <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 15px;">
                                <h3 style="margin: 0; font-size: 18px; color: #2271b1;">
                                    <span class="dashicons dashicons-tag" style="font-size: 18px;"></span>
                                    <?php
                                    /* translators: %s: version number */
                                    printf(esc_html__('Version %s', 'seo-fury'), esc_html($version)); ?>
                                </h3>
                                <span style="background: var(--sf-white, #fff); padding: 5px 12px; border-radius: 4px; font-size: 13px; color: var(--sf-gray-500, #646970);">
                                    <?php echo esc_html(wp_date('d.m.Y', strtotime($data['date']))); ?>
                                </span>
                            </div>

                            <?php if (isset($data['changes']['added']) && !empty($data['changes']['added'])): ?>
                                <div style="margin-bottom: 15px;">
                                    <h4 style="margin: 0 0 10px 0; font-size: 14px; color: #00a32a;">
                                        <span class="dashicons dashicons-plus" style="font-size: 16px;"></span>
                                        <?php esc_html_e('Added', 'seo-fury'); ?>
                                    </h4>
                                    <ul style="margin: 0; padding-left: 25px;">
                                        <?php foreach ($data['changes']['added'] as $item): ?>
                                            <li style="margin-bottom: 5px;"><?php echo esc_html($item); ?></li>
                                        <?php endforeach; ?>
                                    </ul>
                                </div>
                            <?php endif; ?>

                            <?php if (isset($data['changes']['improved']) && !empty($data['changes']['improved'])): ?>
                                <div style="margin-bottom: 15px;">
                                    <h4 style="margin: 0 0 10px 0; font-size: 14px; color: #2271b1;">
                                        <span class="dashicons dashicons-arrow-up-alt" style="font-size: 16px;"></span>
                                        <?php esc_html_e('Improved', 'seo-fury'); ?>
                                    </h4>
                                    <ul style="margin: 0; padding-left: 25px;">
                                        <?php foreach ($data['changes']['improved'] as $item): ?>
                                            <li style="margin-bottom: 5px;"><?php echo esc_html($item); ?></li>
                                        <?php endforeach; ?>
                                    </ul>
                                </div>
                            <?php endif; ?>

                            <?php if (isset($data['changes']['fixed']) && !empty($data['changes']['fixed'])): ?>
                                <div>
                                    <h4 style="margin: 0 0 10px 0; font-size: 14px; color: #d63638;">
                                        <span class="dashicons dashicons-dismiss" style="font-size: 16px;"></span>
                                        <?php esc_html_e('Fixed', 'seo-fury'); ?>
                                    </h4>
                                    <ul style="margin: 0; padding-left: 25px;">
                                        <?php foreach ($data['changes']['fixed'] as $item): ?>
                                            <li style="margin-bottom: 5px;"><?php echo esc_html($item); ?></li>
                                        <?php endforeach; ?>
                                    </ul>
                                </div>
                            <?php endif; ?>
                        </div>
                    <?php endforeach; ?>
                <?php endif; ?>
            </div>
        </div>
<?php
    }

    private function get_changelog_data() {
        $cache_key = 'seo_fury_changelog_data';

        // Allow force refresh via query parameter
        $force_refresh = isset($_GET['refresh_changelog']) && current_user_can('manage_options');

        if (!$force_refresh) {
            $cached = get_transient($cache_key);
            if (is_array($cached) && !empty($cached)) {
                return $cached;
            }
        }

        // Try fetching from remote API
        $url = 'https://seo-fury.com/api/changelog.json';
        $response = wp_remote_get($url, array(
            'timeout' => 15,
            'sslverify' => true,
            'user-agent' => 'SEO Fury/' . SEO_FURY_VERSION . ' (WordPress/' . get_bloginfo('version') . ')',
        ));

        if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
            $body = wp_remote_retrieve_body($response);
            $data = json_decode($body, true);
            if (is_array($data) && !empty($data)) {
                set_transient($cache_key, $data, 6 * HOUR_IN_SECONDS);
                update_option('seo_fury_changelog_fallback', $data, false);
                return $data;
            }
        }

        // Fallback to stored data
        $fallback = get_option('seo_fury_changelog_fallback', array());
        if (is_array($fallback) && !empty($fallback)) {
            return $fallback;
        }

        // Last resort: bundled changelog
        return $this->get_bundled_changelog();
    }

    private function get_bundled_changelog() {
        return array(
            '0.4.15' => array(
                'date' => '2026-03-07',
                'changes' => array(
                    'added' => array(
                        'Italian (it_IT) translation — 2,840 strings fully translated',
                        'Portuguese – Brazil (pt_BR) translation — 2,840 strings fully translated',
                    ),
                    'improved' => array(
                        'Plugin now ships with 6 complete translations: English, Russian, German, French, Spanish, Italian, and Portuguese (BR)',
                    ),
                ),
            ),
            '0.4.14' => array(
                'date' => '2026-03-05',
                'changes' => array(
                    'added' => array(
                        'Self-hosted auto-update system with fallback servers and license-based authentication',
                        'Free license key banner with registration prompt on plugin pages',
                        '"Get Free Key" block in License tab with link to dashboard',
                        'Breadcrumb shortcode aliases: [rank_math_breadcrumb], [wpseo_breadcrumb], [seopress_breadcrumbs], [bcn_display], [aioseo_breadcrumbs]',
                    ),
                    'improved' => array(
                        'Title rendering: 15+ new template variables (%page%, %pagenumber%, %pagetotal%, %currentyear%, %currentmonth%, %currentday%, %currentdate%, %currenttime%)',
                        'Homepage title: per-post custom title now takes priority over global template',
                        'Plugin description expanded with full feature list',
                        'Pricing/tariff descriptions updated with detailed feature comparisons for all 5 plans',
                    ),
                    'fixed' => array(
                        'Gutenberg sidebar React Error #130: PluginSidebar compatibility with WP 5.x – 6.6+',
                        'Gutenberg sidebar icon changed from search to lightning bolt',
                        'Elementor "Update" button not activating when SEO fields are changed',
                        'Rank Math migration: robots.txt import from nested options array',
                        'Rank Math migration: %pt_single% and %search_query% tag conversion typos',
                        'Title rendering: unreplaced variables (%sep%, %sitename%, %page%) in title tag',
                        'Migration wizard: SSL plugin detection and deactivation suggestion',
                    ),
                ),
            ),
            '0.3.0' => array(
                'date' => '2026-02-27',
                'changes' => array(
                    'added' => array(
                        'AI Search Traffic: Track visits from AI search engines (ChatGPT, Perplexity, Gemini, Copilot, Claude, You.com, Phind, Kagi) with dashboard, charts, and source/page analytics (PRO)',
                        'Backlink Checker: Monitor backlink profile via Ahrefs, Moz, DataForSEO, or Majestic APIs with domain metrics (DR/DA/TF/CF), anchor distribution, referring domains, and new/lost reports (PRO)',
                        'GSC Reports: Historical Google Search Console data storage with daily snapshots, period comparison, performance charts, and up to 365 days history (PRO)',
                        'Keyword Change Tracking: Automatic detection of gained and lost keywords over time with visual trend charts',
                        'GSC Auto-Sync: Automatic daily keyword import from Google Search Console into Rank Tracker (Free: 100 keywords, PRO: 2,000 keywords)',
                        'Site Verification: HTML meta tag verification for Google, Bing, Yandex, Baidu, Pinterest, and custom services',
                        'Webmasters Tab: Unified tab with subtabs for Site Verification, Google Search Console, and GSC Reports',
                    ),
                    'improved' => array(
                        'Rank Tracker redesigned: replaced SERP scraping with external API providers (SerpApi, DataForSEO, XMLStock, ValueSERP, SpaceSERP) + free GSC data source',
                        'PRO Limits system: tiered keyword limits (Free: 100, PRO: 2,000) and GSC history limits (Free: 7 days, PRO: 365 days)',
                        'Google Analytics: Proxy tracking mode label updated — recommended for countries with GA blocking (Russia, China)',
                        'Module layout: Statistics shown first, Settings and How It Works sections collapsed at bottom for better UX',
                        'Translations: 175+ new strings translated to Russian, German, French, and Spanish',
                    ),
                ),
            ),
            '0.2.2' => array(
                'date' => '2026-02-22',
                'changes' => array(
                    'added' => array(
                        'SEO Audit: Comprehensive 40+ check site audit based on Google ranking factors (Panda, E-E-A-T, Core Web Vitals, NavBoost)',
                        'Broken Links: Full-site broken link checker with scheduled scanning, email notifications, and batch processing',
                        'Content Decay: Stale content detection with decay score, email alerts, and "Mark as Reviewed" workflow',
                        'Link Assistant: Internal linking analysis with orphaned content detection and link graph',
                        'Rank Tracker: Keyword position tracking across Google, Bing, Yahoo with trend history and charts',
                        'Google Search Console: OAuth 2.0 integration with search performance data (impressions, clicks, CTR, position)',
                        'Google Analytics: GA4 integration with measurement ID, tracking code, and admin dashboard widget',
                    ),
                    'improved' => array(
                        'Sidebar navigation reorganized with visual group headers for easier navigation',
                        'Plugin menu icon changed from magnifying glass to lightning bolt',
                        'Fixed duplicate dashicon usage across sidebar tabs (Meta Titles, .htaccess, AI Keys, License)',
                        'Tabs reordered into logical groups: General, Content & Links, AI Tools, Technical SEO, Indexing & Analytics, System',
                    ),
                ),
            ),
            '0.2.1' => array(
                'date' => '2026-02-21',
                'changes' => array(
                    'added' => array(
                        'Page Speed: Google PageSpeed Insights API integration with Core Web Vitals scores and history',
                        'LLMs.txt: AI crawler discovery files (/llms.txt, /llms-full.txt) for AI model access control',
                        'AI Image Generator: Generate images with DALL-E 3, Stable Diffusion, Google Imagen, Flux Pro (PRO)',
                        'AI SEO Text Generator: Auto-generate meta titles, descriptions, alt text using AI providers (PRO)',
                        'Auto-Redirect: Automatic 301 redirect creation when post/page URL slug changes',
                        'SEO Revisions: Version control for SEO metadata with diff viewer and one-click restore (last 20 revisions)',
                        'Frontend SEO Inspector: Admin bar button to inspect SEO data in real-time on frontend pages',
                        'Migration Wizard: One-click data import from Yoast SEO, Rank Math, All in One SEO, SEOPress',
                    ),
                    'improved' => array(
                        'Shortcode variables system centralized in dedicated class with support for all page types',
                        'AI providers now share centralized API keys from AI Keys module',
                    ),
                ),
            ),
            '0.2.0' => array(
                'date' => '2026-02-15',
                'changes' => array(
                    'added' => array(
                        'Import/Export: Full plugin settings backup and restore via JSON (excludes API keys and license data)',
                        'Encryption: AES-256 encryption for all sensitive data (API keys, OAuth tokens)',
                        'Integrity Verification: SHA-256 file hash manifest with tampering detection',
                        'Plugin Language Override: Change plugin language independently from WordPress site language',
                        'Uninstall Dialog: Interactive modal on plugin deletion with option to keep or remove all data',
                    ),
                    'improved' => array(
                        'Early textdomain loading to prevent WP 6.7+ _load_textdomain_just_in_time warnings',
                        'Duplicate plugin activation detection and auto-deactivation',
                    ),
                ),
            ),
            '0.1.9' => array(
                'date' => '2026-02-14',
                'changes' => array(
                    'added' => array(
                        'AI API Keys: GPT-5.2 series (Thinking, Instant, Pro) added to OpenAI models',
                        'AI API Keys: Gemini 3 Pro and Gemini 3 Flash added to Google models',
                        'AI API Keys: o3, o3 Pro, o4 Mini reasoning models added to OpenAI',
                        'Robots.txt: Per-bot rule presets with quick-add buttons (Googlebot, Yandex, Bingbot, Baiduspider, DuckDuckBot)',
                        'Robots.txt: Comprehensive default template with Googlebot, Yandex, Bingbot sections',
                        'Sitemap: Cache auto-invalidation when sitemap settings change',
                    ),
                    'improved' => array(
                        'AI API Keys: Updated Mistral models (Codestral, Mistral Saba)',
                        'AI API Keys: Updated DeepSeek model labels (V3, R1)',
                        'Indexing: Google Indexing API and IndexNow merged into unified Indexing tab with sub-tabs',
                        'Indexing: Google Indexing API now available in Free plan (removed PRO restriction)',
                        'Indexing: Combined submission history view with system column',
                        'Woo AI: Replaced standalone API key input with centralized AI provider selector',
                    ),
                    'fixed' => array(
                        'Sitemap: Fixed empty urlset when post type has noindex — now returns 404 correctly',
                        'Sitemap: Noindex post types excluded from sitemap index',
                        'Sitemap: Fixed nested array sanitization for post type priority/changefreq settings',
                        'URL Transliteration: Fixed not working in Gutenberg (removed REST API guard)',
                        'General Settings: Fixed save button disabled by white-label PRO overlay div',
                    ),
                ),
            ),
            '0.1.8' => array(
                'date' => '2026-02-10',
                'changes' => array(
                    'added' => array(
                        'SERP Preview: Real-time Google search result preview with desktop and mobile modes',
                        'Social Preview: Facebook and Twitter/X card preview with image support',
                        'Taxonomy Robots Meta: Per-taxonomy noindex, nofollow, noarchive settings',
                        'AI API Keys: Centralized API key management for 5 AI providers with AES-256 encryption',
                        '.htaccess Editor: Visual editor with syntax highlighting and backup/restore',
                        'News Sitemap: Google News compatible sitemap with publication name and language',
                        'Video Sitemap: Automatic video detection from YouTube/Vimeo embeds',
                        'Google Indexing API: Submit URLs directly to Google via Indexing API with JSON key auth',
                        'Sitemap Ping: Automatic Google ping on post save with manual ping button',
                    ),
                    'improved' => array(
                        'Breadcrumbs: Localized labels for Home, Search, 404, and archive pages',
                        'Breadcrumbs: 404 page breadcrumb trail support',
                        'Robots.txt: Modern default template with expanded crawl rules',
                        'Full code audit: sanitize_callback added to all 125 register_setting() calls',
                        'Security: All user inputs properly sanitized and escaped',
                    ),
                    'fixed' => array(
                        'Fixed 21+ PHP issues identified in code audit',
                        'Fixed Gutenberg modal rendering — modals now render in admin_footer',
                        'Fixed shortcode dropdown CSS conflicts in admin settings',
                    ),
                ),
            ),
            '0.1.7' => array(
                'date' => '2026-02-08',
                'changes' => array(
                    'added' => array(
                        'Breadcrumbs: Separate Search Format setting for search results pages',
                    ),
                    'improved' => array(
                        'Breadcrumbs: Archive Format description clarified to reflect actual functionality',
                        'Breadcrumbs: Category and tag archives now use term name directly, avoiding WordPress HTML wrapper issues',
                    ),
                    'fixed' => array(
                        'Breadcrumbs: Archive Format now correctly applies to archive pages instead of search results',
                        'Breadcrumbs: Parent categories now display in breadcrumb trail on category archive pages',
                        'Breadcrumbs: Fixed raw <span> HTML tag appearing when Hide Taxonomy Name is enabled',
                        'Breadcrumbs: Custom separator input now appears inline next to the dropdown instead of below it',
                    ),
                ),
            ),
            '0.1.6' => array(
                'date' => '2026-02-08',
                'changes' => array(
                    'added' => array(
                        'Full translations: Russian (ru_RU), German (de_DE), French (fr_FR), Spanish (es_ES)',
                        'Compiled .mo files for all 4 languages',
                        'Plugin language follows WordPress site language setting',
                    ),
                    'improved' => array(
                        'All UI strings wrapped in i18n functions for proper localization',
                        'Internationalized remaining hardcoded strings in JS and PHP files',
                        'Updated .pot template with 945 translatable strings',
                    ),
                    'fixed' => array(
                        'Fixed integrity check triggering false positive after plugin file updates',
                    ),
                ),
            ),
            '0.1.5' => array(
                'date' => '2026-02-08',
                'changes' => array(
                    'added' => array(
                        'Internal Linking module (PRO) — smart link suggestions in post editor',
                        'SSL / HTTPS Security module — separate admin tab with status dashboard',
                        'Force HTTPS redirect with 301',
                        'Mixed content auto-fix',
                        'HSTS header support with configurable max-age',
                        'WWW / non-WWW canonical redirect',
                        '404 Monitor CSV export',
                        'Sitemap Additional URLs per-URL priority and changefreq settings (PRO)',
                    ),
                    'improved' => array(
                        'Internal linking now uses case-insensitive matching with Cyrillic support',
                        'Changelog now loads remotely from website — single source of truth',
                        '404 CSV export simplified to essential columns',
                        'Cleaned all PHP and JavaScript comments from codebase',
                        'Translated all remaining Russian strings to English',
                    ),
                    'fixed' => array(
                        'Fixed parse_shortcodes() private method visibility error',
                        'Fixed Gutenberg sidebar metabox not displaying (CSS display:none override)',
                        'Fixed internal linking not matching single-word Cyrillic titles',
                    ),
                ),
            ),
            '0.1.4' => array(
                'date' => '2026-01-17',
                'changes' => array(
                    'added' => array(
                        'Rebuilt Meta Titles module with Rank Math-style content type navigation',
                        'Added templates for home, blog, author, search, date, 404, taxonomies, and post types',
                        'Enabled meta description templates for non-singular pages',
                    ),
                    'improved' => array(
                        'Translated remaining admin UI strings across IndexNow, 404, license, and social meta',
                        'Refined sitemap UI and XSL output to English',
                    ),
                    'fixed' => array(
                        'White label now hides pricing links when branding is disabled',
                        'Standardized branding labels to avoid SEO Fury mentions in UI',
                    ),
                ),
            ),
            '0.1.3' => array(
                'date' => '2026-01-17',
                'changes' => array(
                    'added' => array(
                        'Introduced Rank Math-style Gutenberg sidebar with compact tabs and modals',
                        'Added Schema Generator modal with multi-item list and edit/remove actions',
                        'Added social settings modal with left/right layout and nested tabs',
                        'Added JSON-LD import detection to map schema types automatically',
                    ),
                    'improved' => array(
                        'Improved Google preview and snippet editor layout inside the modal',
                        'Refined SEO and readability analysis UI with compact meters',
                        'Updated schema output to support multiple items and custom JSON-LD',
                        'Enhanced modal stacking and overlay behavior in Gutenberg',
                    ),
                    'fixed' => array(
                        'Fixed schema edit actions not opening focused settings',
                        'Fixed schema settings not persisting in Gutenberg sidebar saves',
                        'Fixed duplicate schema types (except custom JSON-LD)',
                    ),
                ),
            ),
            '0.1.2' => array(
                'date' => '2026-01-15',
                'changes' => array(
                    'added' => array(
                        'Added Schema Markup module with support for 13+ structured data types',
                        'New schema types: Article, Product, Review, Recipe, FAQ, How-To, Event, Video, and more',
                        'Implemented JSON-LD generation system for rich snippets',
                        'Added Schema tab to post editor',
                        'Schema JSON-LD preview feature',
                    ),
                    'improved' => array(
                        'Fully translated post editor interface to English',
                        'Improved tab structure: SEO Basics, Advanced, Schema, Social Media',
                        'Added icons to all tabs for better navigation',
                        'Optimized metadata saving system',
                        'Improved wp_head integration for structured data output',
                    ),
                ),
            ),
            '0.1.1' => array(
                'date' => '2026-01-10',
                'changes' => array(
                    'added' => array(
                        'Added Changelog page',
                        'Added PRO feature to block web archive bots',
                        'Improved plugin menu structure',
                    ),
                    'improved' => array(
                        'Unified visual style across all modules',
                        'Improved PRO features and limits display',
                        'Optimized navigation between sections',
                    ),
                ),
            ),
            '0.1.0' => array(
                'date' => '2026-01-01',
                'changes' => array(
                    'added' => array(
                        'First release of the plugin',
                        'robots.txt management with dynamic variables',
                        'XML and HTML sitemap generation',
                        'Redirect manager (301, 302, 307) with hit tracking',
                        'IndexNow API integration',
                        '404 error monitoring and logging',
                        'Meta tags management (titles, descriptions, robots)',
                        'Open Graph and Twitter Card support',
                        'URL transliteration (Cyrillic to Latin)',
                        'Licensing system with Free and Pro plans',
                        'AI bots blocking via robots.txt (PRO)',
                        'White Label branding (PRO)',
                    ),
                ),
            ),
        );
    }

    /**
     * Enqueue the uninstall dialog script on the plugins.php page only.
     *
     * @param string $hook Current admin page hook suffix.
     */
    public function enqueue_uninstall_dialog($hook)
    {
        if ($hook !== 'plugins.php') {
            return;
        }

        if (!current_user_can('delete_plugins')) {
            return;
        }

        wp_enqueue_script(
            'seo-fury-uninstall-dialog',
            SEO_FURY_URL . 'assets/uninstall-dialog.js',
            array('jquery'),
            SEO_FURY_VERSION,
            true
        );

        $plugin_name = function_exists('seo_fury_get_brand_name') ? seo_fury_get_brand_name() : 'SEO Fury';

        wp_localize_script('seo-fury-uninstall-dialog', 'seoFuryUninstall', array(
            'ajaxUrl'    => admin_url('admin-ajax.php'),
            'nonce'      => wp_create_nonce('seo_fury_delete_preference'),
            'pluginSlug' => plugin_basename(SEO_FURY_PATH . 'seo-fury.php'),
            'i18n'       => array(
                'title'       => sprintf(
                    /* translators: %s: plugin name */
                    __('Delete %s', 'seo-fury'),
                    $plugin_name
                ),
                'subtitle'    => __('What would you like to do with the plugin data stored in your database?', 'seo-fury'),
                'keepTitle'   => __('Keep all data and delete plugin files only', 'seo-fury'),
                'keepDesc'    => __('All your SEO settings, meta titles, descriptions, schemas, and redirects will be preserved in the database. This is the best option if you plan to reinstall or want to protect your SEO configuration.', 'seo-fury'),
                'deleteTitle' => __('Completely delete everything including database data', 'seo-fury'),
                'deleteDesc'  => __('All plugin settings, post meta, custom tables, and transients will be permanently removed from the database. This cannot be undone.', 'seo-fury'),
                'recommended' => __('Recommended', 'seo-fury'),
                'cancel'      => __('Cancel', 'seo-fury'),
                'confirm'     => __('Delete Plugin', 'seo-fury'),
                'processing'  => __('Processing...', 'seo-fury'),
            ),
        ));
    }

    /**
     * AJAX handler: save the user's delete-data preference before plugin deletion.
     */
    public function ajax_set_delete_preference()
    {
        check_ajax_referer('seo_fury_delete_preference', 'nonce');

        if (!current_user_can('delete_plugins')) {
            wp_send_json_error('Unauthorized', 403);
        }

        $delete_data = isset($_POST['delete_data']) ? absint($_POST['delete_data']) : 0;
        update_option('seo_fury_delete_data', $delete_data ? 1 : 0, false);

        wp_send_json_success();
    }

    /**
     * Show a dismissible admin notice suggesting PRO upgrade.
     * Appears only on SEO Fury settings pages, once per 30 days after dismissal.
     */
    public function maybe_show_pro_upgrade_notice()
    {
        // Only show on our plugin pages
        $screen = get_current_screen();
        if (!$screen || strpos($screen->id, 'seo-fury') === false) {
            return;
        }

        // Don't show when PRO is already active
        if (apply_filters('seo_fury_is_pro', false)) {
            return;
        }

        // Check if dismissed
        $dismissed_until = get_option('seo_fury_pro_notice_dismissed', 0);
        if ($dismissed_until && time() < (int) $dismissed_until) {
            return;
        }

        // Don't show in the first 3 days after plugin activation
        $activated = get_option('seo_fury_activated_at', 0);
        if (!$activated) {
            update_option('seo_fury_activated_at', time(), false);
            return;
        }
        if (time() - (int) $activated < 3 * DAY_IN_SECONDS) {
            return;
        }

        $pricing_url   = 'https://seo-fury.com/#pricing';
        $dashboard_url = 'https://dashboard.seo-fury.com/dashboard/my-licenses';
        ?>
        <div class="notice notice-info is-dismissible seo-fury-pro-notice" style="border-left-color:#4F46E5;padding:12px 16px;">
            <div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;">
                <span style="font-size:24px;">&#9889;</span>
                <div style="flex:1;min-width:200px;">
                    <strong><?php esc_html_e('Unlock 20+ Advanced SEO Features', 'seo-fury'); ?></strong>
                    <p style="margin:4px 0 0;color:var(--sf-gray-500, #555);font-size:13px;">
                        <?php esc_html_e('Get Google Analytics, Rank Tracker, AI Content, Backlink Checker, SEO Audit, and more with SEO Fury PRO.', 'seo-fury'); ?>
                    </p>
                </div>
                <div style="display:flex;gap:8px;">
                    <a href="<?php echo esc_url($pricing_url); ?>" target="_blank" class="button button-primary" style="text-decoration:none;">
                        <?php esc_html_e('Get PRO', 'seo-fury'); ?>
                    </a>
                    <a href="<?php echo esc_url($dashboard_url); ?>" target="_blank" class="button" style="text-decoration:none;">
                        <?php esc_html_e('I have a license', 'seo-fury'); ?>
                    </a>
                </div>
            </div>
            <script>
            jQuery(function($){
                $(document).on('click', '.seo-fury-pro-notice .notice-dismiss', function(){
                    $.post(ajaxurl, {action:'seo_fury_dismiss_pro_notice', _wpnonce:'<?php echo esc_attr(wp_create_nonce('seo_fury_dismiss_pro')); ?>'});
                });
            });
            </script>
        </div>
        <?php
    }

    /**
     * AJAX handler: dismiss PRO notice for 30 days.
     */
    public function ajax_dismiss_pro_notice()
    {
        check_ajax_referer('seo_fury_dismiss_pro', '_wpnonce');
        // Dismiss for 30 days
        update_option('seo_fury_pro_notice_dismissed', time() + 30 * DAY_IN_SECONDS, false);
        wp_send_json_success();
    }

    /**
     * Detect other active SEO plugins that would output duplicate meta tags,
     * canonical, sitemaps, etc. alongside SEO Fury.
     *
     * @return string[] Human-readable names of conflicting plugins.
     */
    private function get_conflicting_seo_plugins()
    {
        $known = array(
            'wordpress-seo/wp-seo.php'                       => 'Yoast SEO',
            'wordpress-seo-premium/wp-seo-premium.php'       => 'Yoast SEO Premium',
            'seo-by-rank-math/rank-math.php'                 => 'Rank Math',
            'seo-by-rank-math-pro/rank-math-pro.php'         => 'Rank Math PRO',
            'all-in-one-seo-pack/all_in_one_seo_pack.php'    => 'All in One SEO',
            'all-in-one-seo-pack-pro/all_in_one_seo_pack.php' => 'All in One SEO Pro',
            'wp-seopress/seopress.php'                       => 'SEOPress',
            'wp-seopress-pro/seopress-pro.php'               => 'SEOPress Pro',
            'autodescription/autodescription.php'            => 'The SEO Framework',
        );

        $active = (array) get_option('active_plugins', array());
        if (is_multisite()) {
            $active = array_merge($active, array_keys((array) get_site_option('active_sitewide_plugins', array())));
        }

        $found = array();
        foreach ($known as $file => $name) {
            if (in_array($file, $active, true)) {
                $found[] = $name;
            }
        }
        return $found;
    }

    public function maybe_show_conflict_notice()
    {
        $screen = get_current_screen();
        if (!$screen || strpos($screen->id, 'seo-fury') === false) {
            return;
        }

        $dismissed_until = get_option('seo_fury_conflict_notice_dismissed', 0);
        if ($dismissed_until && time() < (int) $dismissed_until) {
            return;
        }

        $conflicts = $this->get_conflicting_seo_plugins();
        if (empty($conflicts)) {
            return;
        }

        $list = implode(', ', array_map('esc_html', $conflicts));
        ?>
        <div class="notice notice-warning is-dismissible seo-fury-conflict-notice" style="border-left-color:#d97706;padding:12px 16px;">
            <p style="margin:0 0 4px;"><strong><?php esc_html_e('Another SEO plugin is active', 'seo-fury'); ?></strong></p>
            <p style="margin:0;color:var(--sf-gray-500, #555);font-size:13px;">
                <?php
                /* translators: %s: comma-separated list of plugin names */
                printf(esc_html__('SEO Fury detected: %s. Running two SEO plugins at once usually produces duplicate meta tags, canonical URLs, and sitemaps, which can hurt your rankings. Keep only one active.', 'seo-fury'), '<strong>' . $list . '</strong>'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $list is esc_html'd per item above.
                ?>
            </p>
            <script>
            jQuery(function($){
                $(document).on('click', '.seo-fury-conflict-notice .notice-dismiss', function(){
                    $.post(ajaxurl, {action:'seo_fury_dismiss_conflict_notice', _wpnonce:'<?php echo esc_attr(wp_create_nonce('seo_fury_dismiss_conflict')); ?>'});
                });
            });
            </script>
        </div>
        <?php
    }

    /**
     * AJAX handler: dismiss the conflict notice for 30 days.
     */
    public function ajax_dismiss_conflict_notice()
    {
        check_ajax_referer('seo_fury_dismiss_conflict', '_wpnonce');
        update_option('seo_fury_conflict_notice_dismissed', time() + 30 * DAY_IN_SECONDS, false);
        wp_send_json_success();
    }

    /**
     * Render the "Get PRO" submenu page with feature comparison and install button.
     */
    public function render_get_pro_page()
    {
        $pricing_url   = 'https://seo-fury.com/#pricing';
        $dashboard_url = 'https://dashboard.seo-fury.com/dashboard/my-licenses';

        $pro_features = array(
            __('Google Analytics integration', 'seo-fury'),
            __('Yandex Metrika integration', 'seo-fury'),
            __('Bing UET / Custom analytics', 'seo-fury'),
            __('Rank Tracker — keyword position monitoring', 'seo-fury'),
            __('Index Tracker — Google index status checker', 'seo-fury'),
            __('Google Search Console reports', 'seo-fury'),
            __('Google Indexing API (bulk URL submissions)', 'seo-fury'),
            __('AI Content Generator (articles, meta, images)', 'seo-fury'),
            __('AI SEO Text — auto content optimization', 'seo-fury'),
            __('AI Image Generator', 'seo-fury'),
            __('AI Search Traffic analysis', 'seo-fury'),
            __('SEO Audit — full site health check', 'seo-fury'),
            __('SEO Images — bulk alt/title optimization', 'seo-fury'),
            __('Backlink Checker', 'seo-fury'),
            __('Broken Link Checker', 'seo-fury'),
            __('Link Assistant — internal linking suggestions', 'seo-fury'),
            __('Content Decay — detect declining pages', 'seo-fury'),
            __('SEO Reports — PDF export', 'seo-fury'),
            __('White Label branding', 'seo-fury'),
            __('Priority support', 'seo-fury'),
            __('Unlimited redirects & 404 logs', 'seo-fury'),
        );
        ?>
        <div class="wrap">
            <h1><?php esc_html_e('Upgrade to SEO Fury PRO', 'seo-fury'); ?></h1>

            <div style="max-width:900px;margin-top:20px;">
                <!-- Hero card -->
                <div style="background:linear-gradient(135deg,#4F46E5 0%,#7C3AED 100%);color:#fff;padding:40px;border-radius:12px;margin-bottom:24px;">
                    <h2 style="color:#fff;font-size:28px;margin:0 0 12px;">&#9889; <?php esc_html_e('Unlock the Full Power of SEO Fury', 'seo-fury'); ?></h2>
                    <p style="font-size:16px;opacity:.9;margin:0 0 24px;max-width:600px;">
                        <?php esc_html_e('Get 20+ advanced features including Google Analytics, Rank Tracker, AI Content Generator, Backlink Checker, and more.', 'seo-fury'); ?>
                    </p>
                    <div style="display:flex;gap:12px;flex-wrap:wrap;">
                        <a href="<?php echo esc_url($pricing_url); ?>" target="_blank"
                           style="display:inline-block;padding:14px 32px;background:#F59E0B;color:#fff;font-weight:700;font-size:15px;border-radius:8px;text-decoration:none;">
                            <?php esc_html_e('View Pricing Plans', 'seo-fury'); ?>
                        </a>
                        <a href="<?php echo esc_url($dashboard_url); ?>" target="_blank"
                           style="display:inline-block;padding:14px 32px;background:rgba(255,255,255,.2);color:#fff;font-weight:600;font-size:15px;border-radius:8px;text-decoration:none;border:1px solid rgba(255,255,255,.4);">
                            <?php esc_html_e('I already have a license → Download PRO', 'seo-fury'); ?>
                        </a>
                    </div>
                </div>

                <!-- Features grid -->
                <div style="background:var(--sf-white, #fff);border:1px solid var(--sf-gray-200, #e2e8f0);border-radius:12px;padding:30px;">
                    <h3 style="font-size:18px;margin:0 0 20px;">
                        <?php esc_html_e('PRO Features', 'seo-fury'); ?>
                    </h3>
                    <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px 24px;">
                        <?php foreach ($pro_features as $feature) : ?>
                            <div style="display:flex;align-items:center;gap:8px;padding:6px 0;">
                                <span style="color:#10B981;font-size:16px;">&#10003;</span>
                                <span style="font-size:14px;color:var(--sf-gray-700, #334155);"><?php echo esc_html($feature); ?></span>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>

                <!-- Installation steps -->
                <div style="background:#FFFBEB;border:1px solid #FDE68A;border-radius:12px;padding:24px;margin-top:24px;">
                    <h3 style="font-size:16px;margin:0 0 16px;">
                        &#128161; <?php esc_html_e('How to install PRO addon', 'seo-fury'); ?>
                    </h3>
                    <ol style="margin:0;padding-left:20px;line-height:2;font-size:14px;">
                        <li><?php esc_html_e('Purchase a PRO license at seo-fury.com', 'seo-fury'); ?></li>
                        <li><?php esc_html_e('Download the PRO addon ZIP from your dashboard', 'seo-fury'); ?></li>
                        <li><?php
                        /* translators: %1$s: opening strong tag, %2$s: closing strong tag */
                        echo wp_kses_post( sprintf( __('In WordPress: %1$sPlugins → Add New → Upload Plugin%2$s → select the ZIP', 'seo-fury'), '<strong>', '</strong>' ) ); ?></li>
                        <li><?php esc_html_e('Activate it — your license key will be detected automatically', 'seo-fury'); ?></li>
                    </ol>
                </div>
            </div>
        </div>
        <?php
    }

    /**
     * Render a PRO feature upsell box for tabs/subtabs that require PRO.
     *
     * @param string $feature_name  Human-readable feature name.
     * @param string $description   Feature description.
     */
    private function render_pro_feature_upsell($feature_name, $description)
    {
        $pricing_url  = 'https://seo-fury.com/#pricing';
        $dashboard_url = 'https://dashboard.seo-fury.com/dashboard/my-licenses';
        ?>
        <div style="max-width:700px;margin:30px auto;text-align:center;padding:40px 30px;background:linear-gradient(135deg,#EEF2FF 0%,#F5F3FF 100%);border:1px solid #C7D2FE;border-radius:12px;">
            <div style="font-size:48px;margin-bottom:16px;">&#9889;</div>
            <h3 style="font-size:22px;color:var(--sf-gray-900, #1e293b);margin-bottom:8px;">
                <?php echo esc_html($feature_name); ?> — <?php esc_html_e('PRO Feature', 'seo-fury'); ?>
            </h3>
            <p style="color:var(--sf-gray-500, #64748b);font-size:14px;max-width:500px;margin:0 auto 20px;">
                <?php echo esc_html($description); ?>
            </p>
            <p style="margin-bottom:24px;">
                <a href="<?php echo esc_url($pricing_url); ?>" target="_blank"
                   class="button button-primary button-hero" style="text-decoration:none;">
                    <?php esc_html_e('Get PRO License', 'seo-fury'); ?>
                </a>
            </p>
            <p style="font-size:12px;color:var(--sf-gray-400, #94a3b8);">
                <?php esc_html_e('Already have a PRO license?', 'seo-fury'); ?>
                <a href="<?php echo esc_url($dashboard_url); ?>" target="_blank" style="color:#4F46E5;">
                    <?php esc_html_e('Download the PRO addon from your dashboard', 'seo-fury'); ?>
                </a>
            </p>
        </div>
        <?php
    }

}
