<?php

namespace WPSN\Admin;

use WPSN\Core\Container;
use WPSN\Core\Capabilities;
use WPSN\Core\Settings;
use WPSN\Core\ModuleRegistry;
use WPSN\Core\UI;
use WPSN\Modules\AI\AISecretsRepository;
use WPSN\Modules\AI\AICreditsRepository;
use WPSN\Modules\AI\OpenAIClient;
use WPSN\Modules\IndexNow\IndexNowSecretsRepository;
use WPSN\Modules\HeadCleanup\HeadCleanupProfile;
use WPSN\Modules\Licensing\BillingSyncService;
use WPSN\Modules\Licensing\LicenseService;
use WPSN\Modules\Licensing\PlanMatrix;
use WPSN\Modules\SerpGap\SerpSecretsRepository;
use WPSN\Modules\Stability\ConfigSnapshotService;
use WPSN\SEO\SchemaTypeLibrary;

defined('ABSPATH') || exit;

final class SettingsPage
{
    private Container $container;
    private SettingsRepository $repo;
    private Settings $settings;
    private ModuleRegistry $modules;

    public function __construct(Container $container)
    {
        $this->container = $container;
        $this->repo      = $container->get('settings_repo');
        $this->settings  = $container->get('settings');
        $this->modules   = $container->get('modules');
    }

    public function render(): void
    {
        if (!Capabilities::canManageSettings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'wp-seo-next'));
        }

        // Stored per-site settings (used to preserve values when parts of the UI are disabled).
        $stored = $this->repo->getAll();

        // Effective settings (multisite network policies may override stored values at runtime).
        $data = $this->settings->all();
        $ai = isset($data['ai']) && is_array($data['ai']) ? $data['ai'] : [];
        $automation = isset($data['automation']) && is_array($data['automation']) ? $data['automation'] : [];
        $sc = isset($data['search_console']) && is_array($data['search_console']) ? $data['search_console'] : [];
        $privacy = isset($data['privacy']) && is_array($data['privacy']) ? $data['privacy'] : [];
        $audit = isset($data['audit']) && is_array($data['audit']) ? $data['audit'] : [];

        $indexnow = isset($data['indexnow']) && is_array($data['indexnow']) ? $data['indexnow'] : [];
        $configSync = isset($data['config_sync']) && is_array($data['config_sync']) ? $data['config_sync'] : [];
        $configSyncStored = isset($stored['config_sync']) && is_array($stored['config_sync']) ? $stored['config_sync'] : [];
        $locked = !empty($configSyncStored['lock_settings']);
        $whiteLabel = isset($data['white_label']) && is_array($data['white_label']) ? $data['white_label'] : [];

        $serpGap = isset($data['serp_gap']) && is_array($data['serp_gap']) ? $data['serp_gap'] : [];
        $serper = isset($serpGap['serper']) && is_array($serpGap['serper']) ? $serpGap['serper'] : [];

        $enforceModules = $this->settings->networkPolicyIsEnforced('modules');
        $enforceWhiteLabel = $this->settings->networkPolicyIsEnforced('white_label');
        $enforceIntegrations = $this->settings->networkPolicyIsEnforced('integrations');

        $secrets = new AISecretsRepository();
        $hasKey = $secrets->hasOpenAIKey();

        $serpSecrets = new SerpSecretsRepository();
        $hasSerperKey = $serpSecrets->hasSerperKey();

        $creditsRepo = new AICreditsRepository($this->settings);
        $creditsBalance = $creditsRepo->getBalance();

        $ui = isset($data['ui']) && is_array($data['ui']) ? $data['ui'] : [];
        $uiMode = sanitize_key((string) ($ui['mode'] ?? UI::MODE_SIMPLE));
        if (!in_array($uiMode, [UI::MODE_SIMPLE, UI::MODE_PRO], true)) {
            $uiMode = UI::MODE_SIMPLE;
        }
        $isProUi = ($uiMode === UI::MODE_PRO);

        $licenseService = new LicenseService($this->settings, $this->container->get('logger'));
        $billingSyncService = new BillingSyncService($this->settings, $this->container->get('logger'));
        $licenseEntitlements = $licenseService->entitlements();
        $currentPlanTier = PlanMatrix::detectCurrentPlan($licenseService->getCache(), $billingSyncService->getCache(), $licenseEntitlements);
        $licensingEnforced = $licenseService->enforceEntitlements();
        $licenseRuntimeTrusted = !$licenseService->requireSigned() || $licenseService->isTrusted();
        $licenseRuntimeReady = $licenseService->isActive() && $licenseRuntimeTrusted;


        ?>
        <div class="wrap wpsn-ui-mode-<?php echo esc_attr($uiMode); ?>">
            <?php
                $wlEnabled = !empty($whiteLabel['enabled']);
                $wlHide = !empty($whiteLabel['hide_branding']);
                $wlBrand = $wlEnabled ? trim((string) ($whiteLabel['brand_name'] ?? '')) : '';
                if ($wlBrand === '') {
                    // Avoid leaking vendor name if white-label is enabled and hide_branding is on.
                    $wlBrand = ($wlEnabled && $wlHide) ? __('SEO', 'wp-seo-next') : 'WP SEO Next';
                }
                $wlMenu = $wlEnabled ? trim((string) ($whiteLabel['menu_title'] ?? '')) : '';
                if ($wlMenu === '') {
                    $wlMenu = $wlBrand;
                }
                $wlHeading = $wlEnabled ? trim((string) ($whiteLabel['settings_heading'] ?? '')) : '';
                if ($wlHeading === '') {
                    $wlHeading = $wlMenu . ' — ' . __('Settings', 'wp-seo-next');
                }
            ?>
            <h1><?php echo esc_html($wlEnabled ? $wlHeading : __('WP SEO Next — Settings', 'wp-seo-next')); ?></h1>

            <style>
                .wpsn-ui-mode-simple .wpsn-ui-pro-only { display:none !important; }
                .wpsn-ui-mode-simple .wpsn-ui-pro-only * { visibility:hidden; }
                .wpsn-ui-mode-simple .wpsn-ui-pro-only { height:0; overflow:hidden; }
            </style>

            <?php
                $focusModule = isset($_GET['wpsn_focus_module']) ? sanitize_key((string) wp_unslash($_GET['wpsn_focus_module'])) : '';
                if (is_string($focusModule) && $focusModule !== '') :
            ?>
                <style>
                    .wpsn-focus-highlight{background:rgba(255,243,205,.55) !important;box-shadow:0 0 0 1px rgba(255,193,7,.35) inset;}
                </style>
                <script>(function(){
                    try {
                        document.addEventListener('DOMContentLoaded', function(){
                            var id = 'wpsn-module-' + <?php echo wp_json_encode($focusModule); ?>;
                            var el = document.getElementById(id);
                            if (!el) { return; }
                            el.classList.add('wpsn-focus-highlight');
                            el.scrollIntoView({behavior:'smooth', block:'center'});
                        });
                    } catch(e) {}
                })();</script>
            <?php endif; ?>

            <p style="margin: 6px 0 14px; opacity: .85;">
                <?php
                    $labelMode = ($uiMode === UI::MODE_PRO) ? __('Pro (advanced)', 'wp-seo-next') : __('Simple (recommended)', 'wp-seo-next');
                    printf(
                        /* translators: %s is UI mode */
                        esc_html__('Interface mode: %s. You can change it below.', 'wp-seo-next'),
                        '<strong>' . esc_html($labelMode) . '</strong>'
                    );
                ?>
                <a href="#wpsn-ui-mode" style="margin-left: 6px;">(<?php echo esc_html__('change', 'wp-seo-next'); ?>)</a>
            </p>

            <?php if (isset($_GET['wpsn_saved'])) : ?>
                <div class="notice notice-success is-dismissible"><p><?php echo esc_html__('Settings saved.', 'wp-seo-next'); ?></p></div>
            <?php endif; ?>


            <?php if (!empty($_GET['wpsn_locked'])) : ?>
                <div class="notice notice-warning is-dismissible"><p><?php echo esc_html__('Settings are locked by Config Sync. Your changes to settings were not applied (API keys can still be saved).', 'wp-seo-next'); ?></p></div>
            <?php endif; ?>

            <?php if (isset($_GET['wpsn_ai_override_cleared'])) : ?>
                <?php
                    $ok = ((string) wp_unslash($_GET['wpsn_ai_override_cleared']) === '1');
                    $uid = isset($_GET['wpsn_ai_override_user']) ? (int) $_GET['wpsn_ai_override_user'] : 0;
                    $msg = $ok
                        ? __('AI user override cleared.', 'wp-seo-next')
                        : __('No user override to clear.', 'wp-seo-next');
                    if ($uid > 0) {
                        $msg .= ' ' . sprintf(__('User ID: %d', 'wp-seo-next'), $uid);
                    }
                ?>
                <div class="notice <?php echo $ok ? 'notice-success' : 'notice-info'; ?> is-dismissible"><p><?php echo esc_html($msg); ?></p></div>
            <?php endif; ?>

            <?php if (!empty($_GET['wpsn_notice']) && sanitize_key((string) wp_unslash($_GET['wpsn_notice'])) === 'ai_overrides_cleared_all') : ?>
                <?php
                    $users = isset($_GET['wpsn_ai_overrides_users']) ? (int) $_GET['wpsn_ai_overrides_users'] : 0;
                    $use = isset($_GET['wpsn_ai_overrides_use']) ? (int) $_GET['wpsn_ai_overrides_use'] : 0;
                    $manage = isset($_GET['wpsn_ai_overrides_manage']) ? (int) $_GET['wpsn_ai_overrides_manage'] : 0;
                    $which = isset($_GET['wpsn_ai_overrides_which']) ? sanitize_key((string) wp_unslash($_GET['wpsn_ai_overrides_which'])) : 'both';

                    $msg = __('AI overrides cleared for all users.', 'wp-seo-next');
                    if ($users > 0) {
                        $msg .= ' ' . sprintf(
                            /* translators: 1: users affected, 2: cleared use, 3: cleared manage, 4: which */
                            __('(%1$d users; use: %2$d, manage: %3$d; mode: %4$s)', 'wp-seo-next'),
                            $users,
                            $use,
                            $manage,
                            $which
                        );
                    }
                ?>
                <div class="notice notice-success is-dismissible"><p><?php echo esc_html($msg); ?></p></div>
            <?php endif; ?>


            <?php
                $notice = !empty($_GET['wpsn_notice']) ? sanitize_key((string) wp_unslash($_GET['wpsn_notice'])) : '';
            ?>

            <?php if ($notice === 'ai_test_result') : ?>
                <?php
                    $uid = (int) get_current_user_id();
                    $key = 'wpsn_ai_test_result_' . $uid;
                    $res = get_transient($key);
                    if (is_array($res)) {
                        delete_transient($key);
                    }
                    $ok = is_array($res) && !empty($res['ok']);
                    $msg = '';
                    if (!is_array($res)) {
                        $msg = __('No AI test result found (it may have expired). Please run the test again.', 'wp-seo-next');
                    } elseif ($ok) {
                        $model = isset($res['model']) ? (string) $res['model'] : '';
                        $latency = isset($res['latency_ms']) ? (int) $res['latency_ms'] : 0;
                        $tokens = isset($res['usage_total']) ? (int) $res['usage_total'] : 0;
                        $msg = __('OpenAI connection OK.', 'wp-seo-next');
                        if ($model !== '') {
                            $msg .= ' ' . sprintf(__('Model: %s', 'wp-seo-next'), $model);
                        }
                        if ($latency > 0) {
                            $msg .= ' ' . sprintf(__('Latency: %d ms', 'wp-seo-next'), $latency);
                        }
                        if ($tokens > 0) {
                            $msg .= ' ' . sprintf(__('Tokens: %d', 'wp-seo-next'), $tokens);
                        }
                        if (!empty($res['key_saved'])) {
                            $msg .= ' ' . __('(API key saved)', 'wp-seo-next');
                        }
                    } else {
                        $err = isset($res['error']) ? (string) $res['error'] : '';
                        $http = isset($res['http_status']) ? (int) $res['http_status'] : 0;
                        $retry = isset($res['retry_after']) ? (int) $res['retry_after'] : 0;
                        $msg = __('OpenAI test failed.', 'wp-seo-next');
                        if ($err !== '') {
                            $msg .= ' ' . $err;
                        }
                        if ($http > 0) {
                            $msg .= ' ' . sprintf(__('HTTP %d', 'wp-seo-next'), $http);
                        }
                        if ($retry > 0) {
                            $msg .= ' ' . sprintf(__('Retry-After: %d s', 'wp-seo-next'), $retry);
                        }
                        if (!empty($privacy['local_only'])) {
                            $msg .= ' ' . __('Note: Privacy → Local-only mode is enabled, external services are blocked at runtime.', 'wp-seo-next');
                        }
                    }
                ?>
                <div class="notice <?php echo $ok ? 'notice-success' : (is_array($res) ? 'notice-error' : 'notice-info'); ?> is-dismissible"><p><?php echo esc_html($msg); ?></p></div>
            <?php endif; ?>

            <?php if ($notice === 'serper_test_result') : ?>
                <?php
                    $uid = (int) get_current_user_id();
                    $key = 'wpsn_serper_test_result_' . $uid;
                    $res = get_transient($key);
                    if (is_array($res)) {
                        delete_transient($key);
                    }

                    $ok = is_array($res) && !empty($res['ok']);
                    $msg = '';
                    if (!is_array($res)) {
                        $msg = __('No Serper test result found (it may have expired). Please run the test again.', 'wp-seo-next');
                    } elseif ($ok) {
                        $http = isset($res['http_status']) ? (int) $res['http_status'] : 0;
                        $results = isset($res['results_count']) ? (int) $res['results_count'] : 0;
                        $lat = isset($res['ms']) ? (int) $res['ms'] : 0;
                        $msg = __('Serper connection OK.', 'wp-seo-next');
                        if ($http > 0) {
                            $msg .= ' ' . sprintf(__('HTTP %d', 'wp-seo-next'), $http);
                        }
                        if ($results > 0) {
                            $msg .= ' ' . sprintf(__('Results: %d', 'wp-seo-next'), $results);
                        }
                        if ($lat > 0) {
                            $msg .= ' ' . sprintf(__('Latency: %d ms', 'wp-seo-next'), $lat);
                        }
                    } else {
                        $err = isset($res['error']) ? (string) $res['error'] : '';
                        $http = isset($res['http_status']) ? (int) $res['http_status'] : 0;
                        $retry = isset($res['retry_after']) ? (int) $res['retry_after'] : 0;
                        $msg = __('Serper test failed.', 'wp-seo-next');
                        if ($err !== '') {
                            $msg .= ' ' . $err;
                        }
                        if ($http > 0) {
                            $msg .= ' ' . sprintf(__('HTTP %d', 'wp-seo-next'), $http);
                        }
                        if ($retry > 0) {
                            $msg .= ' ' . sprintf(__('Retry-After: %d s', 'wp-seo-next'), $retry);
                        }
                        if (!empty($privacy['local_only'])) {
                            $msg .= ' ' . __('Note: Privacy → Local-only mode is enabled, external services are blocked at runtime.', 'wp-seo-next');
                        }
                    }
                ?>
                <div class="notice <?php echo $ok ? 'notice-success' : (is_array($res) ? 'notice-error' : 'notice-info'); ?> is-dismissible"><p><?php echo esc_html($msg); ?></p></div>
            <?php endif; ?>

            <?php if ($notice === 'serper_backoff_cleared') : ?>
                <div class="notice notice-success is-dismissible"><p><?php echo esc_html__('Serper backoff cleared.', 'wp-seo-next'); ?></p></div>
            <?php endif; ?>

            <?php if ($notice === 'ai_preset_applied') : ?>
                <?php
                    $msg = __('AI preset applied: External AI enabled with a cheap, safe default configuration.', 'wp-seo-next');
                    if (!empty($privacy['local_only'])) {
                        $msg .= ' ' . __('Note: Privacy → Local-only mode is enabled, so external AI calls will still be blocked until you turn it off.', 'wp-seo-next');
                    }
                ?>
                <div class="notice notice-success is-dismissible"><p><?php echo esc_html($msg); ?></p></div>
            <?php endif; ?>

            <?php if ($notice === 'ai_preset_locked') : ?>
                <div class="notice notice-warning is-dismissible"><p><?php echo esc_html__('Cannot apply AI preset because settings are locked by Config Sync. You can still save the API key, but preset changes were not applied.', 'wp-seo-next'); ?></p></div>
            <?php endif; ?>

            <?php if (!empty($locked)) : ?>
                <div class="notice notice-info"><p><?php echo wp_kses_post(__('Settings are currently <strong>locked</strong> by Config Sync. Manage lock/export/import in <a href="tools.php?page=wpsn-config-sync">Tools → SEO Config Sync</a>.', 'wp-seo-next')); ?></p></div>
            <?php endif; ?>

            <?php if ($enforceModules || $enforceWhiteLabel || $enforceIntegrations) : ?>
                <div class="notice notice-info"><p>
                    <?php
                        $msg = __('Some settings are enforced by <strong>Network Policies</strong> (multisite). Enforced sections are read-only on this site.', 'wp-seo-next');
                        if (is_multisite() && current_user_can('manage_network_options')) {
                            $link = network_admin_url('settings.php?page=wpsn-network-settings');
                            $msg .= ' ' . sprintf(__('Manage policies in <a href="%s">Network Admin → Settings → SEO Policies</a>.', 'wp-seo-next'), esc_url($link));
                        }
                        echo wp_kses_post($msg);
                    ?>
                </p></div>
            <?php endif; ?>

            <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                <input type="hidden" name="action" value="wpsn_save_settings" />
                <?php wp_nonce_field('wpsn_save_settings', 'wpsn_nonce'); ?>

                <h2 class="title"><?php echo esc_html__('General', 'wp-seo-next'); ?></h2>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Debug mode', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[debug]" value="1" <?php checked(!empty($data['debug'])); ?> />
                                <?php echo esc_html__('Enable debug logging to error_log', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Title separator', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[separator]" value="<?php echo esc_attr((string) $data['separator']); ?>" />
                            <p class="description"><?php echo esc_html__('Used as %sep% in templates.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr id="wpsn-ui-mode">
                        <th scope="row"><?php echo esc_html__('Interface mode', 'wp-seo-next'); ?></th>
                        <td>
                            <select name="wpsn[ui][mode]">
                                <option value="simple" <?php selected($uiMode, UI::MODE_SIMPLE); ?>><?php echo esc_html__('Simple (recommended)', 'wp-seo-next'); ?></option>
                                <option value="pro" <?php selected($uiMode, UI::MODE_PRO); ?>><?php echo esc_html__('Pro (advanced)', 'wp-seo-next'); ?></option>
                            </select>
                            <p class="description"><?php echo esc_html__('Simple mode hides advanced settings and Tools pages. It does not change SEO output.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                <h2 class="title"><?php echo esc_html__('Site verification', 'wp-seo-next'); ?></h2>
                <p class="description">
                    <?php echo esc_html__('Optional meta tags used to verify site ownership in webmaster tools. Paste only the token/code value (not the full <meta> tag).', 'wp-seo-next'); ?>
                </p>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Google Search Console', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[verification][google]" value="<?php echo esc_attr((string) ($data['verification']['google'] ?? '')); ?>" />
                            <p class="description"><?php echo esc_html__('Outputs: <meta name="google-site-verification" ...>', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Bing / Microsoft', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[verification][bing]" value="<?php echo esc_attr((string) ($data['verification']['bing'] ?? '')); ?>" />
                            <p class="description"><?php echo esc_html__('Outputs: <meta name="msvalidate.01" ...>', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Yandex', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[verification][yandex]" value="<?php echo esc_attr((string) ($data['verification']['yandex'] ?? '')); ?>" />
                            <p class="description"><?php echo esc_html__('Outputs: <meta name="yandex-verification" ...>', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Baidu', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[verification][baidu]" value="<?php echo esc_attr((string) ($data['verification']['baidu'] ?? '')); ?>" />
                            <p class="description"><?php echo esc_html__('Outputs: <meta name="baidu-site-verification" ...>', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Ahrefs', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[verification][ahrefs]" value="<?php echo esc_attr((string) ($data['verification']['ahrefs'] ?? '')); ?>" />
                            <p class="description"><?php echo esc_html__('Outputs: <meta name="ahrefs-site-verification" ...>', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                <h2 id="wpsn-settings-breadcrumbs" class="title"><?php echo esc_html__('Breadcrumbs', 'wp-seo-next'); ?></h2>
                <p class="description">
                    <?php echo esc_html__('Frontend breadcrumbs navigation. Use the shortcode or enable auto-insert.', 'wp-seo-next'); ?>
                </p>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Enable breadcrumbs UI', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[breadcrumbs][ui_enabled]" value="1" <?php checked(!empty($data['breadcrumbs']['ui_enabled'])); ?> />
                                <?php echo esc_html__('Enable shortcode + auto-insert output.', 'wp-seo-next'); ?>
                            </label>
                            <p class="description">
                                <?php echo esc_html__('If disabled, visual breadcrumbs are hidden (shortcode returns empty). Schema output can be controlled separately below.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Auto insert', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[breadcrumbs][auto_insert]" value="1" <?php checked(!empty($data['breadcrumbs']['auto_insert'])); ?> />
                                <?php echo esc_html__('Insert breadcrumbs into post content automatically.', 'wp-seo-next'); ?>
                            </label>
                            <p class="description">
                                <?php echo esc_html__('If disabled, you can still use the shortcode: [wpsn_breadcrumbs]', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Auto insert position', 'wp-seo-next'); ?></th>
                        <td>
                            <?php $bcPos = (string) ($data['breadcrumbs']['position'] ?? 'before'); ?>
                            <select name="wpsn[breadcrumbs][position]">
                                <option value="before" <?php selected($bcPos, 'before'); ?>><?php echo esc_html__('Before content', 'wp-seo-next'); ?></option>
                                <option value="after" <?php selected($bcPos, 'after'); ?>><?php echo esc_html__('After content', 'wp-seo-next'); ?></option>
                            </select>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Separator', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[breadcrumbs][separator]" value="<?php echo esc_attr((string) ($data['breadcrumbs']['separator'] ?? '›')); ?>" maxlength="10" />
                            <p class="description"><?php echo esc_html__('Example: › or /', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Home label', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[breadcrumbs][home_label]" value="<?php echo esc_attr((string) ($data['breadcrumbs']['home_label'] ?? '')); ?>" maxlength="80" />
                            <p class="description"><?php echo esc_html__('Optional. Leave empty to use the default “Home”.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Trail prefix', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[breadcrumbs][trail_prefix]" value="<?php echo esc_attr((string) ($data['breadcrumbs']['trail_prefix'] ?? '')); ?>" maxlength="120" />
                            <p class="description"><?php echo esc_html__('Optional text shown before the breadcrumb trail, e.g. “You are here:”.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Archive prefix', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[breadcrumbs][archive_prefix]" value="<?php echo esc_attr((string) ($data['breadcrumbs']['archive_prefix'] ?? '')); ?>" maxlength="120" />
                            <p class="description"><?php echo esc_html__('Optional prefix for archive crumbs, e.g. “Archives for”.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Search prefix', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[breadcrumbs][search_prefix]" value="<?php echo esc_attr((string) ($data['breadcrumbs']['search_prefix'] ?? '')); ?>" maxlength="120" />
                            <p class="description"><?php echo esc_html__('Optional prefix for search crumbs, e.g. “You searched for”.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('404 label', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[breadcrumbs][not_found_label]" value="<?php echo esc_attr((string) ($data['breadcrumbs']['not_found_label'] ?? '')); ?>" maxlength="120" />
                            <p class="description"><?php echo esc_html__('Optional custom label for the 404 breadcrumb.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('BreadcrumbList schema', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[breadcrumbs][schema_enabled]" value="1" <?php checked(!empty($data['breadcrumbs']['schema_enabled'])); ?> />
                                <?php echo esc_html__('Output BreadcrumbList in JSON-LD Schema (separate from visual breadcrumbs).', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Display rules', 'wp-seo-next'); ?></th>
                        <td>
                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[breadcrumbs][show_current]" value="1" <?php checked(!empty($data['breadcrumbs']['show_current'])); ?> />
                                <?php echo esc_html__('Show current page item', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[breadcrumbs][singular_only]" value="1" <?php checked(!empty($data['breadcrumbs']['singular_only'])); ?> />
                                <?php echo esc_html__('Auto insert only on singular pages', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                </table>

<h2 id="wpsn-settings-templates" class="title"><?php echo esc_html__('Templates', 'wp-seo-next'); ?></h2>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Title template', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="large-text" name="wpsn[templates][title]" value="<?php echo esc_attr((string) $data['templates']['title']); ?>" />
                            <p class="description">
                                <?php echo esc_html__('Example: %title% %sep% %sitename%', 'wp-seo-next'); ?>
                                <br/>
                                <?php echo esc_html__('Advanced: use ?? for fallbacks and | for transforms (Tools → Tokens & Variables).', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Description template', 'wp-seo-next'); ?></th>
                        <td>
                            <textarea class="large-text" rows="3" name="wpsn[templates][description]"><?php echo esc_textarea((string) $data['templates']['description']); ?></textarea>
                            <p class="description">
                                <?php echo esc_html__('Example: %excerpt%', 'wp-seo-next'); ?>
                                <br/>
                                <?php echo esc_html__('Tip: %excerpt|strip|truncate(160)%', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>
                    <tr class="wpsn-ui-pro-only">
                        <th scope="row"><?php echo esc_html__('Author archive title template', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="large-text" name="wpsn[templates][author_title]" value="<?php echo esc_attr((string) ($data['templates']['author_title'] ?? '')); ?>" />
                            <p class="description"><?php echo esc_html__('Example: %author_name% %sep% %sitename%', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr class="wpsn-ui-pro-only">
                        <th scope="row"><?php echo esc_html__('Author archive description template', 'wp-seo-next'); ?></th>
                        <td>
                            <textarea class="large-text" rows="3" name="wpsn[templates][author_description]"><?php echo esc_textarea((string) ($data['templates']['author_description'] ?? '')); ?></textarea>
                            <p class="description"><?php echo esc_html__('Example: %author_bio% (from user profile Bio)', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                <h2 id="wpsn-settings-robots" class="title"><?php echo esc_html__('Robots meta', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Global defaults for the meta robots tag. Per-post overrides can be set in the SEO metabox.', 'wp-seo-next'); ?></p>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Index/Follow by page type', 'wp-seo-next'); ?></th>
                        <td>
                            <table class="widefat striped" style="max-width: 760px;">
                                <thead>
                                    <tr>
                                        <th><?php echo esc_html__('Context', 'wp-seo-next'); ?></th>
                                        <th><?php echo esc_html__('Index', 'wp-seo-next'); ?></th>
                                        <th><?php echo esc_html__('Follow', 'wp-seo-next'); ?></th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php
                                        $contexts = [
                                            'home'     => __('Home', 'wp-seo-next'),
                                            'singular' => __('Posts & Pages (singular)', 'wp-seo-next'),
                                            'term'     => __('Taxonomy terms', 'wp-seo-next'),
                                            'archive'  => __('Other archives', 'wp-seo-next'),
                                            'search'   => __('Search results', 'wp-seo-next'),
                                            '404'      => __('404 pages', 'wp-seo-next'),
                                        ];
                                    ?>
                                    <?php foreach ($contexts as $ctxKey => $label) :
                                        $ctxData = $data['robots']['contexts'][$ctxKey] ?? ['index' => true, 'follow' => true];
                                    ?>
                                        <tr>
                                            <td><?php echo esc_html($label); ?></td>
                                            <td>
                                                <label>
                                                    <input type="checkbox" name="wpsn[robots][contexts][<?php echo esc_attr($ctxKey); ?>][index]" value="1" <?php checked(!empty($ctxData['index'])); ?> />
                                                    <?php echo esc_html__('Index', 'wp-seo-next'); ?>
                                                </label>
                                            </td>
                                            <td>
                                                <label>
                                                    <input type="checkbox" name="wpsn[robots][contexts][<?php echo esc_attr($ctxKey); ?>][follow]" value="1" <?php checked(!empty($ctxData['follow'])); ?> />
                                                    <?php echo esc_html__('Follow', 'wp-seo-next'); ?>
                                                </label>
                                            </td>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>

                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[robots][noindex_paged]" value="1" <?php checked(!empty($data['robots']['noindex_paged'])); ?> />
                                    <?php echo esc_html__('Noindex paginated archives/terms (page 2+)', 'wp-seo-next'); ?>
                                </label>
                            </p>
                        </td>
                    </tr>

                    <tr class="wpsn-ui-pro-only">
                        <th scope="row"><?php echo esc_html__('Advanced directives', 'wp-seo-next'); ?></th>
                        <td>
                            <p>
                                <label for="wpsn_mip"><strong><?php echo esc_html__('max-image-preview', 'wp-seo-next'); ?></strong></label><br/>
                                <select id="wpsn_mip" name="wpsn[robots][advanced][max-image-preview]">
                                    <?php
                                        $mip = (string) ($data['robots']['advanced']['max-image-preview'] ?? 'large');
                                        $opts = [
                                            'large'    => 'large',
                                            'standard' => 'standard',
                                            'none'     => 'none',
                                            ''         => __('(do not set)', 'wp-seo-next'),
                                        ];
                                        foreach ($opts as $val => $lbl) {
                                            printf('<option value="%s" %s>%s</option>', esc_attr($val), selected($mip, (string) $val, false), esc_html((string) $lbl));
                                        }
                                    ?>
                                </select>
                            </p>

                            <p>
                                <label for="wpsn_ms"><strong><?php echo esc_html__('max-snippet', 'wp-seo-next'); ?></strong></label><br/>
                                <input id="wpsn_ms" type="number" name="wpsn[robots][advanced][max-snippet]" value="<?php echo esc_attr((string) ($data['robots']['advanced']['max-snippet'] ?? '-1')); ?>" />
                                <span class="description"><?php echo esc_html__('Use -1 for unlimited.', 'wp-seo-next'); ?></span>
                            </p>

                            <p>
                                <label for="wpsn_mvp"><strong><?php echo esc_html__('max-video-preview', 'wp-seo-next'); ?></strong></label><br/>
                                <input id="wpsn_mvp" type="number" name="wpsn[robots][advanced][max-video-preview]" value="<?php echo esc_attr((string) ($data['robots']['advanced']['max-video-preview'] ?? '-1')); ?>" />
                                <span class="description"><?php echo esc_html__('Use -1 for unlimited.', 'wp-seo-next'); ?></span>
                            </p>

                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[robots][advanced][noarchive]" value="1" <?php checked(!empty($data['robots']['advanced']['noarchive'])); ?> />
                                    <?php echo esc_html__('noarchive', 'wp-seo-next'); ?>
                                </label>
                            </p>

                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[robots][advanced][nosnippet]" value="1" <?php checked(!empty($data['robots']['advanced']['nosnippet'])); ?> />
                                    <?php echo esc_html__('nosnippet', 'wp-seo-next'); ?>
                                </label>
                            </p>
                        </td>
                    </tr>
                </table>

                <h2 id="wpsn-settings-archives" class="title"><?php echo esc_html__('Archive controls', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Specific robots defaults, disable modes for archive URLs, and cleanup options for media attachment pages.', 'wp-seo-next'); ?></p>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Specific archive overrides', 'wp-seo-next'); ?></th>
                        <td>
                            <table class="widefat striped" style="max-width: 980px;">
                                <thead>
                                    <tr>
                                        <th><?php echo esc_html__('Archive type', 'wp-seo-next'); ?></th>
                                        <th><?php echo esc_html__('Use specific rule', 'wp-seo-next'); ?></th>
                                        <th><?php echo esc_html__('Mode', 'wp-seo-next'); ?></th>
                                        <th><?php echo esc_html__('Follow', 'wp-seo-next'); ?></th>
                                        <th><?php echo esc_html__('Custom redirect URL', 'wp-seo-next'); ?></th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php
                                        $archiveBuckets = [
                                            'author' => __('Author archives', 'wp-seo-next'),
                                            'date' => __('Date archives', 'wp-seo-next'),
                                            'post_type' => __('Post type archives', 'wp-seo-next'),
                                        ];
                                        $archiveModeChoices = [
                                            'index' => __('Index', 'wp-seo-next'),
                                            'noindex' => __('Noindex', 'wp-seo-next'),
                                            'disable_301_to_home' => __('Disable: 301 to home', 'wp-seo-next'),
                                            'disable_301_to_custom' => __('Disable: 301 to custom URL', 'wp-seo-next'),
                                            'disable_404' => __('Disable: return 404', 'wp-seo-next'),
                                        ];
                                    ?>
                                    <?php foreach ($archiveBuckets as $bucketKey => $bucketLabel) :
                                        $rule = $data['archive_controls'][$bucketKey] ?? [];
                                        if (!is_array($rule)) {
                                            $rule = [];
                                        }
                                        $enabled = !empty($rule['enabled']);
                                        $mode = isset($rule['mode']) ? (string) $rule['mode'] : ((!array_key_exists('index', $rule) || !empty($rule['index'])) ? 'index' : 'noindex');
                                        if (!array_key_exists($mode, $archiveModeChoices)) {
                                            $mode = (!array_key_exists('index', $rule) || !empty($rule['index'])) ? 'index' : 'noindex';
                                        }
                                        $follow = !array_key_exists('follow', $rule) || !empty($rule['follow']);
                                        $redirectUrl = isset($rule['redirect_url']) ? (string) $rule['redirect_url'] : '';
                                    ?>
                                        <tr>
                                            <td><?php echo esc_html($bucketLabel); ?></td>
                                            <td>
                                                <label>
                                                    <input type="checkbox" name="wpsn[archive_controls][<?php echo esc_attr($bucketKey); ?>][enabled]" value="1" <?php checked($enabled); ?> />
                                                    <?php echo esc_html__('Override generic archive defaults', 'wp-seo-next'); ?>
                                                </label>
                                            </td>
                                            <td>
                                                <select name="wpsn[archive_controls][<?php echo esc_attr($bucketKey); ?>][mode]">
                                                    <?php foreach ($archiveModeChoices as $archiveModeKey => $archiveModeLabel) : ?>
                                                        <option value="<?php echo esc_attr($archiveModeKey); ?>" <?php selected($mode, $archiveModeKey); ?>><?php echo esc_html($archiveModeLabel); ?></option>
                                                    <?php endforeach; ?>
                                                </select>
                                            </td>
                                            <td>
                                                <label>
                                                    <input type="checkbox" name="wpsn[archive_controls][<?php echo esc_attr($bucketKey); ?>][follow]" value="1" <?php checked($follow); ?> />
                                                    <?php echo esc_html__('Follow', 'wp-seo-next'); ?>
                                                </label>
                                                <p class="description" style="margin:6px 0 0;"><?php echo esc_html__('Used for Index / Noindex modes only.', 'wp-seo-next'); ?></p>
                                            </td>
                                            <td>
                                                <input type="url" class="regular-text" name="wpsn[archive_controls][<?php echo esc_attr($bucketKey); ?>][redirect_url]" value="<?php echo esc_attr($redirectUrl); ?>" placeholder="https://example.com/target/" />
                                                <p class="description" style="margin:6px 0 0;"><?php echo esc_html__('Used only when “Disable: 301 to custom URL” is selected.', 'wp-seo-next'); ?></p>
                                            </td>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                            <p class="description"><?php echo esc_html__('When a specific rule is off, that archive type inherits the generic “Other archives” robots settings from the section above. Disable modes can fully remove author/date/post type archive URLs with a 301 or 404.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Attachment pages', 'wp-seo-next'); ?></th>
                        <td>
                            <?php $attachmentMode = isset($data['archive_controls']['attachments']['mode']) ? (string) $data['archive_controls']['attachments']['mode'] : 'default'; ?>
                            <select name="wpsn[archive_controls][attachments][mode]">
                                <option value="default" <?php selected($attachmentMode, 'default'); ?>><?php echo esc_html__('Leave enabled (default WordPress behavior)', 'wp-seo-next'); ?></option>
                                <option value="noindex" <?php selected($attachmentMode, 'noindex'); ?>><?php echo esc_html__('Keep the page, but noindex it', 'wp-seo-next'); ?></option>
                                <option value="redirect_file" <?php selected($attachmentMode, 'redirect_file'); ?>><?php echo esc_html__('Redirect to the media file URL (301)', 'wp-seo-next'); ?></option>
                                <option value="redirect_parent" <?php selected($attachmentMode, 'redirect_parent'); ?>><?php echo esc_html__('Redirect to parent content if available, otherwise to the media file (301)', 'wp-seo-next'); ?></option>
                            </select>
                            <p class="description"><?php echo esc_html__('Useful for cleaning thin attachment URLs without affecting uploads themselves.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                <h2 id="wpsn-settings-search-urls" class="title"><?php echo esc_html__('Search URL canonicalization & query cleanup', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Opt-in redirects that normalize search result URLs to the site’s canonical search format, can strip noisy query parameters, and can sanitize the search query itself.', 'wp-seo-next'); ?></p>
                <?php
                    $searchUrls = isset($data['search_urls']) && is_array($data['search_urls']) ? $data['search_urls'] : [];
                    $searchUrlsEnabled = !empty($searchUrls['enabled']);
                    $searchUrlsMode = isset($searchUrls['mode']) ? (string) $searchUrls['mode'] : 'format';
                    if (!in_array($searchUrlsMode, ['format', 'strict'], true)) {
                        $searchUrlsMode = 'format';
                    }
                    $searchUrlsInvalidAction = isset($searchUrls['invalid_action']) ? (string) $searchUrls['invalid_action'] : '404';
                    if (!in_array($searchUrlsInvalidAction, ['redirect_home', '404', 'empty_search'], true)) {
                        $searchUrlsInvalidAction = '404';
                    }
                ?>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Enable redirects', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[search_urls][enabled]" value="1" <?php checked($searchUrlsEnabled); ?> />
                                <?php echo esc_html__('Redirect search requests to the canonical search URL format for this site.', 'wp-seo-next'); ?>
                            </label>
                            <p class="description"><?php echo esc_html__('Target URLs follow WordPress get_search_link(), so sites using pretty search URLs will redirect there automatically; sites using ?s= will normalize to that format instead.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Redirect mode', 'wp-seo-next'); ?></th>
                        <td>
                            <select name="wpsn[search_urls][mode]">
                                <option value="format" <?php selected($searchUrlsMode, 'format'); ?>><?php echo esc_html__('Format only (preserve extra non-tracking query args)', 'wp-seo-next'); ?></option>
                                <option value="strict" <?php selected($searchUrlsMode, 'strict'); ?>><?php echo esc_html__('Strict canonical (drop extra query args unless allowlisted)', 'wp-seo-next'); ?></option>
                            </select>
                            <p class="description"><?php echo esc_html__('Format only is safer for sites with custom search filters. Strict is better when you want one clean crawlable search URL for each query.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Allowlisted extra args', 'wp-seo-next'); ?></th>
                        <td>
                            <textarea class="large-text" rows="3" name="wpsn[search_urls][preserve_args]" placeholder="post_type
lang"><?php echo esc_textarea((string) ($searchUrls['preserve_args'] ?? '')); ?></textarea>
                            <p class="description"><?php echo esc_html__('Only used in Strict mode. Enter one query arg per line (or comma-separated) for search filters you intentionally need to keep.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Category URLs', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[search_urls][strip_category_base]" value="1" <?php checked(!empty($searchUrls['strip_category_base'])); ?> />
                                <?php echo esc_html__('Strip the /category/ base from category archive URLs when possible.', 'wp-seo-next'); ?>
                            </label>
                            <p class="description"><?php echo esc_html__('Best-effort compatibility for imports such as Yoast stripcategorybase. Existing pages or posts with the same path still win to avoid collisions.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Search query sanitizer', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[search_urls][sanitize_query]" value="1" <?php checked(!empty($searchUrls['sanitize_query'])); ?> />
                                <?php echo esc_html__('Clean the search query itself before the page is rendered.', 'wp-seo-next'); ?>
                            </label>
                            <p class="description"><?php echo esc_html__('Use this to trim long spammy searches, remove emoji/pictographs, block known bad patterns, and 301 to the cleaned search URL when possible.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Max query length', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" class="small-text" min="0" max="200" name="wpsn[search_urls][query_limit]" value="<?php echo esc_attr((string) ($searchUrls['query_limit'] ?? 50)); ?>" />
                            <p class="description"><?php echo esc_html__('Maximum number of characters kept in the cleaned search query. Use 0 to disable trimming. A value around 50–80 is usually enough.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Remove emoji', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[search_urls][strip_emoji]" value="1" <?php checked(!empty($searchUrls['strip_emoji'])); ?> />
                                <?php echo esc_html__('Strip emoji / pictographic characters from the search query.', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Common spam patterns', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[search_urls][block_common_patterns]" value="1" <?php checked(!empty($searchUrls['block_common_patterns'])); ?> />
                                <?php echo esc_html__('Block common spam / injection search queries (URLs, script payloads, obvious SQL-like probes).', 'wp-seo-next'); ?>
                            </label>
                            <p class="description"><?php echo esc_html__('Conservative built-in patterns for crawl cleanup. Keep off if your site intentionally allows searching for raw code or URLs.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Custom blocked regex patterns', 'wp-seo-next'); ?></th>
                        <td>
                            <textarea class="large-text" rows="5" name="wpsn[search_urls][blacklist_patterns]" placeholder="(?:https?:\/\/|www\.)
(?:union\s+select|drop\s+table)"><?php echo esc_textarea((string) ($searchUrls['blacklist_patterns'] ?? '')); ?></textarea>
                            <p class="description"><?php echo esc_html__('Optional. Enter one regex per line. Matching queries are treated as invalid before rendering search results.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('When query becomes empty or blocked', 'wp-seo-next'); ?></th>
                        <td>
                            <select name="wpsn[search_urls][invalid_action]">
                                <option value="404" <?php selected($searchUrlsInvalidAction, '404'); ?>><?php echo esc_html__('Return 404', 'wp-seo-next'); ?></option>
                                <option value="redirect_home" <?php selected($searchUrlsInvalidAction, 'redirect_home'); ?>><?php echo esc_html__('Redirect to homepage (301)', 'wp-seo-next'); ?></option>
                                <option value="empty_search" <?php selected($searchUrlsInvalidAction, 'empty_search'); ?>><?php echo esc_html__('Redirect to the empty search URL (301)', 'wp-seo-next'); ?></option>
                            </select>
                            <p class="description"><?php echo esc_html__('Used when cleanup leaves no query behind or the query matches a blocked pattern.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                <h2 id="wpsn-settings-hreflang" class="title"><?php echo esc_html__('Hreflang', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Best-effort rel="alternate" hreflang output for multilingual sites. Currently supports Polylang, WPML, and custom code via the wpsn/hreflang/alternates filter.', 'wp-seo-next'); ?></p>
                <?php $hreflang = isset($data['hreflang']) && is_array($data['hreflang']) ? $data['hreflang'] : []; ?>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Enable hreflang tags', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[hreflang][enabled]" value="1" <?php checked(!empty($hreflang['enabled'])); ?> />
                                <?php echo esc_html__('Output <link rel="alternate" hreflang=...> tags for translated versions when a multilingual plugin provides them.', 'wp-seo-next'); ?>
                            </label>
                            <p class="description"><?php echo esc_html__('Safe first version: singular pages, translated taxonomy terms, and home page. Search, 404, and paged views are skipped on purpose to avoid wrong alternates.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Add x-default', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[hreflang][include_x_default]" value="1" <?php checked(!empty($hreflang['include_x_default'])); ?> />
                                <?php echo esc_html__('Also output x-default.', 'wp-seo-next'); ?>
                            </label>
                            <p class="description"><?php echo esc_html__('When no custom URL is set below, we try to use the default-language translation. If that is unavailable, we fall back to the current canonical URL.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Custom x-default URL', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="url" class="large-text" name="wpsn[hreflang][x_default_url]" value="<?php echo esc_attr((string) ($hreflang['x_default_url'] ?? '')); ?>" placeholder="https://example.com/language-selector/" />
                            <p class="description"><?php echo esc_html__('Optional. Leave empty to use the default-language URL from WPML/Polylang automatically.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                <h2 id="wpsn-settings-schema" class="title"><?php echo esc_html__('Schema', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Used for JSON-LD structured data (Organization / Publisher).', 'wp-seo-next'); ?></p>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Organization name', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[schema][org_name]" value="<?php echo esc_attr((string) ($data['schema']['org_name'] ?? '')); ?>" />
                            <p class="description"><?php echo esc_html__('Leave empty to use the site title.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Organization logo URL', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="url" class="large-text" name="wpsn[schema][org_logo_url]" value="<?php echo esc_attr((string) ($data['schema']['org_logo_url'] ?? '')); ?>" />
                            <p class="description"><?php echo esc_html__('Leave empty to use the theme logo or Site Icon.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Organization profile', 'wp-seo-next'); ?></th>
                        <td>
                            <p style="margin-top:0;">
                                <label>
                                    <?php echo esc_html__('Alternate name', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[schema][org_alternate_name]" value="<?php echo esc_attr((string) ($data['schema']['org_alternate_name'] ?? '')); ?>" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <?php echo esc_html__('Legal name', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[schema][org_legal_name]" value="<?php echo esc_attr((string) ($data['schema']['org_legal_name'] ?? '')); ?>" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <?php echo esc_html__('Email', 'wp-seo-next'); ?><br/>
                                    <input type="email" class="regular-text" name="wpsn[schema][org_email]" value="<?php echo esc_attr((string) ($data['schema']['org_email'] ?? '')); ?>" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <?php echo esc_html__('Telephone', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[schema][org_telephone]" value="<?php echo esc_attr((string) ($data['schema']['org_telephone'] ?? '')); ?>" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <?php echo esc_html__('Description', 'wp-seo-next'); ?><br/>
                                    <textarea class="large-text" rows="3" name="wpsn[schema][org_description]"><?php echo esc_textarea((string) ($data['schema']['org_description'] ?? '')); ?></textarea>
                                </label>
                            </p>
                            <p class="description"><?php echo esc_html__('Optional publisher/organization details used in JSON-LD and helpful when importing from other SEO plugins.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr class="wpsn-ui-pro-only">
                        <th scope="row"><?php echo esc_html__('Social profiles (sameAs)', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $sameAs = $data['schema']['org_same_as'] ?? [];
                                if (!is_array($sameAs)) {
                                    $sameAs = [];
                                }
                                $sameAsText = implode("\n", array_map('strval', $sameAs));
                            ?>
                            <textarea class="large-text" rows="4" name="wpsn[schema][org_same_as]"><?php echo esc_textarea($sameAsText); ?></textarea>
                            <p class="description"><?php echo esc_html__('One URL per line (e.g. https://twitter.com/yourbrand).', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr class="wpsn-ui-pro-only">
                        <th scope="row"><?php echo esc_html__('Editorial / trust pages', 'wp-seo-next'); ?></th>
                        <td>
                            <?php $policyUrls = isset($data['schema']['policy_urls']) && is_array($data['schema']['policy_urls']) ? $data['schema']['policy_urls'] : []; ?>
                            <?php
                                $policyLabels = [
                                    'publishing_principles' => __('Publishing principles', 'wp-seo-next'),
                                    'ownership_funding_info' => __('Ownership / funding info', 'wp-seo-next'),
                                    'actionable_feedback_policy' => __('Actionable feedback policy', 'wp-seo-next'),
                                    'corrections_policy' => __('Corrections policy', 'wp-seo-next'),
                                    'ethics_policy' => __('Ethics policy', 'wp-seo-next'),
                                    'diversity_policy' => __('Diversity policy', 'wp-seo-next'),
                                    'diversity_staffing_report' => __('Diversity staffing report', 'wp-seo-next'),
                                ];
                            ?>
                            <?php foreach ($policyLabels as $policyKey => $policyLabel) : ?>
                                <p<?php echo $policyKey === 'publishing_principles' ? ' style="margin-top:0;"' : ''; ?>>
                                    <label>
                                        <?php echo esc_html($policyLabel); ?><br/>
                                        <input type="url" class="large-text" name="wpsn[schema][policy_urls][<?php echo esc_attr($policyKey); ?>]" value="<?php echo esc_attr((string) ($policyUrls[$policyKey] ?? '')); ?>" />
                                    </label>
                                </p>
                            <?php endforeach; ?>
                            <p class="description"><?php echo esc_html__('Optional URLs for editorial, ethics, corrections, and trust pages. Imported automatically from supported source plugins when possible.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr class="wpsn-ui-pro-only">
                        <th scope="row"><?php echo esc_html__('Organization registry / business IDs', 'wp-seo-next'); ?></th>
                        <td>
                            <p style="margin-top:0;">
                                <label>
                                    <?php echo esc_html__('Founding date', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[schema][org_founding_date]" value="<?php echo esc_attr((string) ($data['schema']['org_founding_date'] ?? '')); ?>" placeholder="YYYY-MM-DD" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <?php echo esc_html__('Number of employees', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="0" class="small-text" name="wpsn[schema][org_number_employees]" value="<?php echo esc_attr((string) (int) ($data['schema']['org_number_employees'] ?? 0)); ?>" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <?php echo esc_html__('VAT ID', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[schema][org_vat_id]" value="<?php echo esc_attr((string) ($data['schema']['org_vat_id'] ?? '')); ?>" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <?php echo esc_html__('Tax ID', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[schema][org_tax_id]" value="<?php echo esc_attr((string) ($data['schema']['org_tax_id'] ?? '')); ?>" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <?php echo esc_html__('ISO 6523 code', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[schema][org_iso6523_code]" value="<?php echo esc_attr((string) ($data['schema']['org_iso6523_code'] ?? '')); ?>" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <?php echo esc_html__('DUNS', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[schema][org_duns]" value="<?php echo esc_attr((string) ($data['schema']['org_duns'] ?? '')); ?>" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <?php echo esc_html__('LEI code', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[schema][org_lei_code]" value="<?php echo esc_attr((string) ($data['schema']['org_lei_code'] ?? '')); ?>" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <?php echo esc_html__('NAICS', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[schema][org_naics]" value="<?php echo esc_attr((string) ($data['schema']['org_naics'] ?? '')); ?>" />
                                </label>
                            </p>
                            <p class="description"><?php echo esc_html__('Optional structured identifiers for Organization schema. Useful when importing richer business settings from Yoast and similar plugins.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr class="wpsn-ui-pro-only">
                        <th scope="row"><?php echo esc_html__('Default schema type by post type', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $schemaDefaultTypes = isset($data['schema']['default_types']) && is_array($data['schema']['default_types']) ? $data['schema']['default_types'] : [];
                                $schemaDefaultPostTypes = get_post_types(['public' => true], 'objects');
                                if (!is_array($schemaDefaultPostTypes)) {
                                    $schemaDefaultPostTypes = [];
                                }
                            ?>
                            <?php foreach ($schemaDefaultPostTypes as $postType => $postTypeObject) : ?>
                                <?php
                                    $postType = sanitize_key((string) $postType);
                                    if ($postType === '' || $postType === 'attachment') {
                                        continue;
                                    }
                                    $label = is_object($postTypeObject) && isset($postTypeObject->labels) && isset($postTypeObject->labels->singular_name)
                                        ? (string) $postTypeObject->labels->singular_name
                                        : $postType;
                                    $defaultType = isset($schemaDefaultTypes[$postType]) ? (string) $schemaDefaultTypes[$postType] : '';
                                ?>
                                <p<?php echo $postType === 'post' ? ' style="margin-top:0;"' : ''; ?>>
                                    <label>
                                        <?php echo esc_html(sprintf(__('Default for %s', 'wp-seo-next'), $label)); ?><br/>
                                        <select name="wpsn[schema][default_types][<?php echo esc_attr($postType); ?>]">
                                            <option value="" <?php selected($defaultType, ''); ?>><?php echo esc_html__('Auto (module default)', 'wp-seo-next'); ?></option>
                                            <option value="article" <?php selected($defaultType, 'article'); ?>><?php echo esc_html__('Article (BlogPosting)', 'wp-seo-next'); ?></option>
                                            <option value="webpage" <?php selected($defaultType, 'webpage'); ?>><?php echo esc_html__('WebPage', 'wp-seo-next'); ?></option>
                                            <?php if ($postType === 'product') : ?>
                                                <option value="product" <?php selected($defaultType, 'product'); ?>><?php echo esc_html__('Product (WooCommerce)', 'wp-seo-next'); ?></option>
                                            <?php endif; ?>
                                            <option value="none" <?php selected($defaultType, 'none'); ?>><?php echo esc_html__('Disable schema by default', 'wp-seo-next'); ?></option>
                                        </select>
                                    </label>
                                </p>
                            <?php endforeach; ?>
                            <p class="description"><?php echo esc_html__('These defaults apply only when a post does not have its own per-post schema override.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                <div class="wpsn-ui-pro-only">
                    <h3><?php echo esc_html__('Custom JSON-LD templates', 'wp-seo-next'); ?></h3>
                    <p class="description">
                        <?php echo esc_html__('Append extra schema nodes by post type. This is useful for FAQ, HowTo, Event, Recipe, Review, Service, or bespoke schema shapes that are not part of the default graph.', 'wp-seo-next'); ?>
                    </p>
                    <p class="description" style="margin-top:8px;">
                        <?php echo esc_html__('Built-in starter library: FAQ, HowTo, Event, Recipe, Review, Service. Pick a starter below to load a safe template into any post type field.', 'wp-seo-next'); ?>
                    </p>

                    <?php
                        $schemaCustom = isset($data['schema']['custom_json_ld']) && is_array($data['schema']['custom_json_ld']) ? $data['schema']['custom_json_ld'] : [];
                        $schemaTemplates = isset($schemaCustom['post_type_templates']) && is_array($schemaCustom['post_type_templates']) ? $schemaCustom['post_type_templates'] : [];
                        $schemaTemplatePostTypes = get_post_types(['public' => true], 'objects');
                        if (!is_array($schemaTemplatePostTypes)) {
                            $schemaTemplatePostTypes = [];
                        }
                    ?>

                    <table class="form-table" role="presentation">
                        <?php foreach ($schemaTemplatePostTypes as $postType => $postTypeObject) : ?>
                            <?php
                                $postType = sanitize_key((string) $postType);
                                if ($postType === '' || $postType === 'attachment') {
                                    continue;
                                }

                                $label = is_object($postTypeObject) && isset($postTypeObject->labels) && isset($postTypeObject->labels->singular_name)
                                    ? (string) $postTypeObject->labels->singular_name
                                    : $postType;

                                $templateValue = isset($schemaTemplates[$postType]) ? (string) $schemaTemplates[$postType] : '';
                            ?>
                            <tr>
                                <th scope="row"><?php echo esc_html(sprintf(__('Template for %s', 'wp-seo-next'), $label)); ?></th>
                                <td>
                                    <?php $schemaTemplateFieldId = 'wpsn_schema_template_' . $postType; ?>
                                    <?php SchemaTypeLibrary::renderPicker($schemaTemplateFieldId); ?>
                                    <textarea id="<?php echo esc_attr($schemaTemplateFieldId); ?>" class="large-text code" rows="6" name="wpsn[schema][custom_json_ld][post_type_templates][<?php echo esc_attr($postType); ?>]" placeholder='{"@type":"FAQPage","name":%title|json%}'><?php echo esc_textarea($templateValue); ?></textarea>
                                    <p class="description">
                                        <?php echo esc_html__('Leave empty to disable for this post type. Accepts a single node object, an array of nodes, or a full @graph object. Tokens are supported; use %title|json% for string values inside JSON.', 'wp-seo-next'); ?>
                                    </p>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </table>
                    <?php SchemaTypeLibrary::renderInlineScript(); ?>
                </div>


                <div class="wpsn-ui-pro-only">

                <h2 id="wpsn-settings-local" class="title"><?php echo esc_html__('Local SEO', 'wp-seo-next'); ?></h2>
                <p class="description">
                    <?php echo esc_html__('Business info (NAP) + LocalBusiness schema + locations KML/sitemap. For multiple locations, add Location posts in Tools → Locations.', 'wp-seo-next'); ?>
                </p>

                <?php
                    $local = isset($data['local']) && is_array($data['local']) ? $data['local'] : [];
                    $localSchema = isset($local['schema']) && is_array($local['schema']) ? $local['schema'] : [];
                    $localBusiness = isset($local['business']) && is_array($local['business']) ? $local['business'] : [];
                    $localKml = isset($local['kml']) && is_array($local['kml']) ? $local['kml'] : [];
                    $localSm = isset($local['locations_sitemap']) && is_array($local['locations_sitemap']) ? $local['locations_sitemap'] : [];
                    $localNap = isset($local['nap']) && is_array($local['nap']) ? $local['nap'] : [];
                    $primaryLocId = isset($local['primary_location_id']) ? (int) $local['primary_location_id'] : 0;
                ?>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('LocalBusiness schema', 'wp-seo-next'); ?></th>
                        <td>
                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[local][schema][enabled]" value="1" <?php checked(!empty($localSchema['enabled'])); ?> />
                                <?php echo esc_html__('Enable LocalBusiness schema output', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[local][schema][show_on_home]" value="1" <?php checked(!empty($localSchema['show_on_home'])); ?> />
                                <?php echo esc_html__('Also output LocalBusiness on the home page', 'wp-seo-next'); ?>
                            </label>

                            <p style="margin: 10px 0 0;">
                                <label>
                                    <?php echo esc_html__('Business type (Schema.org)', 'wp-seo-next'); ?>
                                    <input type="text" class="regular-text" name="wpsn[local][schema][business_type]" value="<?php echo esc_attr((string) ($localSchema['business_type'] ?? 'LocalBusiness')); ?>" placeholder="LocalBusiness" />
                                </label>
                            </p>

                            <p class="description" style="margin: 6px 0 0;">
                                <?php echo esc_html__('Examples: LocalBusiness, Restaurant, Dentist, LegalService, AutoRepair, Store.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Locations sitemap & KML', 'wp-seo-next'); ?></th>
                        <td>
                            <p style="margin-top:0;">
                                <label style="display:block; margin: 4px 0;">
                                    <input type="checkbox" name="wpsn[local][locations_sitemap][enabled]" value="1" <?php checked(!empty($localSm['enabled'])); ?> />
                                    <?php echo esc_html__('Enable locations sitemap', 'wp-seo-next'); ?>
                                </label>
                                <span class="description"><?php echo esc_html__('URL:', 'wp-seo-next'); ?> <code><?php echo esc_html((string) home_url('/locations-sitemap.xml')); ?></code></span>
                            </p>

                            <p>
                                <label style="display:block; margin: 4px 0;">
                                    <input type="checkbox" name="wpsn[local][kml][enabled]" value="1" <?php checked(!empty($localKml['enabled'])); ?> />
                                    <?php echo esc_html__('Enable locations KML', 'wp-seo-next'); ?>
                                </label>
                                <span class="description"><?php echo esc_html__('URL:', 'wp-seo-next'); ?> <code><?php echo esc_html((string) home_url('/locations.kml')); ?></code></span>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Primary location', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $hasCpt = post_type_exists('wpsn_location');
                                $locOptions = [];
                                if ($hasCpt) {
                                    $locOptions = get_posts([
                                        'post_type' => 'wpsn_location',
                                        'post_status' => 'publish',
                                        'posts_per_page' => 200,
                                        'orderby' => 'title',
                                        'order' => 'ASC',
                                        'no_found_rows' => true,
                                        'suppress_filters' => true,
                                    ]);
                                    $locOptions = is_array($locOptions) ? $locOptions : [];
                                }
                            ?>

                            <p style="margin-top:0;">
                                <select name="wpsn[local][primary_location_id]">
                                    <option value="0" <?php selected($primaryLocId, 0); ?>><?php echo esc_html__('— Use Business info (NAP) from settings —', 'wp-seo-next'); ?></option>
                                    <?php if (!empty($locOptions)) : ?>
                                        <?php foreach ($locOptions as $p) : ?>
                                            <?php if (!($p instanceof \WP_Post)) { continue; } ?>
                                            <?php $pid = (int) $p->ID; ?>
                                            <?php $title = trim((string) $p->post_title); ?>
                                            <?php if ($title === '') { $title = sprintf('#%d', $pid); } ?>
                                            <option value="<?php echo esc_attr((string) $pid); ?>" <?php selected($primaryLocId, $pid); ?>><?php echo esc_html($title); ?></option>
                                        <?php endforeach; ?>
                                    <?php endif; ?>
                                </select>
                            </p>

                            <p class="description" style="margin: 6px 0 0;">
                                <?php echo esc_html__('Used as a default for the NAP block/shortcode and for LocalBusiness schema on the home page (when enabled).', 'wp-seo-next'); ?>
                                <?php if (!$hasCpt) : ?>
                                    <br/><?php echo esc_html__('Enable the Local SEO module to manage Location posts.', 'wp-seo-next'); ?>
                                <?php else : ?>
                                    <br/><?php echo esc_html__('Manage locations in Tools → Locations.', 'wp-seo-next'); ?>
                                <?php endif; ?>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('NAP output defaults', 'wp-seo-next'); ?></th>
                        <td>
                            <?php $napTpl = isset($localNap['template']) ? (string) $localNap['template'] : 'plain'; ?>
                            <p style="margin-top:0;">
                                <label>
                                    <?php echo esc_html__('Template', 'wp-seo-next'); ?>
                                    <select name="wpsn[local][nap][template]">
                                        <option value="plain" <?php selected($napTpl, 'plain'); ?>><?php echo esc_html__('Plain (one-line address)', 'wp-seo-next'); ?></option>
                                        <option value="multiline" <?php selected($napTpl, 'multiline'); ?>><?php echo esc_html__('Multiline address', 'wp-seo-next'); ?></option>
                                        <option value="icons" <?php selected($napTpl, 'icons'); ?>><?php echo esc_html__('Icons', 'wp-seo-next'); ?></option>
                                        <option value="icons_multiline" <?php selected($napTpl, 'icons_multiline'); ?>><?php echo esc_html__('Icons + multiline address', 'wp-seo-next'); ?></option>
                                    </select>
                                </label>
                            </p>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[local][nap][microdata]" value="1" <?php checked(!empty($localNap['microdata'])); ?> />
                                <?php echo esc_html__('Enable HTML microdata (itemscope/itemprop) in NAP output', 'wp-seo-next'); ?>
                            </label>

                            <p class="description" style="margin: 6px 0 0;">
                                <?php echo esc_html__('Applies to the [wpsn_nap] shortcode defaults. The NAP block can override these per-block in the editor.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Business info (NAP)', 'wp-seo-next'); ?></th>
                        <td>
                            <p style="margin-top:0;">
                                <label>
                                    <?php echo esc_html__('Business name', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[local][business][name]" value="<?php echo esc_attr((string) ($localBusiness['name'] ?? '')); ?>" />
                                </label>
                            </p>

                            <p>
                                <label>
                                    <?php echo esc_html__('Telephone', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[local][business][telephone]" value="<?php echo esc_attr((string) ($localBusiness['telephone'] ?? '')); ?>" placeholder="+1 555 123 4567" />
                                </label>
                            </p>

                            <p>
                                <label>
                                    <?php echo esc_html__('Email', 'wp-seo-next'); ?><br/>
                                    <input type="email" class="regular-text" name="wpsn[local][business][email]" value="<?php echo esc_attr((string) ($localBusiness['email'] ?? '')); ?>" />
                                </label>
                            </p>

                            <p>
                                <label>
                                    <?php echo esc_html__('Street address', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[local][business][street_address]" value="<?php echo esc_attr((string) ($localBusiness['street_address'] ?? '')); ?>" />
                                </label>
                            </p>

                            <p>
                                <label>
                                    <?php echo esc_html__('City / Locality', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[local][business][address_locality]" value="<?php echo esc_attr((string) ($localBusiness['address_locality'] ?? '')); ?>" />
                                </label>
                            </p>

                            <p>
                                <label>
                                    <?php echo esc_html__('Region / State', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[local][business][address_region]" value="<?php echo esc_attr((string) ($localBusiness['address_region'] ?? '')); ?>" />
                                </label>
                            </p>

                            <p>
                                <label>
                                    <?php echo esc_html__('Postal code', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[local][business][postal_code]" value="<?php echo esc_attr((string) ($localBusiness['postal_code'] ?? '')); ?>" />
                                </label>
                            </p>

                            <p>
                                <label>
                                    <?php echo esc_html__('Country', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[local][business][address_country]" value="<?php echo esc_attr((string) ($localBusiness['address_country'] ?? '')); ?>" placeholder="US" />
                                </label>
                            </p>

                            <p>
                                <label>
                                    <?php echo esc_html__('Latitude', 'wp-seo-next'); ?>
                                    <input type="text" name="wpsn[local][business][latitude]" value="<?php echo esc_attr((string) ($localBusiness['latitude'] ?? '')); ?>" style="width:140px;" placeholder="55.7558" />
                                </label>
                                &nbsp;
                                <label>
                                    <?php echo esc_html__('Longitude', 'wp-seo-next'); ?>
                                    <input type="text" name="wpsn[local][business][longitude]" value="<?php echo esc_attr((string) ($localBusiness['longitude'] ?? '')); ?>" style="width:140px;" placeholder="37.6173" />
                                </label>
                            </p>

                            <p>
                                <label>
                                    <?php echo esc_html__('Price range', 'wp-seo-next'); ?><br/>
                                    <input type="text" class="regular-text" name="wpsn[local][business][price_range]" value="<?php echo esc_attr((string) ($localBusiness['price_range'] ?? '')); ?>" placeholder="$$" />
                                </label>
                            </p>

                            <p>
                                <label>
                                    <?php echo esc_html__('Opening hours (one per line)', 'wp-seo-next'); ?><br/>
                                    <textarea class="large-text" rows="4" name="wpsn[local][business][opening_hours]" placeholder="Mo-Fr 09:00-18:00\nSa 10:00-14:00"><?php echo esc_textarea((string) ($localBusiness['opening_hours'] ?? '')); ?></textarea>
                                </label>
                                <span class="description"><?php echo esc_html__('We will parse these rules into schema.org openingHoursSpecification when possible.', 'wp-seo-next'); ?></span>
                            </p>
                        </td>
                    </tr>
                </table>


                

                </div>

                <h2 id="wpsn-settings-social" class="title"><?php echo esc_html__('Social', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Defaults for OpenGraph/Twitter cards. Per-post overrides are available in the editor.', 'wp-seo-next'); ?></p>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Default OG image URL', 'wp-seo-next'); ?></th>
                        <td>
                            <?php $defaultOg = (string) ($data['social']['default_image_url'] ?? ''); ?>
                            <div class="wpsn-media-field">
                                <input id="wpsn_social_default_og" type="url" class="large-text wpsn-media-url" name="wpsn[social][default_image_url]" value="<?php echo esc_attr($defaultOg); ?>" placeholder="https://..." />
                                <p style="margin-top:8px;">
                                    <button type="button" class="button wpsn-media-select" data-title="<?php echo esc_attr__('Select default OG image', 'wp-seo-next'); ?>" data-button="<?php echo esc_attr__('Use this image', 'wp-seo-next'); ?>"><?php echo esc_html__('Select from media library', 'wp-seo-next'); ?></button>
                                    <button type="button" class="button wpsn-media-clear"><?php echo esc_html__('Clear', 'wp-seo-next'); ?></button>
                                </p>
                                <img class="wpsn-media-preview" src="<?php echo esc_url($defaultOg); ?>" style="<?php echo $defaultOg !== '' ? 'max-width:360px;height:auto;border:1px solid rgba(0,0,0,.12);border-radius:6px;' : 'display:none;max-width:360px;height:auto;border:1px solid rgba(0,0,0,.12);border-radius:6px;'; ?>" alt="" />
                                <p class="description"><?php echo esc_html__('Used when a page has no Featured Image and no per-post OG image override. Recommended size: 1200×630.', 'wp-seo-next'); ?></p>
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Fallbacks', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[social][fallback_author_image]" value="1" <?php checked(!empty($data['social']['fallback_author_image'] ?? false)); ?> />
                                <?php echo esc_html__('Use author image as fallback for posts without a Featured Image', 'wp-seo-next'); ?>
                            </label>
                            <p class="description"><?php echo esc_html__('If enabled, we will use the author profile image (Settings → Users → WP SEO Next — Author SEO) before the global default OG image.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                <div class="wpsn-ui-pro-only">

                <h2 class="title"><?php echo esc_html__('WooCommerce', 'wp-seo-next'); ?></h2>
                <p class="description">
                    <?php echo esc_html__('Optional WooCommerce SEO integration: Product schema and product-specific OpenGraph meta.', 'wp-seo-next'); ?>
                </p>

                <?php if (!class_exists('WooCommerce')) : ?>
                    <div class="notice notice-warning" style="margin: 10px 0 12px;">
                        <p><?php echo esc_html__('WooCommerce is not active. These settings will apply once WooCommerce is installed and activated.', 'wp-seo-next'); ?></p>
                    </div>
                <?php endif; ?>

                <?php
                    $wc = isset($data['woocommerce']) && is_array($data['woocommerce']) ? $data['woocommerce'] : [];
                    $wcSchema = isset($wc['schema']) && is_array($wc['schema']) ? $wc['schema'] : [];
                    $wcSocial = isset($wc['social']) && is_array($wc['social']) ? $wc['social'] : [];
                    $wcCanonical = isset($wc['canonical']) && is_array($wc['canonical']) ? $wc['canonical'] : [];
                    $wcMerchant = isset($wc['merchant_feed']) && is_array($wc['merchant_feed']) ? $wc['merchant_feed'] : [];
                ?>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Product schema', 'wp-seo-next'); ?></th>
                        <td>
                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[woocommerce][schema][enabled]" value="1" <?php checked(!empty($wcSchema['enabled'])); ?> />
                                <?php echo esc_html__('Enable Product JSON-LD schema for WooCommerce products', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[woocommerce][schema][disable_wc_structured_data]" value="1" <?php checked(!empty($wcSchema['disable_wc_structured_data'])); ?> />
                                <?php echo esc_html__('Disable WooCommerce built-in structured data (avoid duplicate schema)', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Product OpenGraph meta', 'wp-seo-next'); ?></th>
                        <td>
                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[woocommerce][social][enabled]" value="1" <?php checked(!empty($wcSocial['enabled'])); ?> />
                                <?php echo esc_html__('Enable product OpenGraph tags (price/currency/availability)', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[woocommerce][social][set_og_type_product]" value="1" <?php checked(!empty($wcSocial['set_og_type_product'])); ?> />
                                <?php echo esc_html__('Set og:type to "product" on product pages', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[woocommerce][social][include_price]" value="1" <?php checked(!empty($wcSocial['include_price'])); ?> />
                                <?php echo esc_html__('Include product price and currency', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[woocommerce][social][include_availability]" value="1" <?php checked(!empty($wcSocial['include_availability'])); ?> />
                                <?php echo esc_html__('Include availability (in stock / out of stock)', 'wp-seo-next'); ?>
                            </label>

                            <p class="description" style="margin: 6px 0 0;">
                                <?php echo esc_html__('These tags are output in addition to standard OpenGraph/Twitter tags from the Social module.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Canonicals & robots (filters)', 'wp-seo-next'); ?></th>
                        <td>
                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[woocommerce][canonical][strip_filter_args]" value="1" <?php checked(!empty($wcCanonical['strip_filter_args'] ?? true)); ?> />
                                <?php echo esc_html__('Strip WooCommerce filter/query parameters from canonical URLs', 'wp-seo-next'); ?>
                            </label>

                            <p class="description" style="margin: 6px 0 10px;">
                                <?php echo esc_html__('Recommended to reduce duplicate URLs caused by layered navigation (filter_* / query_type_*), price filters (min_price/max_price) and product variation params (attribute_*).', 'wp-seo-next'); ?>
                            </p>

                            <label style="display:block; margin: 4px 0;">
                                <?php echo esc_html__('Extra query args to strip (comma-separated)', 'wp-seo-next'); ?><br/>
                                <input type="text" class="regular-text" name="wpsn[woocommerce][canonical][extra_strip_args]" value="<?php echo esc_attr((string) ($wcCanonical['extra_strip_args'] ?? '')); ?>" placeholder="utm_source, utm_medium" />
                            </label>
                            <p class="description" style="margin: 6px 0 10px;">
                                <?php echo esc_html__('Only used on WooCommerce pages. Do not include core permalink args like p, page_id or paged.', 'wp-seo-next'); ?>
                            </p>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[woocommerce][canonical][noindex_filtered_archives]" value="1" <?php checked(!empty($wcCanonical['noindex_filtered_archives'] ?? false)); ?> />
                                <?php echo esc_html__('Noindex filtered shop/category pages when filter params are present', 'wp-seo-next'); ?>
                            </label>
                            <p class="description" style="margin: 6px 0 0;">
                                <?php echo esc_html__('Use with caution: if you rely on indexed filter pages for SEO, keep this disabled.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Merchant feed', 'wp-seo-next'); ?></th>
                        <td>
                            <?php $mfUrl = home_url('/merchant-feed.xml'); ?>
                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[woocommerce][merchant_feed][enabled]" value="1" <?php checked(!empty($wcMerchant['enabled'])); ?> />
                                <?php echo esc_html__('Enable Google Merchant / Shopping feed', 'wp-seo-next'); ?>
                            </label>

                            <p class="description" style="margin: 6px 0 10px;">
                                <?php echo esc_html__('Feed URL:', 'wp-seo-next'); ?>
                                <code><?php echo esc_html((string) $mfUrl); ?></code>
                            </p>

                            <div style="display:flex; flex-wrap:wrap; gap: 14px; align-items:flex-start; margin: 8px 0 0;">
                                <label style="display:block; min-width: 240px;">
                                    <input type="checkbox" name="wpsn[woocommerce][merchant_feed][include_variations]" value="1" <?php checked(!empty($wcMerchant['include_variations'])); ?> />
                                    <?php echo esc_html__('Include variations as separate items', 'wp-seo-next'); ?>
                                </label>

                                <label style="display:block; min-width: 240px;">
                                    <input type="checkbox" name="wpsn[woocommerce][merchant_feed][in_stock_only]" value="1" <?php checked(!empty($wcMerchant['in_stock_only'])); ?> />
                                    <?php echo esc_html__('In-stock only', 'wp-seo-next'); ?>
                                </label>

                                <label style="display:block; min-width: 240px;">
                                    <input type="checkbox" name="wpsn[woocommerce][merchant_feed][exclude_hidden]" value="1" <?php checked(!empty($wcMerchant['exclude_hidden'])); ?> />
                                    <?php echo esc_html__('Exclude hidden products', 'wp-seo-next'); ?>
                                </label>
                            </div>

                            <div style="display:flex; flex-wrap:wrap; gap: 14px; align-items:center; margin: 10px 0 0;">
                                <label>
                                    <?php echo esc_html__('Posts per batch', 'wp-seo-next'); ?>
                                    <input type="number" min="10" max="2000" step="10" name="wpsn[woocommerce][merchant_feed][posts_per_page]" value="<?php echo esc_attr((string) ((int) ($wcMerchant['posts_per_page'] ?? 200))); ?>" style="width:110px;" />
                                </label>

                                <label>
                                    <?php echo esc_html__('Max products (0 = unlimited)', 'wp-seo-next'); ?>
                                    <input type="number" min="0" max="500000" step="1" name="wpsn[woocommerce][merchant_feed][max_products]" value="<?php echo esc_attr((string) ((int) ($wcMerchant['max_products'] ?? 0))); ?>" style="width:140px;" />
                                </label>

                                <label>
                                    <?php echo esc_html__('Condition', 'wp-seo-next'); ?>
                                    <?php $cond = (string) ($wcMerchant['condition'] ?? 'new'); ?>
                                    <select name="wpsn[woocommerce][merchant_feed][condition]">
                                        <option value="new" <?php selected($cond, 'new'); ?>><?php echo esc_html__('New', 'wp-seo-next'); ?></option>
                                        <option value="used" <?php selected($cond, 'used'); ?>><?php echo esc_html__('Used', 'wp-seo-next'); ?></option>
                                        <option value="refurbished" <?php selected($cond, 'refurbished'); ?>><?php echo esc_html__('Refurbished', 'wp-seo-next'); ?></option>
                                    </select>
                                </label>

                                <label>
                                    <?php echo esc_html__('Cache TTL (sec, 0 = off)', 'wp-seo-next'); ?>
                                    <input type="number" min="0" max="21600" step="60" name="wpsn[woocommerce][merchant_feed][cache_ttl_sec]" value="<?php echo esc_attr((string) ((int) ($wcMerchant['cache_ttl_sec'] ?? 0))); ?>" style="width:120px;" />
                                </label>
                            </div>

                            <p class="description" style="margin: 10px 0 0;">
                                <?php echo esc_html__('The feed is generated on-demand (virtual endpoint). For very large catalogs, consider enabling cache TTL if you have an object cache.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>
                </table>

                

                </div>

                <div class="wpsn-ui-pro-only">

                <h2 class="title"><?php echo esc_html__('Media SEO', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Options used by Tools → SEO Media → Filenames (filename cleanup drafts).', 'wp-seo-next'); ?></p>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Dirty filename detector', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $dg = $data['media']['filenames']['dirty_groups'] ?? [];
                                if (!is_array($dg)) {
                                    $dg = [];
                                }
                            ?>

                            <p style="margin-top:0;">
                                <?php echo esc_html__('When "Only if dirty" is enabled, these patterns will be treated as low-quality filenames even if they are ASCII.', 'wp-seo-next'); ?>
                            </p>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[media][filenames][dirty_groups][camera]" value="1" <?php checked(!empty($dg['camera'])); ?> />
                                <?php echo esc_html__('Camera defaults (IMG_1234 / DSC0001 / PXL_… / image-123)', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[media][filenames][dirty_groups][screenshot]" value="1" <?php checked(!empty($dg['screenshot'])); ?> />
                                <?php echo esc_html__('Screenshots (screenshot-… / screen-shot-…)', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[media][filenames][dirty_groups][messenger]" value="1" <?php checked(!empty($dg['messenger'])); ?> />
                                <?php echo esc_html__('Messengers (whatsapp-image / telegram-image / signal-…)', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[media][filenames][dirty_groups][editor]" value="1" <?php checked(!empty($dg['editor'])); ?> />
                                <?php echo esc_html__('Editor leftovers (copy-of / edited / cropped / resized / pasted-image)', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[media][filenames][dirty_groups][untitled]" value="1" <?php checked(!empty($dg['untitled'])); ?> />
                                <?php echo esc_html__('Untitled / scans (untitled / scan)', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[media][filenames][dirty_groups][numeric]" value="1" <?php checked(!empty($dg['numeric'])); ?> />
                                <?php echo esc_html__('Mostly numeric / timestamps', 'wp-seo-next'); ?>
                            </label>

                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[media][filenames][dirty_groups][hash]" value="1" <?php checked(!empty($dg['hash'])); ?> />
                                <?php echo esc_html__('Hash-like names (a3f9d0…)', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Custom dirty prefixes', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $custom = $data['media']['filenames']['custom_prefixes'] ?? '';
                                $custom = is_string($custom) ? $custom : '';
                            ?>
                            <textarea class="large-text" rows="3" name="wpsn[media][filenames][custom_prefixes]" placeholder="banner\nhero\nproduct\nimg\n..."><?php echo esc_textarea($custom); ?></textarea>
                            <p class="description">
                                <?php echo esc_html__('One prefix per line. Example: "banner" will treat banner-123.jpg as dirty and suggest a better name.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>
                </table>

                

                </div>

                <h2 class="title" id="wpsn-sitemaps"><?php echo esc_html__('Sitemaps', 'wp-seo-next'); ?></h2>
                <p class="description">
                    <?php
                        $sitemapIndexUrl = home_url('/sitemap_index.xml');
                        printf(
                            /* translators: %s is the sitemap index URL */
                            esc_html__('Sitemap index: %s', 'wp-seo-next'),
                            sprintf('<a href="%1$s" target="_blank" rel="noopener">%1$s</a>', esc_url($sitemapIndexUrl))
                        );
                    ?>
                    &nbsp;
                    <a class="button button-secondary" href="<?php echo esc_url(admin_url('tools.php?page=wpsn-sitemaps')); ?>">
                        <?php echo esc_html__('Open Sitemap Center', 'wp-seo-next'); ?>
                    </a>
                </p>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('URLs per sitemap', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="100" max="50000" name="wpsn[sitemap][urls_per_sitemap]" value="<?php echo esc_attr((string) ($data['sitemap']['urls_per_sitemap'] ?? 1000)); ?>" />
                            <p class="description"><?php echo esc_html__('Google supports up to 50,000 URLs per sitemap, but smaller files are often faster.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Include taxonomies', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[sitemap][include_taxonomies]" value="1" <?php checked(!empty($data['sitemap']['include_taxonomies'])); ?> />
                                <?php echo esc_html__('Add taxonomy term URLs (categories, tags, etc.)', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Image sitemap', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $im = $data['sitemap']['images'] ?? [];
                                if (!is_array($im)) {
                                    $im = [];
                                }
                                $imEnabled = !empty($im['enabled']);
                                $imMax = isset($im['max_per_url']) ? (int) $im['max_per_url'] : 5;
                            ?>
                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[sitemap][images][enabled]" value="1" <?php checked($imEnabled); ?> />
                                <?php echo esc_html__('Add images to each post URL entry (<image:image>).', 'wp-seo-next'); ?>
                            </label>
                            <p class="description">
                                <?php echo esc_html__('When enabled, featured images and/or images found in post content will be included in post sitemaps.', 'wp-seo-next'); ?>
                            </p>

                            <div style="margin-top:8px;">
                                <label style="display:inline-block; margin-right: 14px;">
                                    <input type="checkbox" name="wpsn[sitemap][images][include_featured]" value="1" <?php checked(!empty($im['include_featured'])); ?> />
                                    <?php echo esc_html__('Featured image', 'wp-seo-next'); ?>
                                </label>
                                <label style="display:inline-block; margin-right: 14px;">
                                    <input type="checkbox" name="wpsn[sitemap][images][include_content]" value="1" <?php checked(!empty($im['include_content'])); ?> />
                                    <?php echo esc_html__('Images in content', 'wp-seo-next'); ?>
                                </label>
                            </div>

                            <div style="margin-top:8px;">
                                <label>
                                    <?php echo esc_html__('Max images per URL:', 'wp-seo-next'); ?>
                                    <input type="number" min="1" max="100" name="wpsn[sitemap][images][max_per_url]" value="<?php echo esc_attr((string) $imMax); ?>" style="width:90px;" />
                                </label>
                            </div>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Google News sitemap', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $news = $data['sitemap']['news'] ?? [];
                                if (!is_array($news)) {
                                    $news = [];
                                }
                                $newsEnabled = !empty($news['enabled']);
                                $newsUrl = home_url('/news-sitemap.xml');
                                $siteLang = strtolower((string) substr((string) get_locale(), 0, 2));
                                if ($siteLang === '') {
                                    $siteLang = 'en';
                                }
                            ?>
                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[sitemap][news][enabled]" value="1" <?php checked($newsEnabled); ?> />
                                <?php
                                    printf(
                                        /* translators: %s is the News sitemap URL */
                                        esc_html__('Enable Google News sitemap at %s', 'wp-seo-next'),
                                        sprintf('<a href="%1$s" target="_blank" rel="noopener">%1$s</a>', esc_url($newsUrl))
                                    );
                                ?>
                            </label>

                            <p class="description">
                                <?php echo esc_html__('Includes up to 1,000 recently published URLs (last 48 hours). Google News requires correct publication name + language.', 'wp-seo-next'); ?>
                            </p>

                            <div style="margin-top:8px; display:flex; gap:12px; flex-wrap:wrap;">
                                <label>
                                    <?php echo esc_html__('Publication name', 'wp-seo-next'); ?>
                                    <input type="text" class="regular-text" name="wpsn[sitemap][news][publication_name]" value="<?php echo esc_attr((string) ($news['publication_name'] ?? '')); ?>" placeholder="<?php echo esc_attr(get_bloginfo('name')); ?>" />
                                </label>

                                <label>
                                    <?php echo esc_html__('Language', 'wp-seo-next'); ?>
                                    <input type="text" class="small-text" name="wpsn[sitemap][news][language]" value="<?php echo esc_attr((string) ($news['language'] ?? $siteLang)); ?>" placeholder="<?php echo esc_attr($siteLang); ?>" />
                                    <span class="description"><?php echo esc_html__('e.g., en, en-us', 'wp-seo-next'); ?></span>
                                </label>

                                <label>
                                    <?php echo esc_html__('Genres', 'wp-seo-next'); ?>
                                    <input type="text" class="regular-text" name="wpsn[sitemap][news][genres]" value="<?php echo esc_attr((string) ($news['genres'] ?? '')); ?>" placeholder="<?php echo esc_attr__('PressRelease, Blog', 'wp-seo-next'); ?>" />
                                </label>
                            </div>

                            <div style="margin-top:8px;">
                                <label>
                                    <input type="checkbox" name="wpsn[sitemap][news][include_keywords]" value="1" <?php checked(!empty($news['include_keywords'])); ?> />
                                    <?php echo esc_html__('Include keywords from categories/tags (<news:keywords>).', 'wp-seo-next'); ?>
                                </label>
                            </div>

                            <details style="margin-top:10px;">
                                <summary><?php echo esc_html__('Post types for News sitemap', 'wp-seo-next'); ?></summary>
                                <div style="margin-top:8px;">
                                    <?php
                                        $newsPt = $news['post_types'] ?? [];
                                        if (!is_array($newsPt)) {
                                            $newsPt = [];
                                        }
                                        $ptAllNews = get_post_types(['public' => true], 'objects');
                                    ?>
                                    <?php foreach ($ptAllNews as $pt => $obj) :
                                        if ($pt === 'attachment') {
                                            continue;
                                        }
                                        $checked = empty($newsPt) ? ($pt === 'post') : !empty($newsPt[$pt]);
                                    ?>
                                        <label style="display:block; margin: 2px 0;">
                                            <input type="checkbox" name="wpsn[sitemap][news][post_types][<?php echo esc_attr($pt); ?>]" value="1" <?php checked($checked); ?> />
                                            <?php echo esc_html($obj->labels->singular_name ?? $pt); ?>
                                            <code style="opacity:.7"><?php echo esc_html($pt); ?></code>
                                        </label>
                                    <?php endforeach; ?>
                                </div>
                            </details>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Video sitemap', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $vid = $data['sitemap']['video'] ?? [];
                                if (!is_array($vid)) {
                                    $vid = [];
                                }
                                $vidEnabled = !empty($vid['enabled']);
                                $vidUrl = home_url('/video-sitemap.xml');
                                $vidMode = isset($vid['mode']) ? (string) $vid['mode'] : 'meta';
                            ?>
                            <label style="display:block; margin: 4px 0;">
                                <input type="checkbox" name="wpsn[sitemap][video][enabled]" value="1" <?php checked($vidEnabled); ?> />
                                <?php
                                    printf(
                                        /* translators: %s is the Video sitemap URL */
                                        esc_html__('Enable Video sitemap at %s', 'wp-seo-next'),
                                        sprintf('<a href="%1$s" target="_blank" rel="noopener">%1$s</a>', esc_url($vidUrl))
                                    );
                                ?>
                            </label>

                            <p class="description">
                                <?php echo esc_html__('Includes URLs that have video meta set. Required post meta: _wpsn_video_url. Optional: _wpsn_video_thumbnail, _wpsn_video_title, _wpsn_video_description, _wpsn_video_duration (seconds).', 'wp-seo-next'); ?>
                            </p>

                            <div style="margin-top:8px; display:flex; gap:12px; flex-wrap:wrap; align-items:center;">
                                <label>
                                    <?php echo esc_html__('Mode', 'wp-seo-next'); ?>
                                    <select name="wpsn[sitemap][video][mode]">
                                        <option value="meta" <?php selected($vidMode, 'meta'); ?>><?php echo esc_html__('Meta only', 'wp-seo-next'); ?></option>
                                        <option value="youtube_auto" <?php selected($vidMode, 'youtube_auto'); ?>><?php echo esc_html__('Meta + YouTube auto-detect fallback', 'wp-seo-next'); ?></option>
                                    </select>
                                </label>

                                <label>
                                    <input type="checkbox" name="wpsn[sitemap][video][include_featured_thumbnail]" value="1" <?php checked(!empty($vid['include_featured_thumbnail'])); ?> />
                                    <?php echo esc_html__('Fallback to featured image as video thumbnail.', 'wp-seo-next'); ?>
                                </label>
                            </div>

                            <details style="margin-top:10px;">
                                <summary><?php echo esc_html__('Post types for Video sitemap', 'wp-seo-next'); ?></summary>
                                <div style="margin-top:8px;">
                                    <?php
                                        $vidPt = $vid['post_types'] ?? [];
                                        if (!is_array($vidPt)) {
                                            $vidPt = [];
                                        }
                                        $ptAllVid = get_post_types(['public' => true], 'objects');
                                    ?>
                                    <?php foreach ($ptAllVid as $pt => $obj) :
                                        if ($pt === 'attachment') {
                                            continue;
                                        }
                                        $checked = empty($vidPt) ? true : !empty($vidPt[$pt]);
                                    ?>
                                        <label style="display:block; margin: 2px 0;">
                                            <input type="checkbox" name="wpsn[sitemap][video][post_types][<?php echo esc_attr($pt); ?>]" value="1" <?php checked($checked); ?> />
                                            <?php echo esc_html($obj->labels->singular_name ?? $pt); ?>
                                            <code style="opacity:.7"><?php echo esc_html($pt); ?></code>
                                        </label>
                                    <?php endforeach; ?>
                                </div>
                            </details>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Post types', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $ptEnabled = $data['sitemap']['post_types'] ?? [];
                                if (!is_array($ptEnabled)) {
                                    $ptEnabled = [];
                                }
                                $ptAll = get_post_types(['public' => true], 'objects');
                            ?>
                            <fieldset>
                                <?php foreach ($ptAll as $pt => $obj) :
                                    if ($pt === 'attachment') {
                                        continue;
                                    }
                                    $checked = empty($ptEnabled) ? true : !empty($ptEnabled[$pt]);
                                ?>
                                    <label style="display:block; margin: 2px 0;">
                                        <input type="checkbox" name="wpsn[sitemap][post_types][<?php echo esc_attr($pt); ?>]" value="1" <?php checked($checked); ?> />
                                        <?php echo esc_html($obj->labels->singular_name ?? $pt); ?>
                                        <code style="opacity:.7"><?php echo esc_html($pt); ?></code>
                                    </label>
                                <?php endforeach; ?>
                            </fieldset>
                            <p class="description"><?php echo esc_html__('Noindex items are automatically excluded.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Taxonomies', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $txEnabled = $data['sitemap']['taxonomies'] ?? [];
                                if (!is_array($txEnabled)) {
                                    $txEnabled = [];
                                }
                                $txAll = get_taxonomies(['public' => true], 'objects');
                            ?>
                            <fieldset>
                                <?php foreach ($txAll as $tx => $obj) :
                                    $checked = empty($txEnabled) ? true : !empty($txEnabled[$tx]);
                                ?>
                                    <label style="display:block; margin: 2px 0;">
                                        <input type="checkbox" name="wpsn[sitemap][taxonomies][<?php echo esc_attr($tx); ?>]" value="1" <?php checked($checked); ?> />
                                        <?php echo esc_html($obj->labels->singular_name ?? $tx); ?>
                                        <code style="opacity:.7"><?php echo esc_html($tx); ?></code>
                                    </label>
                                <?php endforeach; ?>
                            </fieldset>
                        </td>
                    </tr>
                </table>

                <div class="wpsn-ui-pro-only">

                <h2 class="title"><?php echo esc_html__('Robots.txt', 'wp-seo-next'); ?></h2>
                <p class="description">
                    <?php
                        $robotsUrl = home_url('/robots.txt');
                        $robotsCenterUrl = admin_url('tools.php?page=wpsn-robots');
                        printf(
                            /* translators: %s is the robots.txt URL */
                            esc_html__('Virtual robots.txt is served by WordPress at: %s', 'wp-seo-next'),
                            sprintf('<a href="%1$s" target="_blank" rel="noopener">%1$s</a>', esc_url($robotsUrl))
                        );
                    ?>
                    &nbsp;<?php echo wp_kses_post(sprintf('(<a href="%s">%s</a>)', esc_url($robotsCenterUrl), esc_html__('Open Robots Center', 'wp-seo-next'))); ?>
                </p>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Add Sitemap directive', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[robots_txt][append_sitemap]" value="1" <?php checked(!empty($data['robots_txt']['append_sitemap'])); ?> />
                                <?php echo esc_html__('Append "Sitemap: …/sitemap_index.xml" to robots.txt', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Custom rules', 'wp-seo-next'); ?></th>
                        <td>
                            <textarea class="large-text" rows="6" name="wpsn[robots_txt][custom]" placeholder="# Examples:
# User-agent: *
# Disallow: /wp-admin/
"><?php echo esc_textarea((string) ($data['robots_txt']['custom'] ?? '')); ?></textarea>
                            <p class="description"><?php echo esc_html__('Allowed directives: User-agent, Disallow, Allow, Sitemap, Crawl-delay, Host. Other lines are ignored for safety. Google crawlers ignore Crawl-delay, so use it only for selected non-Google bots.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                <h2 id="wpsn-settings-head-cleanup" class="title"><?php echo esc_html__('Head Cleanup', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Opt-in cleanup of default WordPress head tags and related endpoints. Conservative removes common clutter; Strict also removes feed/oEmbed discovery links, feed endpoints, and pingback leftovers. Switch to Custom to fine-tune the checkboxes below.', 'wp-seo-next'); ?></p>

                <?php
                    $headCleanup = isset($data['head_cleanup']) && is_array($data['head_cleanup']) ? HeadCleanupProfile::sanitize($data['head_cleanup']) : HeadCleanupProfile::defaultConfig();
                    $headCleanupItems = !empty($headCleanup['enabled']) ? HeadCleanupProfile::activeItemLabels($headCleanup) : [];
                    $headCleanupLabels = HeadCleanupProfile::labels();
                ?>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Enable cleanup', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[head_cleanup][enabled]" value="1" <?php checked(!empty($headCleanup['enabled'])); ?> />
                                <?php echo esc_html__('Apply head cleanup on front-end requests.', 'wp-seo-next'); ?>
                            </label>
                            <p class="description"><?php echo esc_html__('This module is strictly opt-in so nothing changes until you enable it.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Preset', 'wp-seo-next'); ?></th>
                        <td>
                            <select name="wpsn[head_cleanup][preset]">
                                <?php foreach (HeadCleanupProfile::presetChoices() as $presetKey => $presetLabel) : ?>
                                    <option value="<?php echo esc_attr($presetKey); ?>" <?php selected((string) ($headCleanup['preset'] ?? HeadCleanupProfile::PRESET_CUSTOM), $presetKey); ?>><?php echo esc_html($presetLabel); ?></option>
                                <?php endforeach; ?>
                            </select>
                            <p class="description"><?php echo esc_html__('Conservative: emoji + discovery/meta clutter. Strict: Conservative plus oEmbed/feed links, feed endpoint blocking, and pingback cleanup. Custom: keep full manual control.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Cleanup items', 'wp-seo-next'); ?></th>
                        <td>
                            <?php foreach ($headCleanupLabels as $cleanupKey => $cleanupLabel) : ?>
                                <label style="display:block; margin: 4px 0;">
                                    <input type="checkbox" name="wpsn[head_cleanup][<?php echo esc_attr($cleanupKey); ?>]" value="1" <?php checked(!empty($headCleanup[$cleanupKey])); ?> />
                                    <?php echo esc_html($cleanupLabel); ?>
                                </label>
                            <?php endforeach; ?>
                            <p class="description" style="margin: 8px 0 0;"><?php echo esc_html__('When Conservative or Strict is selected, these checkboxes are derived from the preset on save. Switch to Custom before making manual exceptions.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <?php if (!empty($headCleanupItems)) : ?>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Active removals', 'wp-seo-next'); ?></th>
                        <td>
                            <ul style="margin:0; padding-left:18px;">
                                <?php foreach ($headCleanupItems as $cleanupItem) : ?>
                                    <li><?php echo esc_html($cleanupItem); ?></li>
                                <?php endforeach; ?>
                            </ul>
                        </td>
                    </tr>
                    <?php endif; ?>
                </table>

                </div>

                <h2 class="title"><?php echo esc_html__('Privacy & External services', 'wp-seo-next'); ?></h2>
                <p class="description">
                    <?php
                        $privacyUrl = admin_url('tools.php?page=wpsn-privacy');
                        printf(
                            /* translators: %s is Tools URL */
                            esc_html__('Configure a local-only mode and see a transparency data map in: %s', 'wp-seo-next'),
                            sprintf('<a href="%s">%s</a>', esc_url($privacyUrl), esc_html__('Tools → SEO Privacy', 'wp-seo-next'))
                        );
                    ?>
                </p>

                <table class="form-table" role="presentation">
                    <?php $trustMode = !empty($privacy['trust_mode']); ?>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Trust Mode (strict)', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[privacy][trust_mode]" value="1" <?php checked($trustMode); ?> />
                                <?php echo esc_html__('Enable a privacy/security preset (runtime-only).', 'wp-seo-next'); ?>
                            </label>
                            <p class="description">
                                <?php echo esc_html__('When enabled, WP SEO Next forces: Local-only mode, Hide AI UI, Hide licensing/upgrade UI, Disable 3rd-party install helpers, and disables setup notices (no nags). Stored settings are preserved.', 'wp-seo-next'); ?>
                            </p>
                            <p class="description">
                                <?php echo wp_kses_post(sprintf(
                                    /* translators: %s is a wp-config constant example */
                                    esc_html__('You can also force this via wp-config.php: %s', 'wp-seo-next'),
                                    '<code>define(\'WPSN_TRUST_MODE\', true);</code>'
                                )); ?>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Local-only mode', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[privacy][local_only]" value="1" <?php checked(!empty($privacy['local_only'])); ?> <?php disabled($trustMode); ?> />
                                <?php echo esc_html__('Disable external services at runtime (OpenAI, Google Search Console, IndexNow submissions, Webhooks).', 'wp-seo-next'); ?>
                            </label>
                            <p class="description">
                                <?php echo esc_html__('Stored API keys/settings are preserved; disabling local-only restores previous config.', 'wp-seo-next'); ?>
                            </p>
                            <?php if ($trustMode) : ?>
                                <p class="description"><strong><?php echo esc_html__('Forced by Trust Mode.', 'wp-seo-next'); ?></strong></p>
                            <?php endif; ?>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Hide AI UI', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[privacy][hide_ai_ui]" value="1" <?php checked(!empty($privacy['hide_ai_ui'])); ?> <?php disabled($trustMode); ?> />
                                <?php echo esc_html__('Hide all AI-related UI across the plugin (editor panels, AI buttons, prompt library).', 'wp-seo-next'); ?>
                            </label>
                            <p class="description">
                                <?php echo esc_html__('This is a UI-only switch. To block outbound calls to external services, enable Local-only mode above.', 'wp-seo-next'); ?>
                            </p>
                            <?php if ($trustMode) : ?>
                                <p class="description"><strong><?php echo esc_html__('Forced by Trust Mode.', 'wp-seo-next'); ?></strong></p>
                            <?php endif; ?>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Disable 3rd-party install helpers', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[privacy][disable_sitekit_install_helper]" value="1" <?php checked(!empty($privacy['disable_sitekit_install_helper'])); ?> <?php disabled($trustMode); ?> />
                                <?php echo esc_html__('Hide/disable the “Install & activate” helper buttons for third-party plugins.', 'wp-seo-next'); ?>
                            </label>
                            <p class="description">
                                <?php echo esc_html__('Useful for locked-down environments where plugin installs are restricted by policy.', 'wp-seo-next'); ?>
                            </p>
                            <?php if ($trustMode) : ?>
                                <p class="description"><strong><?php echo esc_html__('Forced by Trust Mode.', 'wp-seo-next'); ?></strong></p>
                            <?php endif; ?>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('No nags', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[privacy][no_nags]" value="1" <?php checked(!empty($privacy['no_nags'])); ?> <?php disabled($trustMode); ?> />
                                <?php echo esc_html__('Disable setup/recommendation notices in wp-admin.', 'wp-seo-next'); ?>
                            </label>
                            <?php if ($trustMode) : ?>
                                <p class="description"><strong><?php echo esc_html__('Forced by Trust Mode.', 'wp-seo-next'); ?></strong></p>
                            <?php endif; ?>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('External request log', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[privacy][log_external_requests]" value="1" <?php checked(!empty($privacy['log_external_requests'])); ?> />
                                <?php echo esc_html__('Log marked outbound HTTP requests made by this plugin.', 'wp-seo-next'); ?>
                            </label>
                            <p class="description">
                                <?php echo esc_html__('Log entries are visible in Tools → SEO Privacy. We store service name, method, URL (without query), HTTP code and error.', 'wp-seo-next'); ?>
                            </p>

                            <label>
                                <?php echo esc_html__('Retention (days):', 'wp-seo-next'); ?>
                                <input type="number" min="1" max="365" name="wpsn[privacy][retention_days]" value="<?php echo esc_attr((string) ($privacy['retention_days'] ?? 30)); ?>" style="width:100px;" />
                            </label>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Activity log', 'wp-seo-next'); ?></th>
                        <td>
                            <p class="description">
                                <?php
                                    $activityUrl = admin_url('tools.php?page=wpsn-activity-log');
                                    printf(
                                        /* translators: %s is Tools URL */
                                        esc_html__('Keeps a local log of important admin actions. View it in: %s', 'wp-seo-next'),
                                        sprintf('<a href="%s">%s</a>', esc_url($activityUrl), esc_html__('Tools → SEO Activity Log', 'wp-seo-next'))
                                    );
                                ?>
                            </p>
                            <label>
                                <?php echo esc_html__('Retention (days):', 'wp-seo-next'); ?>
                                <input type="number" min="0" max="3650" name="wpsn[activity_log][retention_days]" value="<?php echo esc_attr((string) ($data['activity_log']['retention_days'] ?? 90)); ?>" style="width:120px;" />
                            </label>
                            <p class="description"><?php echo esc_html__('Set 0 to disable auto-purge (keep forever).', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Audit history', 'wp-seo-next'); ?></th>
                        <td>
                            <p class="description">
                                <?php
                                    $auditUrl = admin_url('tools.php?page=wpsn-audit');
                                    printf(
                                        /* translators: %s is Tools URL */
                                        esc_html__('Stores scan history for the rule-based SEO Audit. View it in: %s', 'wp-seo-next'),
                                        sprintf('<a href="%s">%s</a>', esc_url($auditUrl), esc_html__('Tools → SEO Audit', 'wp-seo-next'))
                                    );
                                ?>
                            </p>
                            <label>
                                <?php echo esc_html__('Keep last scans:', 'wp-seo-next'); ?>
                                <input type="number" min="0" max="500" name="wpsn[audit][history_keep_scans]" value="<?php echo esc_attr((string) ($audit['history_keep_scans'] ?? 20)); ?>" style="width:120px;" />
                            </label>
                            <p class="description"><?php echo esc_html__('Set 0 to disable auto-purge (keep forever).', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                <?php if (empty($privacy['hide_ai_ui'])) : ?>

                <h2 class="title"><?php echo esc_html__('AI (Suggestions + OpenAI)', 'wp-seo-next'); ?></h2>
                <p class="description">
                    <?php echo esc_html__('Local suggestions work without sending content anywhere. External generation uses OpenAI and is optional.', 'wp-seo-next'); ?>
                    <br/>
                    <?php
                        $toolsUrl = admin_url('tools.php?page=wpsn-seo-ai');
                        printf(
                            /* translators: %s is Tools URL */
                            esc_html__('Usage & logs: %s', 'wp-seo-next'),
                            sprintf('<a href="%s">%s</a>', esc_url($toolsUrl), esc_html__('Tools → SEO AI', 'wp-seo-next'))
                        );
                    ?>
                </p>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Local suggestions', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[ai][local][enabled]" value="1" <?php checked(!empty($ai['local']['enabled'])); ?> />
                                <?php echo esc_html__('Enable local suggestions in the editor', 'wp-seo-next'); ?>
                            </label>

                            <div class="wpsn-ui-pro-only" style="margin-top: 10px; display:grid; grid-template-columns: 180px 1fr; gap: 8px; max-width: 720px;">
                                <label><?php echo esc_html__('Title max length', 'wp-seo-next'); ?></label>
                                <input type="number" min="20" max="120" name="wpsn[ai][local][title_max_length]" value="<?php echo esc_attr((string) ($ai['local']['title_max_length'] ?? 60)); ?>" />

                                <label><?php echo esc_html__('Description max length', 'wp-seo-next'); ?></label>
                                <input type="number" min="50" max="400" name="wpsn[ai][local][description_max_length]" value="<?php echo esc_attr((string) ($ai['local']['description_max_length'] ?? 155)); ?>" />

                                <label><?php echo esc_html__('Keywords limit', 'wp-seo-next'); ?></label>
                                <input type="number" min="5" max="50" name="wpsn[ai][local][keywords_limit]" value="<?php echo esc_attr((string) ($ai['local']['keywords_limit'] ?? 12)); ?>" />

                                <label><?php echo esc_html__('Max content chars sent to AI', 'wp-seo-next'); ?></label>
                                <input type="number" min="2000" max="50000" name="wpsn[ai][local][max_content_chars]" value="<?php echo esc_attr((string) ($ai['local']['max_content_chars'] ?? 12000)); ?>" />
                            </div>

                            <p class="description wpsn-ui-pro-only" style="margin-top: 10px;">
                                <?php echo esc_html__('Max content chars is used for external AI prompts too (helps control cost).', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Privacy', 'wp-seo-next'); ?></th>
                        <td>
                            <label style="display:block; margin: 2px 0;">
                                <input type="checkbox" name="wpsn[ai][privacy][no_drafts]" value="1" <?php checked(!empty($ai['privacy']['no_drafts'])); ?> />
                                <?php echo esc_html__('Do not send drafts to external AI', 'wp-seo-next'); ?>
                            </label>
                            <label style="display:block; margin: 2px 0;">
                                <input type="checkbox" name="wpsn[ai][privacy][redact_pii]" value="1" <?php checked(!empty($ai['privacy']['redact_pii'])); ?> />
                                <?php echo esc_html__('Redact emails and phone numbers before sending', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('OpenAI API key', 'wp-seo-next'); ?></th>
                        <td>
                            <p>
                                <?php if ($hasKey) : ?>
                                    <span style="color:#0a7; font-weight:600;">✔ <?php echo esc_html__('API key is configured', 'wp-seo-next'); ?></span>
                                <?php else : ?>
                                    <span style="color:#a00; font-weight:600;">✖ <?php echo esc_html__('API key is not set', 'wp-seo-next'); ?></span>
                                <?php endif; ?>
                            </p>

                            <input type="password" class="regular-text" name="wpsn_ai_openai_key" value="" autocomplete="off" placeholder="sk-..." />
                            <p class="description">
                                <?php echo esc_html__('Leave empty to keep current key. Key is stored separately and is NOT included in export.', 'wp-seo-next'); ?>
                            </p>

                            <label>
                                <input type="checkbox" name="wpsn_ai_openai_key_clear" value="1" />
                                <?php echo esc_html__('Clear stored API key', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Quick connect', 'wp-seo-next'); ?></th>
                        <td>
                            <div style="padding: 10px; border: 1px solid #ccd0d4; background: #fff; max-width: 720px;">
                                <p style="margin:0 0 8px;">
                                    <?php echo esc_html__('Paste your OpenAI API key above, then test the connection. You can also apply a recommended cheap preset for autofill and bulk tools.', 'wp-seo-next'); ?>
                                </p>
                                <p style="display:flex; gap:8px; flex-wrap:wrap; margin:0 0 6px;">
                                    <button type="submit" class="button" name="wpsn_quick_action" value="ai_test_openai"><?php echo esc_html__('Save key + Test OpenAI', 'wp-seo-next'); ?></button>
                                    <button type="submit" class="button button-secondary" name="wpsn_quick_action" value="ai_apply_cheap_preset" onclick="return confirm(<?php echo wp_json_encode(__('Apply the cheap AI preset now? This will update AI settings (model, limits, rate limit).', 'wp-seo-next')); ?>);">
                                        <?php echo esc_html__('Apply cheap AI preset', 'wp-seo-next'); ?>
                                    </button>
                                </p>
                                <p class="description" style="margin:0;">
                                    <?php echo esc_html__('Cheap preset: enables External AI, sets model gpt-4o-mini, temperature 0.4, max output 220, and enables a small server-side rate limit.', 'wp-seo-next'); ?>
                                </p>
                            </div>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('External AI', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[ai][external][enabled]" value="1" <?php checked(!empty($ai['external']['enabled'])); ?> />
                                <?php echo esc_html__('Enable OpenAI generation buttons in editor', 'wp-seo-next'); ?>
                            </label>

                            <div class="wpsn-ui-pro-only" style="margin-top: 10px; display:grid; grid-template-columns: 180px 1fr; gap: 8px; max-width: 720px;">
                                <label><?php echo esc_html__('Provider', 'wp-seo-next'); ?></label>
                                <select name="wpsn[ai][external][provider]">
                                    <option value="openai" <?php selected((string) ($ai['external']['provider'] ?? 'openai'), 'openai'); ?>>OpenAI</option>
                                    <option value="saas_proxy" <?php selected((string) ($ai['external']['provider'] ?? 'openai'), 'saas_proxy'); ?>><?php echo esc_html__('SaaS proxy (cloud credits)', 'wp-seo-next'); ?></option>
                                </select>

                                <label><?php echo esc_html__('Model', 'wp-seo-next'); ?></label>
                                <input type="text" class="regular-text" name="wpsn[ai][external][model]" value="<?php echo esc_attr((string) ($ai['external']['model'] ?? 'gpt-4.1-mini')); ?>" />

                                <label><?php echo esc_html__('Max output tokens', 'wp-seo-next'); ?></label>
                                <input type="number" min="16" max="2048" name="wpsn[ai][external][max_output_tokens]" value="<?php echo esc_attr((string) ($ai['external']['max_output_tokens'] ?? 180)); ?>" />

                                <label><?php echo esc_html__('Brief max output tokens', 'wp-seo-next'); ?></label>
                                <input type="number" min="64" max="4096" name="wpsn[ai][external][brief_max_output_tokens]" value="<?php echo esc_attr((string) ($ai['external']['brief_max_output_tokens'] ?? 900)); ?>" />

                                <label><?php echo esc_html__('Temperature', 'wp-seo-next'); ?></label>
                                <input type="number" step="0.1" min="0" max="2" name="wpsn[ai][external][temperature]" value="<?php echo esc_attr((string) ($ai['external']['temperature'] ?? 0.7)); ?>" />

                                <label><?php echo esc_html__('Daily request limit', 'wp-seo-next'); ?></label>
                                <input type="number" min="0" max="1000000" name="wpsn[ai][external][daily_request_limit]" value="<?php echo esc_attr((string) ($ai['external']['daily_request_limit'] ?? 0)); ?>" />

                                <label><?php echo esc_html__('Daily token limit', 'wp-seo-next'); ?></label>
                                <input type="number" min="0" max="100000000" name="wpsn[ai][external][daily_token_limit]" value="<?php echo esc_attr((string) ($ai['external']['daily_token_limit'] ?? 0)); ?>" />

                                <label><?php echo esc_html__('Daily budget (USD)', 'wp-seo-next'); ?></label>
                                <input type="number" step="0.01" min="0" name="wpsn[ai][external][daily_budget_usd]" value="<?php echo esc_attr((string) ($ai['external']['daily_budget_usd'] ?? 0)); ?>" />

                                <label><?php echo esc_html__('Price input / 1M tokens (USD)', 'wp-seo-next'); ?></label>
                                <input type="number" step="0.01" min="0" name="wpsn[ai][external][price_input_per_1m]" value="<?php echo esc_attr((string) ($ai['external']['price_input_per_1m'] ?? 0)); ?>" />

                                <label><?php echo esc_html__('Price output / 1M tokens (USD)', 'wp-seo-next'); ?></label>
                                <input type="number" step="0.01" min="0" name="wpsn[ai][external][price_output_per_1m]" value="<?php echo esc_attr((string) ($ai['external']['price_output_per_1m'] ?? 0)); ?>" />

                                <label><?php echo esc_html__('OpenAI Organization (optional)', 'wp-seo-next'); ?></label>
                                <input type="text" class="regular-text" name="wpsn[ai][external][openai_org]" value="<?php echo esc_attr((string) ($ai['external']['openai_org'] ?? '')); ?>" />

                                <label><?php echo esc_html__('OpenAI Project (optional)', 'wp-seo-next'); ?></label>
                                <input type="text" class="regular-text" name="wpsn[ai][external][openai_project]" value="<?php echo esc_attr((string) ($ai['external']['openai_project'] ?? '')); ?>" />
                            </div>

                            <div class="wpsn-ui-pro-only" style="margin-top: 10px; padding: 10px; border: 1px solid #ccd0d4; background: #fff; max-width: 720px;">
                                <div style="font-weight: 600; margin-bottom: 6px;"><?php echo esc_html__('Rate limiting', 'wp-seo-next'); ?></div>
                                <label style="display:block; margin: 2px 0;">
                                    <input type="checkbox" name="wpsn[ai][external][ratelimit][enabled]" value="1" <?php checked(!empty($ai['external']['ratelimit']['enabled'] ?? false)); ?> />
                                    <?php echo esc_html__('Enable rate limiting for external AI generation endpoint', 'wp-seo-next'); ?>
                                </label>

                                <div class="wpsn-ui-pro-only" style="margin-top: 8px; display:grid; grid-template-columns: 180px 1fr; gap: 8px;">
                                    <label><?php echo esc_html__('Requests per minute', 'wp-seo-next'); ?></label>
                                    <input type="number" min="0" max="6000" name="wpsn[ai][external][ratelimit][requests_per_minute]" value="<?php echo esc_attr((string) ($ai['external']['ratelimit']['requests_per_minute'] ?? 30)); ?>" />

                                    <label><?php echo esc_html__('Per-user', 'wp-seo-next'); ?></label>
                                    <label style="display:flex; align-items:center; gap:8px;">
                                        <input type="checkbox" name="wpsn[ai][external][ratelimit][per_user]" value="1" <?php checked(!empty($ai['external']['ratelimit']['per_user'] ?? true)); ?> />
                                        <?php echo esc_html__('Apply limits per user (recommended)', 'wp-seo-next'); ?>
                                    </label>
                                </div>

                                <p class="description" style="margin-top: 8px;">
                                    <?php echo esc_html__('This is a best-effort server-side limiter to prevent accidental rapid clicking. OpenAI API has its own limits too.', 'wp-seo-next'); ?>
                                </p>
                            </div>

                            <p class="wpsn-ui-pro-only" style="margin-top:10px;">
                                <label>
                                    <input type="checkbox" name="wpsn[ai][external][store_responses]" value="1" <?php checked(!empty($ai['external']['store_responses'])); ?> />
                                    <?php echo esc_html__('Store AI response text in logs (may contain content)', 'wp-seo-next'); ?>
                                </label>
                            </p>

                            <p class="description wpsn-ui-pro-only">
                                <?php echo esc_html__('SaaS proxy mode routes generation through your SaaS (signed policy + credits). OpenAI key is not required in that mode.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>

                    <tr class="wpsn-ui-pro-only">
                        <th scope="row"><?php echo esc_html__('AI credits', 'wp-seo-next'); ?></th>
                        <td>
                            <label style="display:block; margin: 2px 0;">
                                <input type="checkbox" name="wpsn[ai][credits][enabled]" value="1" <?php checked(!empty($ai['credits']['enabled'])); ?> />
                                <?php echo esc_html__('Enforce a credits balance for external AI (hard block when depleted)', 'wp-seo-next'); ?>
                            </label>

                            <div class="wpsn-ui-pro-only" style="margin-top: 10px; display:grid; grid-template-columns: 180px 1fr; gap: 8px; max-width: 720px;">
                                <label><?php echo esc_html__('Mode', 'wp-seo-next'); ?></label>
                                <select name="wpsn[ai][credits][mode]">
                                    <option value="tokens" <?php selected((string) ($ai['credits']['mode'] ?? 'tokens'), 'tokens'); ?>><?php echo esc_html__('Tokens (recommended)', 'wp-seo-next'); ?></option>
                                    <option value="usd" <?php selected((string) ($ai['credits']['mode'] ?? 'tokens'), 'usd'); ?>><?php echo esc_html__('USD cost (requires pricing)', 'wp-seo-next'); ?></option>
                                </select>

                                <label><?php echo esc_html__('Tokens per 1 credit', 'wp-seo-next'); ?></label>
                                <input type="number" min="100" max="1000000" name="wpsn[ai][credits][tokens_per_credit]" value="<?php echo esc_attr((string) ($ai['credits']['tokens_per_credit'] ?? 1000)); ?>" />

                                <label><?php echo esc_html__('Credits per $1 (USD mode)', 'wp-seo-next'); ?></label>
                                <input type="number" step="0.01" min="0" name="wpsn[ai][credits][credits_per_usd]" value="<?php echo esc_attr((string) ($ai['credits']['credits_per_usd'] ?? 100)); ?>" />
                            </div>

                            <p class="description" style="margin-top:10px;">
                                <?php
                                    printf(
                                        /* translators: 1: credits balance */
                                        esc_html__('Current balance: %s credits. Balance is managed in Tools → SEO AI (admins).', 'wp-seo-next'),
                                        '<strong>' . esc_html((string) $creditsBalance) . '</strong>'
                                    );
                                ?>
                            </p>
                        </td>
                    </tr>

                    <tr class="wpsn-ui-pro-only">
                        <th scope="row"><?php echo esc_html__('OpenAI permissions', 'wp-seo-next'); ?></th>
                        <td>
                            <?php if (!current_user_can('manage_options')) : ?>
                                <p class="description">
                                    <?php echo esc_html__('Only administrators can change who can use OpenAI. Ask a site admin to update role permissions.', 'wp-seo-next'); ?>
                                </p>
                            <?php else : ?>
                                <p class="description">
                                    <?php echo esc_html__('Choose which WordPress roles can use OpenAI generation (capability: wpsn_use_ai) and which roles can access AI admin/tools (capability: wpsn_manage_ai). Administrators always have access.', 'wp-seo-next'); ?>
                                </p>

                                <input type="hidden" name="wpsn_ai_role_caps_present" value="1" />

                                <table class="widefat striped" style="max-width: 980px;">
                                    <thead>
                                        <tr>
                                            <th><?php echo esc_html__('Role', 'wp-seo-next'); ?></th>
                                            <th style="width:200px;"><?php echo esc_html__('Can use OpenAI', 'wp-seo-next'); ?></th>
                                            <th style="width:200px;"><?php echo esc_html__('Can manage AI', 'wp-seo-next'); ?></th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <?php
                                            $roles = function_exists('get_editable_roles') ? get_editable_roles() : [];
                                            if (!is_array($roles)) {
                                                $roles = [];
                                            }

                                            foreach ($roles as $roleId => $roleInfo) {
                                                $roleId = sanitize_key((string) $roleId);
                                                if ($roleId === '') {
                                                    continue;
                                                }

                                                $name = '';
                                                if (is_array($roleInfo) && isset($roleInfo['name'])) {
                                                    $name = (string) $roleInfo['name'];
                                                }
                                                if ($name === '') {
                                                    $name = $roleId;
                                                }

                                                $roleObj = get_role($roleId);
                                                $hasUse = $roleObj ? $roleObj->has_cap(\WPSN\Core\Capabilities::CAP_USE_AI) : false;
                                                $hasManage = $roleObj ? $roleObj->has_cap(\WPSN\Core\Capabilities::CAP_AI_ADMIN) : false;
                                                $isAdminRole = ($roleId === 'administrator');
                                                ?>
                                                <tr>
                                                    <td>
                                                        <strong><?php echo esc_html($name); ?></strong>
                                                        <div style="opacity:.7;"><code><?php echo esc_html($roleId); ?></code></div>
                                                    </td>
                                                    <td>
                                                        <label>
                                                            <input type="checkbox" name="wpsn_ai_role_caps_use[<?php echo esc_attr($roleId); ?>]" value="1"
                                                                <?php checked($hasUse); ?>
                                                                <?php disabled($isAdminRole); ?>
                                                            />
                                                            <?php echo esc_html($isAdminRole ? __('Always allowed', 'wp-seo-next') : __('Allow', 'wp-seo-next')); ?>
                                                        </label>
                                                    </td>
                                                    <td>
                                                        <label>
                                                            <input type="checkbox" name="wpsn_ai_role_caps_manage[<?php echo esc_attr($roleId); ?>]" value="1"
                                                                <?php checked($hasManage); ?>
                                                                <?php disabled($isAdminRole); ?>
                                                            />
                                                            <?php echo esc_html($isAdminRole ? __('Always allowed', 'wp-seo-next') : __('Allow', 'wp-seo-next')); ?>
                                                        </label>
                                                    </td>
                                                </tr>
                                                <?php
                                            }
                                        ?>
                                    </tbody>
                                </table>

                                <p class="description" style="margin-top:10px;">
                                    <?php echo esc_html__('Tip: this updates role capabilities immediately. If you use a role editor plugin, you will see the same capability there.', 'wp-seo-next'); ?>
                                </p>

                                <p class="description" style="margin-top:10px;">
                                    <?php echo esc_html__('Need to allow/deny OpenAI or AI admin access for a single user? Edit the user profile → WP SEO Next — AI Permissions.', 'wp-seo-next'); ?>
                                </p>

                                <?php
                                    // List users with per-user overrides (use/manage) for quick audit + clear.
                                    $perPage = 50;
                                    $pageNum = isset($_GET['wpsn_ai_overrides_page']) ? (int) $_GET['wpsn_ai_overrides_page'] : 1;
                                    if ($pageNum <= 0) {
                                        $pageNum = 1;
                                    }
                                    $search = isset($_GET['wpsn_ai_overrides_search']) ? trim((string) wp_unslash($_GET['wpsn_ai_overrides_search'])) : '';
                                    $search = is_string($search) ? $search : '';
                                    $offset = ($pageNum - 1) * $perPage;

                                    $args = [
                                        'number' => $perPage,
                                        'offset' => $offset,
                                        'orderby' => 'ID',
                                        'order' => 'ASC',
                                        'count_total' => true,
                                        'fields' => 'all',
                                        'meta_query' => [
                                            'relation' => 'OR',
                                            [
                                                'key' => \WPSN\Core\Capabilities::USERMETA_AI_USE_OVERRIDE,
                                                'compare' => 'EXISTS',
                                            ],
                                            [
                                                'key' => \WPSN\Core\Capabilities::USERMETA_AI_MANAGE_OVERRIDE,
                                                'compare' => 'EXISTS',
                                            ],
                                        ],
                                    ];

                                    if ($search !== '') {
                                        $args['search'] = '*' . $search . '*';
                                        $args['search_columns'] = ['user_login', 'user_email', 'display_name'];
                                    }

                                    $q = new \WP_User_Query($args);
                                    $users = $q->get_results();
                                    $total = (int) $q->get_total();
                                    $totalPages = (int) ceil($total / $perPage);
                                    if ($totalPages <= 0) {
                                        $totalPages = 1;
                                    }

                                    $baseUrl = admin_url('admin.php?page=wp-seo-next');
                                ?>

                                <hr style="margin:16px 0;"/>
                                <h4 style="margin:0 0 8px 0;"><?php echo esc_html__('Per-user overrides', 'wp-seo-next'); ?></h4>
                                <p class="description" style="margin-top:0;">
                                    <?php echo esc_html__('These users have explicit per-user overrides (allow/deny) set. Use this table to review and quickly clear overrides.', 'wp-seo-next'); ?>
                                </p>

                                <div style="margin: 10px 0; max-width: 980px; padding: 10px 12px; background: #fff; border: 1px solid #dcdcde; border-radius: 4px;">
                                    <p style="margin:0 0 10px 0;">
                                        <strong><?php echo esc_html__('Bulk action', 'wp-seo-next'); ?>:</strong>
                                        <?php echo esc_html__('Clear all per-user AI overrides across the site (does not change role permissions).', 'wp-seo-next'); ?>
                                    </p>
                                    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" onsubmit="return confirm(<?php echo wp_json_encode(__('Clear ALL per-user AI overrides? This cannot be undone.', 'wp-seo-next')); ?>);" style="margin:0;">
                                        <input type="hidden" name="action" value="wpsn_clear_ai_overrides_all" />
                                        <input type="hidden" name="which" value="both" />
                                        <?php wp_nonce_field('wpsn_clear_ai_overrides_all'); ?>
                                        <?php submit_button(__('Clear all overrides', 'wp-seo-next'), 'delete', 'submit', false); ?>
                                    </form>
                                </div>

                                <div style="display:flex; gap:10px; align-items:center; margin:10px 0; max-width: 980px;">
                                    <input type="text" class="regular-text" id="wpsn_ai_overrides_search" value="<?php echo esc_attr($search); ?>" placeholder="<?php echo esc_attr__('Search users (login/email/name)…', 'wp-seo-next'); ?>" />
                                    <button type="button" class="button" id="wpsn_ai_overrides_search_btn"><?php echo esc_html__('Search', 'wp-seo-next'); ?></button>
                                    <?php if ($search !== '') : ?>
                                        <a class="button button-link-delete" href="<?php echo esc_url($baseUrl); ?>"><?php echo esc_html__('Clear', 'wp-seo-next'); ?></a>
                                    <?php endif; ?>
                                    <div style="margin-left:auto; opacity:.7;">
                                        <?php
                                            printf(
                                                /* translators: %d total */
                                                esc_html__('%d users with overrides', 'wp-seo-next'),
                                                (int) $total
                                            );
                                        ?>
                                    </div>
                                </div>

                                <script>
                                (function(){
                                    var btn = document.getElementById('wpsn_ai_overrides_search_btn');
                                    var input = document.getElementById('wpsn_ai_overrides_search');
                                    if (!btn || !input) return;

                                    function go(){
                                        var v = (input.value || '').trim();
                                        var url = <?php echo wp_json_encode($baseUrl); ?>;
                                        if (v) {
                                            url += '&wpsn_ai_overrides_search=' + encodeURIComponent(v) + '&wpsn_ai_overrides_page=1';
                                        } else {
                                            url += '&wpsn_ai_overrides_page=1';
                                        }
                                        window.location = url;
                                    }

                                    btn.addEventListener('click', go);
                                    input.addEventListener('keydown', function(e){
                                        if (e && e.key === 'Enter') {
                                            e.preventDefault();
                                            go();
                                        }
                                    });
                                })();
                                </script>

                                <table class="widefat striped" style="max-width: 980px;">
                                    <thead>
                                        <tr>
                                            <th><?php echo esc_html__('User', 'wp-seo-next'); ?></th>
                                            <th style="width:180px;"><?php echo esc_html__('Roles', 'wp-seo-next'); ?></th>
                                            <th style="width:140px;"><?php echo esc_html__('OpenAI use', 'wp-seo-next'); ?></th>
                                            <th style="width:140px;"><?php echo esc_html__('AI manage', 'wp-seo-next'); ?></th>
                                            <th style="width:260px;"><?php echo esc_html__('Actions', 'wp-seo-next'); ?></th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <?php if (empty($users)) : ?>
                                            <tr>
                                                <td colspan="5" style="text-align:center; opacity:.7; padding:14px;">
                                                    <?php echo esc_html__('No user overrides found.', 'wp-seo-next'); ?>
                                                </td>
                                            </tr>
                                        <?php else : ?>
                                            <?php foreach ($users as $u) : ?>
                                                <?php
                                                    if (!$u instanceof \WP_User) {
                                                        continue;
                                                    }
                                                    $uid = (int) $u->ID;
                                                    $login = (string) ($u->user_login ?? '');
                                                    $name = (string) ($u->display_name ?? '');
                                                    $email = (string) ($u->user_email ?? '');
                                                    $rolesStr = '';
                                                    if (!empty($u->roles) && is_array($u->roles)) {
                                                        $rolesStr = implode(', ', array_map('sanitize_key', $u->roles));
                                                    }
                                                    $useMode = \WPSN\Core\Capabilities::getUserAIUseOverride($uid);
                                                    $manageMode = \WPSN\Core\Capabilities::getUserAIManageOverride($uid);

                                                    $clearBase = admin_url('admin-post.php?action=wpsn_clear_ai_user_override&user_id=' . $uid);
                                                    // Preserve current search/page via referer redirect.
                                                    $urlUse = wp_nonce_url(add_query_arg('which', 'use', $clearBase), 'wpsn_clear_ai_user_override');
                                                    $urlManage = wp_nonce_url(add_query_arg('which', 'manage', $clearBase), 'wpsn_clear_ai_user_override');
                                                    $urlBoth = wp_nonce_url(add_query_arg('which', 'both', $clearBase), 'wpsn_clear_ai_user_override');
                                                    $editUrl = get_edit_user_link($uid);

                                                    $fmtMode = static function (string $m): string {
                                                        $m = sanitize_key($m);
                                                        if ($m === 'allow') {
                                                            return 'allow';
                                                        }
                                                        if ($m === 'deny') {
                                                            return 'deny';
                                                        }
                                                        return 'inherit';
                                                    };
                                                ?>
                                                <tr>
                                                    <td>
                                                        <strong><?php echo esc_html($login !== '' ? $login : ('user#' . $uid)); ?></strong>
                                                        <?php if ($name !== '' && $name !== $login) : ?>
                                                            <span style="opacity:.7;">— <?php echo esc_html($name); ?></span>
                                                        <?php endif; ?>
                                                        <?php if ($email !== '') : ?>
                                                            <div style="opacity:.65;"><code><?php echo esc_html($email); ?></code></div>
                                                        <?php endif; ?>
                                                    </td>
                                                    <td style="opacity:.85;"><?php echo esc_html($rolesStr); ?></td>
                                                    <td><code><?php echo esc_html($fmtMode($useMode)); ?></code></td>
                                                    <td><code><?php echo esc_html($fmtMode($manageMode)); ?></code></td>
                                                    <td>
                                                        <a class="button button-small" href="<?php echo esc_url($urlUse); ?>"><?php echo esc_html__('Clear use', 'wp-seo-next'); ?></a>
                                                        <a class="button button-small" href="<?php echo esc_url($urlManage); ?>"><?php echo esc_html__('Clear manage', 'wp-seo-next'); ?></a>
                                                        <a class="button button-small" href="<?php echo esc_url($urlBoth); ?>"><?php echo esc_html__('Clear both', 'wp-seo-next'); ?></a>
                                                        <?php if (is_string($editUrl) && $editUrl !== '') : ?>
                                                            <a class="button button-small" href="<?php echo esc_url($editUrl); ?>"><?php echo esc_html__('Edit user', 'wp-seo-next'); ?></a>
                                                        <?php endif; ?>
                                                    </td>
                                                </tr>
                                            <?php endforeach; ?>
                                        <?php endif; ?>
                                    </tbody>
                                </table>

                                <?php if ($totalPages > 1) : ?>
                                    <div style="margin-top:10px; max-width: 980px; display:flex; gap:8px; align-items:center;">
                                        <?php
                                            $prev = max(1, $pageNum - 1);
                                            $next = min($totalPages, $pageNum + 1);
                                            $prevUrl = add_query_arg([
                                                'wpsn_ai_overrides_page' => $prev,
                                                'wpsn_ai_overrides_search' => $search,
                                            ], $baseUrl);
                                            $nextUrl = add_query_arg([
                                                'wpsn_ai_overrides_page' => $next,
                                                'wpsn_ai_overrides_search' => $search,
                                            ], $baseUrl);
                                        ?>
                                        <a class="button" href="<?php echo esc_url($prevUrl); ?>" <?php echo $pageNum <= 1 ? 'style="pointer-events:none;opacity:.5;"' : ''; ?>><?php echo esc_html__('← Prev', 'wp-seo-next'); ?></a>
                                        <span style="opacity:.7;">
                                            <?php
                                                printf(
                                                    /* translators: 1: page number, 2: total pages */
                                                    esc_html__('Page %1$d of %2$d', 'wp-seo-next'),
                                                    (int) $pageNum,
                                                    (int) $totalPages
                                                );
                                            ?>
                                        </span>
                                        <a class="button" href="<?php echo esc_url($nextUrl); ?>" <?php echo $pageNum >= $totalPages ? 'style="pointer-events:none;opacity:.5;"' : ''; ?>><?php echo esc_html__('Next →', 'wp-seo-next'); ?></a>
                                    </div>
                                <?php endif; ?>
                            <?php endif; ?>
                        </td>
                    </tr>

                    <tr class="wpsn-ui-pro-only">
                        <th scope="row"><?php echo esc_html__('Prompt templates', 'wp-seo-next'); ?></th>
                        <td>
                            <p class="description">
                                <?php echo esc_html__('Use placeholders:', 'wp-seo-next'); ?>
                                <code>{sitename}</code>, <code>{language}</code>, <code>{max_length}</code>,
                                <code>{post_title}</code>, <code>{excerpt}</code>, <code>{content}</code>,
                                <code>{current_seo_title}</code>, <code>{current_meta_description}</code>,
                                <code>{query}</code>, <code>{top_queries}</code>, <code>{existing_h2}</code>, <code>{existing_h3}</code>,
                                <code>{attachment_title}</code>, <code>{caption}</code>, <code>{filename}</code>,
                                <code>{parent_title}</code>, <code>{parent_excerpt}</code>, <code>{current_alt}</code>,
                                <code>{site_locale}</code>, <code>{site_name}</code>, <code>{target_url}</code>,
                                <code>{target_headings}</code>, <code>{serp_snippets}</code>, <code>{competitor_snapshots}</code>,
                                <code>{missing_topics}</code>
                            </p>

                            <p><strong><?php echo esc_html__('Title prompt', 'wp-seo-next'); ?></strong>
                                <span style="opacity:.7">(v<?php echo esc_html((string) ($ai['prompts']['title_version'] ?? 1)); ?>)</span>
                            </p>
                            <textarea class="large-text" rows="6" name="wpsn[ai][prompts][title_template]" placeholder="<?php echo esc_attr__('Leave empty to use default prompt.', 'wp-seo-next'); ?>"><?php echo esc_textarea((string) ($ai['prompts']['title_template'] ?? '')); ?></textarea>

                            <p style="margin-top:14px;"><strong><?php echo esc_html__('Description prompt', 'wp-seo-next'); ?></strong>
                                <span style="opacity:.7">(v<?php echo esc_html((string) ($ai['prompts']['description_version'] ?? 1)); ?>)</span>
                            </p>
                            <textarea class="large-text" rows="6" name="wpsn[ai][prompts][description_template]" placeholder="<?php echo esc_attr__('Leave empty to use default prompt.', 'wp-seo-next'); ?>"><?php echo esc_textarea((string) ($ai['prompts']['description_template'] ?? '')); ?></textarea>

                            <p style="margin-top:14px;"><strong><?php echo esc_html__('Image ALT prompt', 'wp-seo-next'); ?></strong>
                                <span style="opacity:.7">(v<?php echo esc_html((string) ($ai['prompts']['alt_version'] ?? 1)); ?>)</span>
                            </p>
                            <textarea class="large-text" rows="6" name="wpsn[ai][prompts][alt_template]" placeholder="<?php echo esc_attr__('Leave empty to use default prompt.', 'wp-seo-next'); ?>"><?php echo esc_textarea((string) ($ai['prompts']['alt_template'] ?? '')); ?></textarea>
                            <p class="description"><?php echo esc_html__('Used by Tools → SEO Media when generating ALT drafts with OpenAI.', 'wp-seo-next'); ?></p>

                            <p style="margin-top:14px;"><strong><?php echo esc_html__('Content brief prompt', 'wp-seo-next'); ?></strong>
                                <span style="opacity:.7">(v<?php echo esc_html((string) ($ai['prompts']['brief_version'] ?? 1)); ?>)</span>
                            </p>
                            <textarea class="large-text" rows="7" name="wpsn[ai][prompts][brief_template]" placeholder="<?php echo esc_attr__('Leave empty to use default prompt.', 'wp-seo-next'); ?>"><?php echo esc_textarea((string) ($ai['prompts']['brief_template'] ?? '')); ?></textarea>
                            <p class="description">
                                <?php echo esc_html__('Used by Query optimizer / content brief (GSC → H2/H3/FAQ). Extra placeholders:', 'wp-seo-next'); ?>
                                <code>{query}</code>, <code>{existing_h2}</code>, <code>{existing_h3}</code>, <code>{top_queries}</code>, <code>{gsc_start}</code>, <code>{gsc_end}</code>
                            </p>

                            <p style="margin-top:14px;"><strong><?php echo esc_html__('SERP Gap prompt', 'wp-seo-next'); ?></strong>
                                <span style="opacity:.7">(v<?php echo esc_html((string) ($ai['prompts']['serp_gap_version'] ?? 1)); ?>)</span>
                            </p>
                            <textarea class="large-text" rows="8" name="wpsn[ai][prompts][serp_gap_template]" placeholder="<?php echo esc_attr__('Leave empty to use default prompt.', 'wp-seo-next'); ?>"><?php echo esc_textarea((string) ($ai['prompts']['serp_gap_template'] ?? '')); ?></textarea>
                            <p class="description"><?php echo esc_html__('Used by Tools → SERP Gap when generating outline/checklist/insights.', 'wp-seo-next'); ?></p>

                            <p style="margin-top:14px;"><strong><?php echo esc_html__('SERP Gap FAQ prompt', 'wp-seo-next'); ?></strong>
                                <span style="opacity:.7">(v<?php echo esc_html((string) ($ai['prompts']['serp_gap_faq_version'] ?? 1)); ?>)</span>
                            </p>
                            <textarea class="large-text" rows="6" name="wpsn[ai][prompts][serp_gap_faq_template]" placeholder="<?php echo esc_attr__('Leave empty to use default prompt.', 'wp-seo-next'); ?>"><?php echo esc_textarea((string) ($ai['prompts']['serp_gap_faq_template'] ?? '')); ?></textarea>
                            <p class="description"><?php echo esc_html__('Used by Tools → SERP Gap when generating FAQ JSON.', 'wp-seo-next'); ?></p>

                            <p class="description" style="margin-top:10px;">
                                <?php echo esc_html__('Versions auto-increment when you change template text (useful for auditing).', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>
                </table>

                <?php endif; ?>

                <div class="wpsn-ui-pro-only">

                <h2 class="title"><?php echo esc_html__('Automation SDK', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Developer & agency automation layer: REST API (read/write overrides) + outgoing webhooks.', 'wp-seo-next'); ?></p>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('REST API', 'wp-seo-next'); ?></th>
                        <td>
                            <?php $restEnabled = !empty($automation['rest']['enabled']); ?>
                            <label>
                                <input type="checkbox" name="wpsn[automation][rest][enabled]" value="1" <?php checked($restEnabled); ?> />
                                <?php echo esc_html__('Enable authenticated REST endpoints (wpsn/v1).', 'wp-seo-next'); ?>
                            </label>
                            <p class="description" style="margin-top:6px;">
                                <?php echo esc_html__('Endpoints:', 'wp-seo-next'); ?>
                                <code>/wp-json/wpsn/v1/automation/meta/post/&lt;id&gt;</code>,
                                <code>/wp-json/wpsn/v1/automation/meta/term/&lt;taxonomy&gt;/&lt;id&gt;</code>
                            </p>
                        </td>
                    
                    <tr>
                        <th scope="row"><?php echo esc_html__('Public Head API', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $rest = $automation['rest'] ?? [];
                                if (!is_array($rest)) {
                                    $rest = [];
                                }
                                $ph = $rest['public_head'] ?? [];
                                if (!is_array($ph)) {
                                    $ph = [];
                                }
                                $phEnabled = !empty($ph['enabled']);
                                $phTtl = isset($ph['cache_ttl']) ? (int) $ph['cache_ttl'] : 60;
                            ?>
                            <label>
                                <input type="checkbox" name="wpsn[automation][rest][public_head][enabled]" value="1" <?php checked($phEnabled); ?> />
                                <?php echo esc_html__('Enable public headless endpoint (read-only).', 'wp-seo-next'); ?>
                            </label>
                            <p class="description" style="margin-top:6px;">
                                <?php echo esc_html__('Safe: returns resolved SEO meta for published posts/terms. Drafts require edit capability.', 'wp-seo-next'); ?>
                            </p>
                            <p style="margin-top:8px;">
                                <label>
                                    <?php echo esc_html__('Cache TTL (seconds)', 'wp-seo-next'); ?>
                                    <input type="number" min="0" max="86400" name="wpsn[automation][rest][public_head][cache_ttl]" value="<?php echo esc_attr((string) $phTtl); ?>" />
                                </label>
                            </p>
                            <p class="description">
                                <?php echo esc_html__('Endpoints:', 'wp-seo-next'); ?>
                                <code>/wp-json/wpsn/v1/head/post/&lt;id&gt;</code>,
                                <code>/wp-json/wpsn/v1/head/term/&lt;taxonomy&gt;/&lt;id&gt;</code>,
                                <code>/wp-json/wpsn/v1/head/home</code>
                            </p>
                        </td>
                    </tr>

</tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Webhooks', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                $wh = $automation['webhooks'] ?? [];
                                if (!is_array($wh)) {
                                    $wh = [];
                                }
                            ?>
                            <p><strong><?php echo esc_html__('Meta updated', 'wp-seo-next'); ?></strong></p>
                            <input type="url" class="large-text" name="wpsn[automation][webhooks][meta_updated]" value="<?php echo esc_attr((string) ($wh['meta_updated'] ?? '')); ?>" placeholder="https://..." />

                            <p style="margin-top:10px;"><strong><?php echo esc_html__('Content brief generated', 'wp-seo-next'); ?></strong></p>
                            <input type="url" class="large-text" name="wpsn[automation][webhooks][brief_generated]" value="<?php echo esc_attr((string) ($wh['brief_generated'] ?? '')); ?>" placeholder="https://..." />
                            <p class="description"><?php echo esc_html__('Triggered when a Query optimizer / Content brief is generated and saved to post meta.', 'wp-seo-next'); ?></p>

                            <p style="margin-top:10px;"><strong><?php echo esc_html__('Redirect created', 'wp-seo-next'); ?></strong></p>
                            <input type="url" class="large-text" name="wpsn[automation][webhooks][redirect_created]" value="<?php echo esc_attr((string) ($wh['redirect_created'] ?? '')); ?>" placeholder="https://..." />

                            <p style="margin-top:10px;"><strong><?php echo esc_html__('Redirect updated', 'wp-seo-next'); ?></strong></p>
                            <input type="url" class="large-text" name="wpsn[automation][webhooks][redirect_updated]" value="<?php echo esc_attr((string) ($wh['redirect_updated'] ?? '')); ?>" placeholder="https://..." />

                            <p style="margin-top:10px;"><strong><?php echo esc_html__('Audit scan completed', 'wp-seo-next'); ?></strong></p>
                            <input type="url" class="large-text" name="wpsn[automation][webhooks][audit_scan_completed]" value="<?php echo esc_attr((string) ($wh['audit_scan_completed'] ?? '')); ?>" placeholder="https://..." />
                            <p class="description"><?php echo esc_html__('Triggered when Tools → SEO Audit scan finishes (payload includes summary + counts).', 'wp-seo-next'); ?></p>

                            <p style="margin-top:10px;"><strong><?php echo esc_html__('Schema scan completed', 'wp-seo-next'); ?></strong></p>
                            <input type="url" class="large-text" name="wpsn[automation][webhooks][schema_scan_completed]" value="<?php echo esc_attr((string) ($wh['schema_scan_completed'] ?? '')); ?>" placeholder="https://..." />
                            <p class="description"><?php echo esc_html__('Triggered when Tools → Schema Validator scan finishes (payload includes summary + counts).', 'wp-seo-next'); ?></p>

                            <p style="margin-top:10px;"><strong><?php echo esc_html__('Schema safe fixes completed', 'wp-seo-next'); ?></strong></p>
                            <input type="url" class="large-text" name="wpsn[automation][webhooks][schema_fix_completed]" value="<?php echo esc_attr((string) ($wh['schema_fix_completed'] ?? '')); ?>" placeholder="https://..." />
                            <p class="description"><?php echo esc_html__('Triggered when “Fix all safe” completes in Tools → Schema Validator.', 'wp-seo-next'); ?></p>

                            <p style="margin-top:10px;"><strong><?php echo esc_html__('Schema validation failed', 'wp-seo-next'); ?></strong></p>
                            <input type="url" class="large-text" name="wpsn[automation][webhooks][schema_validation_failed]" value="<?php echo esc_attr((string) ($wh['schema_validation_failed'] ?? '')); ?>" placeholder="https://..." />
                            <p class="description"><?php echo esc_html__('Triggered after Schema Validator scan when it detects any HIGH severity issues.', 'wp-seo-next'); ?></p>


                            <p style="margin-top:10px;"><strong><?php echo esc_html__('Webhook secret (optional)', 'wp-seo-next'); ?></strong></p>
                            <input type="text" class="regular-text" name="wpsn[automation][webhooks][secret]" value="<?php echo esc_attr((string) ($wh['secret'] ?? '')); ?>" />
                            <p class="description"><?php echo esc_html__('If set, requests will include header X-WPSN-Signature: sha256=... (HMAC of the JSON body).', 'wp-seo-next'); ?></p>

                            <p style="margin-top:10px;"><strong><?php echo esc_html__('Webhook timeout (seconds)', 'wp-seo-next'); ?></strong></p>
                            <input type="number" min="1" max="30" name="wpsn[automation][webhooks][timeout]" value="<?php echo esc_attr((string) ($wh['timeout'] ?? 5)); ?>" />
                        </td>
                    </tr>
                </table>

                

                </div>

                <div class="wpsn-ui-pro-only">

                <h2 class="title"><?php echo esc_html__('Search Console Hub', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Controls for the GSC Data Hub + Content Gap + Internal Linking Suggestions module. OAuth connection is configured in Tools → Search Console Hub.', 'wp-seo-next'); ?></p>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Fetch range (days)', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="1" max="180" name="wpsn[search_console][range_days]" value="<?php echo esc_attr((string) ($sc['range_days'] ?? 28)); ?>" />
                            <p class="description"><?php echo esc_html__('Default range for pulling Search Analytics data (e.g., last 28 days).', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Row limit', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="1000" max="25000" name="wpsn[search_console][row_limit]" value="<?php echo esc_attr((string) ($sc['row_limit'] ?? 25000)); ?>" />
                            <p class="description"><?php echo esc_html__('Search Analytics API rowLimit (max 25,000). Use a lower value on shared hosts.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Scheduled sync', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[search_console][scheduled_sync]" value="1" <?php checked(!empty($sc['scheduled_sync'])); ?> />
                                <?php echo esc_html__('Enable daily background fetch (cron).', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Content gap thresholds', 'wp-seo-next'); ?></th>
                        <td>
                            <?php $cg = isset($sc['content_gap']) && is_array($sc['content_gap']) ? $sc['content_gap'] : []; ?>
                            <label><?php echo esc_html__('Min impressions', 'wp-seo-next'); ?>
                                <input type="number" min="0" name="wpsn[search_console][content_gap][min_impressions]" value="<?php echo esc_attr((string) ($cg['min_impressions'] ?? 50)); ?>" style="width:120px;" />
                            </label>
                            <label style="margin-left:10px;"><?php echo esc_html__('Position', 'wp-seo-next'); ?>
                                <input type="number" min="1" max="100" name="wpsn[search_console][content_gap][pos_min]" value="<?php echo esc_attr((string) ($cg['pos_min'] ?? 8)); ?>" style="width:80px;" />
                                —
                                <input type="number" min="1" max="100" name="wpsn[search_console][content_gap][pos_max]" value="<?php echo esc_attr((string) ($cg['pos_max'] ?? 20)); ?>" style="width:80px;" />
                            </label>
                            <label style="margin-left:10px;"><?php echo esc_html__('Max CTR', 'wp-seo-next'); ?>
                                <input type="number" min="0" max="1" step="0.001" name="wpsn[search_console][content_gap][ctr_max]" value="<?php echo esc_attr((string) ($cg['ctr_max'] ?? 0.02)); ?>" style="width:120px;" />
                            </label>
                            <p class="description"><?php echo esc_html__('Used by reports (e.g., low CTR opportunities, content gap).', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Internal linking suggestions', 'wp-seo-next'); ?></th>
                        <td>
                            <?php $il = isset($sc['internal_links']) && is_array($sc['internal_links']) ? $sc['internal_links'] : []; ?>
                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[search_console][internal_links][enabled]" value="1" <?php checked(!empty($il['enabled'])); ?> />
                                    <?php echo esc_html__('Enable internal linking suggestions.', 'wp-seo-next'); ?>
                                </label>
                                <label style="margin-left:12px;">
                                    <input type="checkbox" name="wpsn[search_console][internal_links][only_orphans]" value="1" <?php checked(!empty($il['only_orphans'])); ?> />
                                    <?php echo esc_html__('Only orphan targets by default.', 'wp-seo-next'); ?>
                                </label>
                            </p>
                            <p style="display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end;">
                                <label><?php echo esc_html__('Min impressions', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="0" name="wpsn[search_console][internal_links][min_impressions]" value="<?php echo esc_attr((string) ($il['min_impressions'] ?? 50)); ?>" style="width:120px;" />
                                </label>
                                <label><?php echo esc_html__('Max targets', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="1" max="200" name="wpsn[search_console][internal_links][max_targets]" value="<?php echo esc_attr((string) ($il['max_targets'] ?? 30)); ?>" style="width:120px;" />
                                </label>
                                <label><?php echo esc_html__('Queries/target', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="1" max="10" name="wpsn[search_console][internal_links][max_queries_per_target]" value="<?php echo esc_attr((string) ($il['max_queries_per_target'] ?? 3)); ?>" style="width:120px;" />
                                </label>
                                <label><?php echo esc_html__('Sources/query', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="1" max="50" name="wpsn[search_console][internal_links][max_sources_per_query]" value="<?php echo esc_attr((string) ($il['max_sources_per_query'] ?? 10)); ?>" style="width:120px;" />
                                </label>
                                <label><?php echo esc_html__('Suggestions/target', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="1" max="20" name="wpsn[search_console][internal_links][max_suggestions_per_target]" value="<?php echo esc_attr((string) ($il['max_suggestions_per_target'] ?? 5)); ?>" style="width:140px;" />
                                </label>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Rank tracking (daily)', 'wp-seo-next'); ?></th>
                        <td>
                            <?php $rt = isset($sc['rank_tracking']) && is_array($sc['rank_tracking']) ? $sc['rank_tracking'] : []; ?>
                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[search_console][rank_tracking][enabled]" value="1" <?php checked(!empty($rt['enabled'])); ?> />
                                    <?php echo esc_html__('Enable daily snapshots (date + page).', 'wp-seo-next'); ?>
                                </label>
                            </p>
                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[search_console][rank_tracking][scheduled_sync]" value="1" <?php checked(!empty($rt['scheduled_sync'])); ?> />
                                    <?php echo esc_html__('Enable daily background snapshot fetch (cron).', 'wp-seo-next'); ?>
                                </label>
                            </p>

                            <p style="display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end;">
                                <label><?php echo esc_html__('Backfill days', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="1" max="30" name="wpsn[search_console][rank_tracking][backfill_days]" value="<?php echo esc_attr((string) ($rt['backfill_days'] ?? 7)); ?>" style="width:120px;" />
                                </label>
                                <label><?php echo esc_html__('Retention (days)', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="30" max="730" name="wpsn[search_console][rank_tracking][retention_days]" value="<?php echo esc_attr((string) ($rt['retention_days'] ?? 180)); ?>" style="width:140px;" />
                                </label>
                            </p>
                            <p class="description"><?php echo esc_html__('GSC data is typically delayed. Backfill refetches the last N days to keep snapshots consistent.', 'wp-seo-next'); ?></p>

                            <h4 style="margin:12px 0 6px;"><?php echo esc_html__('Query-level tracking (optional)', 'wp-seo-next'); ?></h4>
                            <?php $ql = isset($rt['query_level']) && is_array($rt['query_level']) ? $rt['query_level'] : []; ?>
                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[search_console][rank_tracking][query_level][enabled]" value="1" <?php checked(!empty($ql['enabled'])); ?> />
                                    <?php echo esc_html__('Enable daily snapshots (day + query + page).', 'wp-seo-next'); ?>
                                </label>
                            </p>
                            <p style="display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end;">
                                <label><?php echo esc_html__('Row limit / day', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="1000" max="25000" name="wpsn[search_console][rank_tracking][query_level][row_limit]" value="<?php echo esc_attr((string) ($ql['row_limit'] ?? 5000)); ?>" style="width:140px;" />
                                </label>
                                <label><?php echo esc_html__('Min impressions (alerts)', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="0" name="wpsn[search_console][rank_tracking][query_level][min_impressions]" value="<?php echo esc_attr((string) ($ql['min_impressions'] ?? 50)); ?>" style="width:160px;" />
                                </label>
                                <label><?php echo esc_html__('Scan rows/day (alerts)', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="50" max="2000" name="wpsn[search_console][rank_tracking][query_level][alert_rows_limit]" value="<?php echo esc_attr((string) ($ql['alert_rows_limit'] ?? 500)); ?>" style="width:170px;" />
                                </label>
                            </p>
                            <p class="description"><?php echo esc_html__('Query-level tracking can be heavy for large sites. It fetches top query+page rows per day (limited by row limit).', 'wp-seo-next'); ?></p>

                            <h4 style="margin:10px 0 6px;"><?php echo esc_html__('Alerts', 'wp-seo-next'); ?></h4>
                            <?php $a = isset($rt['alerts']) && is_array($rt['alerts']) ? $rt['alerts'] : []; ?>
                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[search_console][rank_tracking][alerts][enabled]" value="1" <?php checked(!empty($a['enabled'])); ?> />
                                    <?php echo esc_html__('Enable alerts based on snapshot deltas.', 'wp-seo-next'); ?>
                                </label>
                            </p>
                            <p style="display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end;">
                                <label><?php echo esc_html__('Compare days', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="1" max="30" name="wpsn[search_console][rank_tracking][alerts][compare_days]" value="<?php echo esc_attr((string) ($a['compare_days'] ?? 7)); ?>" style="width:120px;" />
                                </label>
                                <label><?php echo esc_html__('Min impressions', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="0" name="wpsn[search_console][rank_tracking][alerts][min_impressions]" value="<?php echo esc_attr((string) ($a['min_impressions'] ?? 100)); ?>" style="width:140px;" />
                                </label>
                                <label><?php echo esc_html__('Position drop ≥', 'wp-seo-next'); ?><br/>
                                    <input type="number" step="0.1" min="0.5" max="50" name="wpsn[search_console][rank_tracking][alerts][position_drop]" value="<?php echo esc_attr((string) ($a['position_drop'] ?? 3)); ?>" style="width:140px;" />
                                </label>
                                <label><?php echo esc_html__('CTR drop ≥', 'wp-seo-next'); ?><br/>
                                    <input type="number" step="0.001" min="0" max="1" name="wpsn[search_console][rank_tracking][alerts][ctr_drop]" value="<?php echo esc_attr((string) ($a['ctr_drop'] ?? 0.02)); ?>" style="width:120px;" />
                                </label>
                            </p>

                            <h4 style="margin:12px 0 6px;"><?php echo esc_html__('Digest (email / Slack)', 'wp-seo-next'); ?></h4>
                            <?php $dig = isset($a['digest']) && is_array($a['digest']) ? $a['digest'] : []; ?>
                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[search_console][rank_tracking][alerts][digest][enabled]" value="1" <?php checked(!empty($dig['enabled'])); ?> />
                                    <?php echo esc_html__('Send a digest after daily alert computation.', 'wp-seo-next'); ?>
                                </label>
                            </p>
                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[search_console][rank_tracking][alerts][digest][email_enabled]" value="1" <?php checked(!empty($dig['email_enabled'])); ?> />
                                    <?php echo esc_html__('Email', 'wp-seo-next'); ?>
                                </label>
                                <label style="margin-left:12px;">
                                    <?php echo esc_html__('Recipients', 'wp-seo-next'); ?>
                                    <input type="text" name="wpsn[search_console][rank_tracking][alerts][digest][email_recipients]" value="<?php echo esc_attr((string) ($dig['email_recipients'] ?? '')); ?>" style="width:360px;" placeholder="admin@example.com, seo@example.com" />
                                </label>
                            </p>
                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[search_console][rank_tracking][alerts][digest][slack_enabled]" value="1" <?php checked(!empty($dig['slack_enabled'])); ?> />
                                    <?php echo esc_html__('Slack webhook', 'wp-seo-next'); ?>
                                </label>
                                <label style="margin-left:12px;">
                                    <input type="url" name="wpsn[search_console][rank_tracking][alerts][digest][slack_webhook]" value="<?php echo esc_attr((string) ($dig['slack_webhook'] ?? '')); ?>" style="width:420px;" placeholder="https://hooks.slack.com/services/..." />
                                </label>
                            </p>
                            <p style="display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end;">
                                <label><?php echo esc_html__('Max items', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="1" max="100" name="wpsn[search_console][rank_tracking][alerts][digest][max_items]" value="<?php echo esc_attr((string) ($dig['max_items'] ?? 25)); ?>" style="width:120px;" />
                                </label>
                                <label style="padding-top:18px;">
                                    <?php echo esc_html__('Include:', 'wp-seo-next'); ?>
                                    <input type="checkbox" name="wpsn[search_console][rank_tracking][alerts][digest][include_info]" value="1" <?php checked(!empty($dig['include_info'])); ?> /> <?php echo esc_html__('Info', 'wp-seo-next'); ?>
                                    <input type="checkbox" name="wpsn[search_console][rank_tracking][alerts][digest][include_warning]" value="1" <?php checked(!empty($dig['include_warning'])); ?> /> <?php echo esc_html__('Warning', 'wp-seo-next'); ?>
                                    <input type="checkbox" name="wpsn[search_console][rank_tracking][alerts][digest][include_critical]" value="1" <?php checked(!empty($dig['include_critical'])); ?> /> <?php echo esc_html__('Critical', 'wp-seo-next'); ?>
                                </label>
                            </p>
                            <p class="description"><?php echo esc_html__('Slack is an external request and will be blocked by Local-only mode. If recipients are empty, the site admin email is used.', 'wp-seo-next'); ?></p>

                            <h4 style="margin:12px 0 6px;"><?php echo esc_html__('Weekly digest (cron)', 'wp-seo-next'); ?></h4>
                            <p>
                                <label>
                                    <input type="checkbox" name="wpsn[search_console][rank_tracking][alerts][digest][weekly_enabled]" value="1" <?php checked(!empty($dig['weekly_enabled'])); ?> />
                                    <?php echo esc_html__('Send an additional weekly digest (scheduled).', 'wp-seo-next'); ?>
                                </label>
                            </p>
                            <p style="display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end;">
                                <label><?php echo esc_html__('Weekday (UTC)', 'wp-seo-next'); ?><br/>
                                    <select name="wpsn[search_console][rank_tracking][alerts][digest][weekly_weekday]" style="width:200px;">
                                        <?php
                                            $wd = (int) ($dig['weekly_weekday'] ?? 1);
                                            $days = [
                                                1 => __('Monday', 'wp-seo-next'),
                                                2 => __('Tuesday', 'wp-seo-next'),
                                                3 => __('Wednesday', 'wp-seo-next'),
                                                4 => __('Thursday', 'wp-seo-next'),
                                                5 => __('Friday', 'wp-seo-next'),
                                                6 => __('Saturday', 'wp-seo-next'),
                                                7 => __('Sunday', 'wp-seo-next'),
                                            ];
                                            foreach ($days as $k => $lbl) {
                                                echo '<option value="' . esc_attr((string) $k) . '" ' . selected($wd, $k, false) . '>' . esc_html($lbl) . '</option>';
                                            }
                                        ?>
                                    </select>
                                </label>
                                <label><?php echo esc_html__('UTC time', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="0" max="23" name="wpsn[search_console][rank_tracking][alerts][digest][weekly_hour_utc]" value="<?php echo esc_attr((string) ($dig['weekly_hour_utc'] ?? 3)); ?>" style="width:80px;" /> :
                                    <input type="number" min="0" max="59" name="wpsn[search_console][rank_tracking][alerts][digest][weekly_minute_utc]" value="<?php echo esc_attr((string) ($dig['weekly_minute_utc'] ?? 15)); ?>" style="width:80px;" />
                                </label>
                                <label><?php echo esc_html__('Window (days)', 'wp-seo-next'); ?><br/>
                                    <input type="number" min="1" max="30" name="wpsn[search_console][rank_tracking][alerts][digest][weekly_days]" value="<?php echo esc_attr((string) ($dig['weekly_days'] ?? 7)); ?>" style="width:120px;" />
                                </label>
                            </p>
                            <p class="description"><?php echo esc_html__('Weekly digest uses WP-Cron (runs when the site gets traffic). It reuses the same email/Slack settings above.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                
                

                </div>

                <div class="wpsn-ui-pro-only">

                <h2 id="wpsn-settings-indexnow" class="title"><?php echo esc_html__('IndexNow', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Instant URL submission via IndexNow (Bing and other engines). Requires a key file at /{key}.txt.', 'wp-seo-next'); ?></p>

                <?php
                    $idxModuleEnabled = $this->settings->moduleEnabled('indexnow', false);
                    $idxSecrets = new IndexNowSecretsRepository();
                    $idxKey = $idxSecrets->getKey();
                    $idxKeyUrl = $idxKey !== '' ? home_url('/' . rawurlencode($idxKey) . '.txt') : '';
                ?>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Enable submissions', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[indexnow][enabled]" value="1" <?php checked(!empty($indexnow['enabled'])); ?> />
                                <?php echo esc_html__('Enable IndexNow submissions (external requests).', 'wp-seo-next'); ?>
                            </label>
                            <p class="description"><?php echo esc_html__('You can keep the module enabled but disable submissions here.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Auto-submit', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[indexnow][auto_submit]" value="1" <?php checked(!empty($indexnow['auto_submit'])); ?> />
                                <?php echo esc_html__('Queue submissions automatically on content/SEO changes.', 'wp-seo-next'); ?>
                            </label>
                            <p style="margin-top:8px;">
                                <label>
                                    <input type="checkbox" name="wpsn[indexnow][submit_terms]" value="1" <?php checked(!empty($indexnow['submit_terms'])); ?> />
                                    <?php echo esc_html__('Include terms (category/tag archives).', 'wp-seo-next'); ?>
                                </label>
                                <label style="margin-left:12px;">
                                    <input type="checkbox" name="wpsn[indexnow][submit_redirects]" value="1" <?php checked(!empty($indexnow['submit_redirects'])); ?> />
                                    <?php echo esc_html__('Include redirects (submit old+new URLs).', 'wp-seo-next'); ?>
                                </label>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Sitemap pings', 'wp-seo-next'); ?></th>
                        <td>
                            <?php $sp = isset($indexnow['sitemap_pings']) && is_array($indexnow['sitemap_pings']) ? $indexnow['sitemap_pings'] : []; ?>
                            <label>
                                <input type="checkbox" name="wpsn[indexnow][sitemap_pings][enabled]" value="1" <?php checked(!empty($sp['enabled'])); ?> />
                                <?php echo esc_html__('Ping sitemap URLs on updates (external requests).', 'wp-seo-next'); ?>
                            </label>
                            <p class="description"><?php echo esc_html__('When the sitemap cache is updated, WP SEO Next can send lightweight ping requests to search engines for selected sitemaps.', 'wp-seo-next'); ?></p>

                            <p style="margin-top:8px;">
                                <strong><?php echo esc_html__('Include:', 'wp-seo-next'); ?></strong><br/>
                                <label style="display:inline-block; margin-right:12px;">
                                    <input type="checkbox" name="wpsn[indexnow][sitemap_pings][include_index]" value="1" <?php checked(!empty($sp['include_index'])); ?> />
                                    <?php echo esc_html__('Sitemap index', 'wp-seo-next'); ?>
                                </label>
                                <label style="display:inline-block; margin-right:12px;">
                                    <input type="checkbox" name="wpsn[indexnow][sitemap_pings][include_news]" value="1" <?php checked(!empty($sp['include_news'])); ?> />
                                    <?php echo esc_html__('News sitemap', 'wp-seo-next'); ?>
                                </label>
                                <label style="display:inline-block; margin-right:12px;">
                                    <input type="checkbox" name="wpsn[indexnow][sitemap_pings][include_video]" value="1" <?php checked(!empty($sp['include_video'])); ?> />
                                    <?php echo esc_html__('Video sitemap', 'wp-seo-next'); ?>
                                </label>
                            </p>

                            <p style="margin-top:8px;">
                                <strong><?php echo esc_html__('Providers:', 'wp-seo-next'); ?></strong><br/>
                                <?php $prov = isset($sp['providers']) && is_array($sp['providers']) ? $sp['providers'] : []; ?>
                                <label style="display:inline-block; margin-right:12px;">
                                    <input type="checkbox" name="wpsn[indexnow][sitemap_pings][providers][bing]" value="1" <?php checked(!empty($prov['bing'])); ?> />
                                    <?php echo esc_html__('Bing', 'wp-seo-next'); ?>
                                </label>
                                <label style="display:inline-block; margin-right:12px;">
                                    <input type="checkbox" name="wpsn[indexnow][sitemap_pings][providers][google]" value="1" <?php checked(!empty($prov['google'])); ?> />
                                    <?php echo esc_html__('Google', 'wp-seo-next'); ?>
                                </label>
                            </p>
                        </td>
                    </tr>
<tr>
                        <th scope="row"><?php echo esc_html__('Endpoint', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="url" class="large-text" name="wpsn[indexnow][endpoint]" value="<?php echo esc_attr((string) ($indexnow['endpoint'] ?? 'https://api.indexnow.org/indexnow')); ?>" />
                            <p class="description"><?php echo esc_html__('Default is api.indexnow.org (protocol gateway).', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Batch size', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="1" max="10000" name="wpsn[indexnow][batch_size]" value="<?php echo esc_attr((string) ($indexnow['batch_size'] ?? 100)); ?>" />
                            <p class="description"><?php echo esc_html__('Max URLs per API request (IndexNow allows up to 10,000).', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Dedupe window (seconds)', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="0" max="3600" name="wpsn[indexnow][dedupe_window]" value="<?php echo esc_attr((string) ($indexnow['dedupe_window'] ?? 300)); ?>" />
                            <p class="description"><?php echo esc_html__('Prevents repeated submissions for the same URL within a short time window.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Rate limit backoff', 'wp-seo-next'); ?></th>
                        <td>
                            <label><?php echo esc_html__('Base (sec)', 'wp-seo-next'); ?>
                                <input type="number" min="5" max="3600" name="wpsn[indexnow][base_backoff]" value="<?php echo esc_attr((string) ($indexnow['base_backoff'] ?? 30)); ?>" style="width:120px;" />
                            </label>
                            <label style="margin-left:12px;"><?php echo esc_html__('Max (sec)', 'wp-seo-next'); ?>
                                <input type="number" min="5" max="7200" name="wpsn[indexnow][max_backoff]" value="<?php echo esc_attr((string) ($indexnow['max_backoff'] ?? 600)); ?>" style="width:120px;" />
                            </label>
                            <p class="description"><?php echo esc_html__('On HTTP 429/503 the job will retry later with exponential backoff.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Key', 'wp-seo-next'); ?></th>
                        <td>
                            <?php if ($idxKey === '') : ?>
                                <?php if (!empty($idxModuleEnabled)) : ?>
                                    <p><?php echo esc_html__('No key yet. Generate one in Tools → IndexNow.', 'wp-seo-next'); ?></p>
                                <?php else : ?>
                                    <p><?php echo esc_html__('No key yet. Enable the IndexNow module first (Modules section below), then generate a key in Tools → IndexNow.', 'wp-seo-next'); ?></p>
                                <?php endif; ?>
                            <?php else : ?>
                                <p><?php echo esc_html__('Key:', 'wp-seo-next'); ?> <code style="user-select:all;"><?php echo esc_html($idxKey); ?></code></p>
                                <p><?php echo esc_html__('Key URL:', 'wp-seo-next'); ?> <a href="<?php echo esc_url($idxKeyUrl); ?>" target="_blank" rel="noopener noreferrer"><?php echo esc_html($idxKeyUrl); ?></a></p>
                            <?php endif; ?>
                            <?php if (!empty($idxModuleEnabled)) : ?>
                                <p><a class="button" href="<?php echo esc_url(admin_url('tools.php?page=wpsn-indexnow')); ?>"><?php echo esc_html__('Open IndexNow tools', 'wp-seo-next'); ?></a></p>
                            <?php else : ?>
                                <p class="description"><?php echo esc_html__('IndexNow module is disabled. Enable it in the Modules section below to use tools and serve the key file.', 'wp-seo-next'); ?></p>
                            <?php endif; ?>
                        </td>
                    </tr>
                </table>

                

                </div>

                <div class="wpsn-ui-pro-only">

                <h2 class="title"><?php echo esc_html__('Config Sync', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Export/import settings (and selected data) between environments. Useful for agencies and staging→production workflows.', 'wp-seo-next'); ?></p>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Lock settings UI', 'wp-seo-next'); ?></th>
                        <td>
                            <?php if (!empty($locked)) : ?>
                                <p><?php echo wp_kses_post(__('Settings are locked. Manage lock in <a href="tools.php?page=wpsn-config-sync">Tools → SEO Config Sync</a>.', 'wp-seo-next')); ?></p>
                            <?php else : ?>
                                <label>
                                    <input type="checkbox" name="wpsn[config_sync][lock_settings]" value="1" <?php checked(!empty($configSync['lock_settings'])); ?> />
                                    <?php echo esc_html__('Prevent saving settings from this page (use Config Sync import instead).', 'wp-seo-next'); ?>
                                </label>
                                <p class="description"><?php echo esc_html__('When locked, changes to settings here will be ignored. API keys can still be saved.', 'wp-seo-next'); ?></p>
                            <?php endif; ?>
                            <p><a class="button" href="<?php echo esc_url(admin_url('tools.php?page=wpsn-config-sync')); ?>"><?php echo esc_html__('Open Config Sync tools', 'wp-seo-next'); ?></a></p>
                        </td>
                    </tr>
                </table>


                
                

                </div>

                <div class="wpsn-ui-pro-only">

                <h2 class="title"><?php echo esc_html__('White label', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Agency presets often require re-branding admin screens. These settings let you white-label menu titles and headings (does not rename the plugin in the Plugins list).', 'wp-seo-next'); ?></p>

                <?php if ($enforceWhiteLabel) : ?>
                    <div class="notice notice-info"><p><?php echo esc_html__('White label settings are enforced by Network Policies and cannot be changed on this site.', 'wp-seo-next'); ?></p></div>
                <?php endif; ?>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Enable white label', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[white_label][enabled]" value="1" <?php checked(!empty($whiteLabel['enabled'])); ?> <?php disabled($enforceWhiteLabel); ?> />
                                <?php echo esc_html__('Enable white label UI overrides.', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Brand name', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[white_label][brand_name]" value="<?php echo esc_attr((string) ($whiteLabel['brand_name'] ?? '')); ?>" placeholder="My Agency SEO" <?php disabled($enforceWhiteLabel); ?> />
                            <p class="description"><?php echo esc_html__('Used as a fallback when custom titles are empty.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Menu title', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[white_label][menu_title]" value="<?php echo esc_attr((string) ($whiteLabel['menu_title'] ?? '')); ?>" placeholder="<?php echo esc_attr((string) $wlBrand); ?>" <?php disabled($enforceWhiteLabel); ?> />
                            <p class="description"><?php echo esc_html__('Overrides the Settings menu label for this plugin.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Settings heading', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" class="regular-text" name="wpsn[white_label][settings_heading]" value="<?php echo esc_attr((string) ($whiteLabel['settings_heading'] ?? '')); ?>" placeholder="<?php echo esc_attr((string) $wlMenu); ?> — <?php echo esc_attr__('Settings', 'wp-seo-next'); ?>" <?php disabled($enforceWhiteLabel); ?> />
                            <p class="description"><?php echo esc_html__('Heading shown at the top of the settings screen.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Hide plugin branding', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[white_label][hide_branding]" value="1" <?php checked(!empty($whiteLabel['hide_branding'])); ?> <?php disabled($enforceWhiteLabel); ?> />
                                <?php echo esc_html__('Hide plugin branding text in helper links and descriptions where possible.', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Hide upgrade UI', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[white_label][hide_upgrade_ui]" value="1" <?php checked(!empty($whiteLabel['hide_upgrade_ui'])); ?> <?php disabled($enforceWhiteLabel || !empty($privacy['trust_mode'])); ?> />
                                <?php echo esc_html__('Agency mode: hide licensing/upgrade screens in wp-admin (useful for client sites).', 'wp-seo-next'); ?>
                            </label>
                            <?php if (!empty($privacy['trust_mode'])) : ?>
                                <p class="description"><strong><?php echo esc_html__('Forced by Trust Mode.', 'wp-seo-next'); ?></strong></p>
                            <?php endif; ?>
                        </td>
                    </tr>
                </table>

                

                </div>

                <div class="wpsn-ui-pro-only">

                <h2 class="title"><?php echo esc_html__('Integrations', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Optional adapters for page builders and custom fields providers.', 'wp-seo-next'); ?></p>

                <?php if ($enforceIntegrations) : ?>
                    <div class="notice notice-info"><p><?php echo esc_html__('Integrations settings are enforced by Network Policies and cannot be changed on this site.', 'wp-seo-next'); ?></p></div>
                <?php endif; ?>

                <?php
                    $integrations = isset($data['integrations']) && is_array($data['integrations']) ? $data['integrations'] : [];
                    $el = isset($integrations['elementor']) && is_array($integrations['elementor']) ? $integrations['elementor'] : [];
                    $dv = isset($integrations['divi']) && is_array($integrations['divi']) ? $integrations['divi'] : [];
                    $bb = isset($integrations['beaver']) && is_array($integrations['beaver']) ? $integrations['beaver'] : [];
                    $cf = isset($integrations['custom_fields']) && is_array($integrations['custom_fields']) ? $integrations['custom_fields'] : [];
                ?>

                <h3><?php echo esc_html__('Elementor', 'wp-seo-next'); ?></h3>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Enable Elementor adapter', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[integrations][elementor][enabled]" value="1" <?php checked(!empty($el['enabled'])); ?> <?php disabled($enforceIntegrations); ?> />
                                <?php echo esc_html__('Use Elementor rendered content for analysis/excerpts/AI prompts.', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Elementor editor controls', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[integrations][elementor][editor_controls]" value="1" <?php checked(!empty($el['editor_controls'])); ?> <?php disabled($enforceIntegrations); ?> />
                                <?php echo esc_html__('Show SEO Title/Description controls inside Elementor editor.', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                </table>

                <h3><?php echo esc_html__('Divi', 'wp-seo-next'); ?></h3>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Enable Divi adapter', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[integrations][divi][enabled]" value="1" <?php checked(!empty($dv['enabled'])); ?> <?php disabled($enforceIntegrations); ?> />
                                <?php echo esc_html__('Use Divi rendered content for analysis/excerpts/AI prompts.', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Universal SEO panel', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[integrations][divi][universal_metabox]" value="1" <?php checked(!empty($dv['universal_metabox'])); ?> <?php disabled($enforceIntegrations); ?> />
                                <?php echo esc_html__('Show a lightweight SEO panel inside Divi Visual Builder (front-end) so editors can edit SEO fields without leaving the builder.', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                </table>

                <h3><?php echo esc_html__('Beaver Builder', 'wp-seo-next'); ?></h3>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Enable Beaver adapter', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[integrations][beaver][enabled]" value="1" <?php checked(!empty($bb['enabled'])); ?> <?php disabled($enforceIntegrations); ?> />
                                <?php echo esc_html__('Use Beaver Builder rendered content for analysis/excerpts/AI prompts.', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Universal SEO panel', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[integrations][beaver][universal_metabox]" value="1" <?php checked(!empty($bb['universal_metabox'])); ?> <?php disabled($enforceIntegrations); ?> />
                                <?php echo esc_html__('Show a lightweight SEO panel inside Beaver Builder (front-end) so editors can edit SEO fields without leaving the builder.', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                </table>

                <h3><?php echo esc_html__('Custom Fields', 'wp-seo-next'); ?></h3>
                <p class="description">
                    <?php echo wp_kses_post(__('Template tokens supported: <code>%acf:field%</code>, <code>%mb:field%</code>, <code>%jet:field%</code>, <code>%meta:key%</code>, <code>%cf:key%</code> (auto).', 'wp-seo-next')); ?>
                </p>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Enable custom fields integration', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[integrations][custom_fields][enabled]" value="1" <?php checked(!empty($cf['enabled'])); ?> <?php disabled($enforceIntegrations); ?> />
                                <?php echo esc_html__('Enable dynamic tokens for ACF / Meta Box / JetEngine.', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Include selected fields in analysis text', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[integrations][custom_fields][include_in_analysis]" value="1" <?php checked(!empty($cf['include_in_analysis'])); ?> <?php disabled($enforceIntegrations); ?> />
                                <?php echo esc_html__('Append allowlisted custom field values into content for Local/OpenAI generation.', 'wp-seo-next'); ?>
                            </label>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Allowlist field keys', 'wp-seo-next'); ?></th>
                        <td>
                            <textarea class="large-text" rows="5" name="wpsn[integrations][custom_fields][analysis_keys]" <?php disabled($enforceIntegrations); ?>><?php echo esc_textarea((string) ($cf['analysis_keys'] ?? '')); ?></textarea>
                            <p class="description"><?php echo esc_html__('One key per line. Example: hero_text', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Max chars per field', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" name="wpsn[integrations][custom_fields][max_value_chars]" value="<?php echo esc_attr((string) ($cf['max_value_chars'] ?? 500)); ?>" min="50" max="5000" <?php disabled($enforceIntegrations); ?> />
                        </td>
                    </tr>
                </table>

                <h4><?php echo esc_html__('Token helper', 'wp-seo-next'); ?></h4>
                <p class="description">
                    <?php echo esc_html__('Use these tokens in Title/Description templates (they work for posts and terms). Nested keys are supported for ACF/Meta Box/JetEngine using colon paths (groups/repeaters).', 'wp-seo-next'); ?>
                </p>

                <?php
                    $cfCheat = [];
                    $cfCheat[] = 'Custom field template tokens:';
                    $cfCheat[] = '';
                    $cfCheat[] = '%acf:field%';
                    $cfCheat[] = '%acf:group:subfield%';
                    $cfCheat[] = '%acf:repeater:subfield%';
                    $cfCheat[] = '';
                    $cfCheat[] = '%mb:field%';
                    $cfCheat[] = '%mb:group:subfield%';
                    $cfCheat[] = '%mb:repeater:subfield%';
                    $cfCheat[] = '';
                    $cfCheat[] = '%jet:field%';
                    $cfCheat[] = '%jet:group:subfield%';
                    $cfCheat[] = '';
                    $cfCheat[] = '%meta:key%  (native postmeta/termmeta)';
                    $cfCheat[] = '%cf:key%    (auto: tries ACF → Meta Box → JetEngine → native meta)';
                    $cfCheat[] = '';
                    $cfCheat[] = 'Notes:';
                    $cfCheat[] = '- Repeater values are joined into a single string.';
                    $cfCheat[] = '- Empty values are ignored in auto mode.';

                    $cfCheatText = implode("\n", $cfCheat);
                ?>

                <div style="max-width:900px; display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin:6px 0 10px 0;">
                    <button type="button" class="button" id="wpsn-cf-cheat-copy"><?php echo esc_html__('Copy cheat sheet', 'wp-seo-next'); ?></button>
                    <span class="description" id="wpsn-cf-cheat-copied" style="display:none;"><?php echo esc_html__('Copied.', 'wp-seo-next'); ?></span>
                </div>
                <pre id="wpsn-cf-cheat" style="max-width:900px; background:#0b1220; color:#e9eef7; padding:12px 14px; border-radius:10px; border:1px solid rgba(0,0,0,.15); overflow:auto; max-height:260px; white-space:pre;"><?php echo esc_html($cfCheatText); ?></pre>

                <h4 style="margin-top:14px;"><?php echo esc_html__('Token tester', 'wp-seo-next'); ?></h4>
                <p class="description">
                    <?php echo esc_html__('Test a token against a specific post/term to quickly debug why a template is empty.', 'wp-seo-next'); ?>
                </p>

                <?php
                $cfReportId = isset($_GET['wpsn_cf_report']) ? sanitize_key((string) wp_unslash($_GET['wpsn_cf_report'])) : '';
                $cfReport = null;
                if ($cfReportId !== '') {
                    $cfReport = get_transient(\WPSN\Admin\CustomFieldsTokenTester::getResultTransientPrefix() . $cfReportId);
                    if (is_array($cfReport)) {
                        delete_transient(\WPSN\Admin\CustomFieldsTokenTester::getResultTransientPrefix() . $cfReportId);
                    } else {
                        $cfReport = null;
                    }
                }
                ?>

                <div id="wpsn-cf-token-tester" style="max-width:900px; background:#fff; border:1px solid rgba(0,0,0,.08); border-radius:12px; padding:12px 14px; margin:8px 0 12px 0;">
                    <?php if (is_array($cfReport)) : ?>
                        <?php if (!empty($cfReport['success'])) : ?>
                            <div class="notice notice-success inline"><p><?php echo esc_html__('Token test completed.', 'wp-seo-next'); ?></p></div>
                        <?php else : ?>
                            <div class="notice notice-error inline"><p><?php echo esc_html((string) ($cfReport['message'] ?? __('Token test failed.', 'wp-seo-next'))); ?></p></div>
                        <?php endif; ?>
                    <?php endif; ?>
                    <div style="display:flex; gap:10px; flex-wrap:wrap; align-items:flex-end;">
                        <div>
                            <label for="wpsn-cf-obj-type"><strong><?php echo esc_html__('Object', 'wp-seo-next'); ?></strong></label><br/>
                            <select id="wpsn-cf-obj-type">
                                <option value="post"><?php echo esc_html__('Post', 'wp-seo-next'); ?></option>
                                <option value="term"><?php echo esc_html__('Term', 'wp-seo-next'); ?></option>
                            </select>
                        </div>

                        <div id="wpsn-cf-post-wrap">
                            <label for="wpsn-cf-post-id"><strong><?php echo esc_html__('Post ID', 'wp-seo-next'); ?></strong></label><br/>
                            <input type="number" id="wpsn-cf-post-id" value="" min="1" placeholder="123" style="width:110px;" />
                        </div>

                        <div id="wpsn-cf-term-wrap" style="display:none;">
                            <label for="wpsn-cf-term-id"><strong><?php echo esc_html__('Term ID', 'wp-seo-next'); ?></strong></label><br/>
                            <input type="number" id="wpsn-cf-term-id" value="" min="1" placeholder="45" style="width:110px;" />
                        </div>

                        <div id="wpsn-cf-tax-wrap" style="display:none;">
                            <label for="wpsn-cf-taxonomy"><strong><?php echo esc_html__('Taxonomy', 'wp-seo-next'); ?></strong></label><br/>
                            <input type="text" id="wpsn-cf-taxonomy" value="category" placeholder="category" style="width:150px;" />
                        </div>

                        <div style="flex:1; min-width:240px;">
                            <label for="wpsn-cf-token"><strong><?php echo esc_html__('Token', 'wp-seo-next'); ?></strong></label><br/>
                            <input type="text" id="wpsn-cf-token" value="%cf:hero_text%" style="width:100%;" />
                        </div>

                        <div>
                            <button type="button" class="button button-secondary" id="wpsn-cf-token-test-btn"><?php echo esc_html__('Test token', 'wp-seo-next'); ?></button>
                        </div>
                    </div>

                    <p class="wpsn-ajax-optional" style="margin-top:10px;">
                        <label>
                            <input type="checkbox" id="wpsn-cf-token-live" value="1" />
                            <?php echo esc_html__('Live mode (AJAX, optional)', 'wp-seo-next'); ?>
                        </label>
                    </p>

                    <p class="description" id="wpsn-cf-token-test-status" style="margin-top:10px; display:none;"></p>
                    <pre id="wpsn-cf-token-test-result" style="display:none; margin-top:8px; background:#0b1220; color:#e9eef7; padding:12px 14px; border-radius:10px; border:1px solid rgba(0,0,0,.15); overflow:auto; max-height:260px; white-space:pre;"><?php if (is_array($cfReport) && !empty($cfReport['success'])) { echo esc_html('Provider used: ' . ((string) ($cfReport['provider_used'] ?? '-')) . "\n" . 'Token: ' . ((string) ($cfReport['token_normalized'] ?? '')) . "\n" . 'Key: ' . ((string) ($cfReport['key'] ?? '')) . "\n\n" . 'Value:' . "\n" . (((string) ($cfReport['value'] ?? '')) !== '' ? (string) $cfReport['value'] : __('Empty (no value).', 'wp-seo-next'))); } ?></pre>
                </div>

                

                </div>

                <div class="wpsn-ui-pro-only">

                <h2 class="title"><?php echo esc_html__('Performance budget', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Control how much background processing the plugin is allowed to do (useful for low-resource hosting).', 'wp-seo-next'); ?></p>

                <?php
                    $perf = isset($data['performance']) && is_array($data['performance']) ? $data['performance'] : [];
                    $pq = isset($perf['queue']) && is_array($perf['queue']) ? $perf['queue'] : [];
                    $pqMode = isset($pq['mode']) ? (string) $pq['mode'] : 'auto';
                    $pqMins = isset($pq['interval_minutes']) ? (int) $pq['interval_minutes'] : 1;
                    $pqMax  = isset($pq['max_jobs']) ? (int) $pq['max_jobs'] : 5;

                    
                    $pd = isset($pq['direct']) && is_array($pq['direct']) ? $pq['direct'] : [];
                    $pdMaxJobs = isset($pd['max_jobs']) ? (int) $pd['max_jobs'] : 200;
                    $pdMaxSeconds = isset($pd['max_seconds']) ? (int) $pd['max_seconds'] : 20;
                    $pdEager = isset($pd['eager_run_at_seconds']) ? (int) $pd['eager_run_at_seconds'] : 5;

$ap = isset($pq['autopause']) && is_array($pq['autopause']) ? $pq['autopause'] : [];
                    $apEnabled = !empty($ap['enabled']);
                    $apThreshold = isset($ap['threshold']) ? (int) $ap['threshold'] : 3;
                    $apWindow = isset($ap['window_minutes']) ? (int) $ap['window_minutes'] : 10;
                    $apPause = isset($ap['pause_minutes']) ? (int) $ap['pause_minutes'] : 30;
                    $nextQueue = wp_next_scheduled('wpsn_queue_tick');
                    $nextQueueHuman = $nextQueue ? gmdate('Y-m-d H:i:s', (int) $nextQueue) . ' UTC' : __('Not scheduled', 'wp-seo-next');
                ?>

                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Queue mode', 'wp-seo-next'); ?></th>
                        <td>
                            <select name="wpsn[performance][queue][mode]">
                                <option value="auto" <?php selected($pqMode, 'auto'); ?>><?php echo esc_html__('Auto (WP-Cron)', 'wp-seo-next'); ?></option>
                                <option value="direct" <?php selected($pqMode, 'direct'); ?>><?php echo esc_html__('Direct (no cron)', 'wp-seo-next'); ?></option>
                                <option value="manual" <?php selected($pqMode, 'manual'); ?>><?php echo esc_html__('Manual (no schedule)', 'wp-seo-next'); ?></option>
                            </select>
                            <p class="description">
                                <?php echo esc_html__('Auto: schedules background jobs with WP-Cron. Direct: runs the worker at the end of the current request (no schedule) — useful on hosts where WP-Cron is unreliable. Manual: disables scheduling (run jobs via WP-CLI or tools pages when needed).', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Queue interval', 'wp-seo-next'); ?></th>
                        <td>
                            <select name="wpsn[performance][queue][interval_minutes]">
                                <?php foreach ([1, 2, 5, 10, 15] as $m) : ?>
                                    <option value="<?php echo esc_attr((string) $m); ?>" <?php selected($pqMins, $m); ?>><?php echo esc_html(sprintf(_n('%d minute', '%d minutes', $m, 'wp-seo-next'), $m)); ?></option>
                                <?php endforeach; ?>
                            </select>
                            <p class="description">
                                <?php echo esc_html__('How often the queue worker runs (when Queue mode is Auto).', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Max jobs per tick', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="1" max="50" name="wpsn[performance][queue][max_jobs]" value="<?php echo esc_attr((string) $pqMax); ?>" />
                            <p class="description">
                                <?php echo esc_html__('Limits work per cron run. Lower values reduce CPU spikes but make bulk operations slower.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Direct mode limits', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <?php echo esc_html__('Max jobs', 'wp-seo-next'); ?>
                                <input type="number" min="1" max="5000" style="width:100px; margin-left:6px;" name="wpsn[performance][queue][direct][max_jobs]" value="<?php echo esc_attr((string) $pdMaxJobs); ?>" />
                            </label>
                            <label style="margin-left:10px;">
                                <?php echo esc_html__('Max seconds', 'wp-seo-next'); ?>
                                <input type="number" min="1" max="180" style="width:100px; margin-left:6px;" name="wpsn[performance][queue][direct][max_seconds]" value="<?php echo esc_attr((string) $pdMaxSeconds); ?>" />
                            </label>
                            <label style="margin-left:10px;">
                                <?php echo esc_html__('Eager run-at (sec)', 'wp-seo-next'); ?>
                                <input type="number" min="0" max="60" style="width:100px; margin-left:6px;" name="wpsn[performance][queue][direct][eager_run_at_seconds]" value="<?php echo esc_attr((string) $pdEager); ?>" />
                            </label>
                            <p class="description">
                                <?php echo esc_html__('Only used when Queue mode is Direct. The worker runs at the end of the current request and stops when it reaches one of these limits.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>


                    <tr>
                        <th scope="row"><?php echo esc_html__('Auto-pause on 503/429 bursts', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="checkbox" name="wpsn[performance][queue][autopause][enabled]" value="1" <?php checked($apEnabled); ?> />
                                <?php echo esc_html__('Enable auto-pause', 'wp-seo-next'); ?>
                            </label>
                            <p class="description">
                                <?php echo esc_html__('If background jobs repeatedly hit transient overload responses (HTTP 503 Service Unavailable / 429 Too Many Requests), WP SEO Next will pause the queue for a short window to avoid retry storms.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Auto-pause tuning', 'wp-seo-next'); ?></th>
                        <td>
                            <label>
                                <input type="number" min="2" max="50" style="width:90px;" name="wpsn[performance][queue][autopause][threshold]" value="<?php echo esc_attr((string) $apThreshold); ?>" />
                                <?php echo esc_html__('events within', 'wp-seo-next'); ?>
                            </label>
                            <label style="margin-left:8px;">
                                <input type="number" min="1" max="180" style="width:90px;" name="wpsn[performance][queue][autopause][window_minutes]" value="<?php echo esc_attr((string) $apWindow); ?>" />
                                <?php echo esc_html__('minutes', 'wp-seo-next'); ?>
                            </label>
                            <label style="margin-left:8px;">
                                <?php echo esc_html__('Pause for', 'wp-seo-next'); ?>
                                <input type="number" min="1" max="10080" style="width:100px;" name="wpsn[performance][queue][autopause][pause_minutes]" value="<?php echo esc_attr((string) $apPause); ?>" />
                                <?php echo esc_html__('minutes.', 'wp-seo-next'); ?>
                            </label>
                            <p class="description">
                                <?php echo esc_html__('Tip: On shared hosting, start with 3 events / 10 minutes → pause 30 minutes.', 'wp-seo-next'); ?>
                            </p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Next scheduled run', 'wp-seo-next'); ?></th>
                        <td>
                            <code><?php echo esc_html($nextQueueHuman); ?></code>
                            <p class="description"><?php echo esc_html__('Hook: wpsn_queue_tick (only scheduled in Auto mode).', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                

                </div>

                <div class="wpsn-ui-pro-only">

                <h2 class="title"><?php echo esc_html__('SERP Providers', 'wp-seo-next'); ?></h2>
                <p class="description"><?php echo esc_html__('Configure external SERP APIs used by Tools → SERP Gap Analyzer and query features.', 'wp-seo-next'); ?></p>

                <?php
                    $sgProvider = isset($serpGap['provider_id']) ? (string) $serpGap['provider_id'] : 'manual';
                    $sgProvider = $sgProvider !== '' ? $sgProvider : 'manual';
                    $sgLimit = isset($serpGap['limit']) ? (int) $serpGap['limit'] : 5;
                    $sgLimit = max(3, min(20, $sgLimit));

                    $sgDepth = isset($serpGap['depth']) ? sanitize_key((string) $serpGap['depth']) : 'quick';
                    $sgDepth = in_array($sgDepth, ['quick', 'deep'], true) ? $sgDepth : 'quick';
                    $sgDeep = isset($serpGap['deep']) && is_array($serpGap['deep']) ? $serpGap['deep'] : [];
                    $sgDeepTimeout = isset($sgDeep['timeout']) ? (int) $sgDeep['timeout'] : 8;
                    $sgDeepTimeout = max(3, min(60, $sgDeepTimeout));
                    $sgDeepMaxBytes = isset($sgDeep['max_html_bytes']) ? (int) $sgDeep['max_html_bytes'] : 2000000;
                    $sgDeepMaxBytes = max(200000, min(8000000, $sgDeepMaxBytes));

                    $serperEndpoint = isset($serper['endpoint']) ? (string) $serper['endpoint'] : 'https://google.serper.dev/search';
                    $serperGl = isset($serper['gl']) ? (string) $serper['gl'] : '';
                    $serperHl = isset($serper['hl']) ? (string) $serper['hl'] : '';
                    $serperNum = isset($serper['num']) ? (int) $serper['num'] : 10;
                    $serperRpm = isset($serper['rpm_limit']) ? (int) $serper['rpm_limit'] : 60;
                    $serperBackoff = isset($serper['backoff_seconds']) ? (int) $serper['backoff_seconds'] : 30;
                    $serperTimeout = isset($serper['timeout']) ? (int) $serper['timeout'] : 15;

                    $serperBackoffUntil = (int) get_transient('wpsn_serper_backoff_until');
                    $serperNow = time();
                    $serperBackoffActive = $serperBackoffUntil > $serperNow;
                    $serperBackoffRetry = $serperBackoffActive ? max(1, $serperBackoffUntil - $serperNow) : 0;

                    $serperRpmHits = 0;
                    $serperRpmRemaining = 0;
                    if ($serperRpm > 0) {
                        $uid = (int) get_current_user_id();
                        $rlKey = sanitize_key('wpsn_serper_rl_' . ($uid > 0 ? (string) $uid : 'site'));
                        $ts = get_transient($rlKey);
                        if (is_array($ts)) {
                            $cutoff = $serperNow - 60;
                            $filtered = [];
                            foreach ($ts as $t) {
                                $tt = (int) $t;
                                if ($tt > $cutoff) {
                                    $filtered[] = $tt;
                                }
                            }
                            $serperRpmHits = count($filtered);
                        }
                        $serperRpmRemaining = max(0, $serperRpm - $serperRpmHits);
                    }

                ?>

                <h3><?php echo esc_html__('SERP Gap defaults', 'wp-seo-next'); ?></h3>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><?php echo esc_html__('Default provider', 'wp-seo-next'); ?></th>
                        <td>
                            <select name="wpsn[serp_gap][provider_id]">
                                <option value="manual" <?php selected($sgProvider, 'manual'); ?>><?php echo esc_html__('Manual (paste results)', 'wp-seo-next'); ?></option>
                                <option value="serper" <?php selected($sgProvider, 'serper'); ?>><?php echo esc_html__('Serper.dev (Google Search API)', 'wp-seo-next'); ?></option>
                            </select>
                            <p class="description"><?php echo esc_html__('You can override it per run in Tools → SERP Gap.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Default Top N', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="3" max="20" name="wpsn[serp_gap][limit]" value="<?php echo esc_attr((string) $sgLimit); ?>" />
                            <p class="description"><?php echo esc_html__('How many top organic results to compare (we still may fetch more from the provider).', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Default depth', 'wp-seo-next'); ?></th>
                        <td>
                            <select name="wpsn[serp_gap][depth]">
                                <option value="quick" <?php selected($sgDepth, 'quick'); ?>><?php echo esc_html__('Quick (titles/snippets only)', 'wp-seo-next'); ?></option>
                                <option value="deep" <?php selected($sgDepth, 'deep'); ?>><?php echo esc_html__('Deep (fetch competitor headings via queue)', 'wp-seo-next'); ?></option>
                            </select>
                            <p class="description"><?php echo esc_html__('Used as a default in Tools → SERP Gap (you can override per run).', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Deep fetch timeout (seconds)', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="3" max="60" name="wpsn[serp_gap][deep][timeout]" value="<?php echo esc_attr((string) $sgDeepTimeout); ?>" />
                            <p class="description"><?php echo esc_html__('Timeout per competitor page request in Deep mode.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Deep max HTML bytes', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="200000" max="8000000" step="10000" name="wpsn[serp_gap][deep][max_html_bytes]" value="<?php echo esc_attr((string) $sgDeepMaxBytes); ?>" />
                            <p class="description"><?php echo esc_html__('Hard cap for downloaded competitor HTML (helps avoid memory spikes).', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                </table>

                <h3><?php echo esc_html__('Serper.dev', 'wp-seo-next'); ?></h3>
                <p class="description">
                    <?php echo esc_html__('Serper.dev provides a simple Google Search API. API key is stored separately (not exported).', 'wp-seo-next'); ?>
                    <?php if ((bool) $this->settings->get('privacy.local_only', false)) : ?>
                        <br/><strong style="color:#a00;"><?php echo esc_html__('Local-only mode is enabled, external calls are blocked.', 'wp-seo-next'); ?></strong>
                    <?php endif; ?>
                </p>

                <table class="form-table" role="presentation" style="max-width: 900px;">
                    <tr>
                        <th scope="row"><?php echo esc_html__('API key', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="password" class="regular-text" name="wpsn_serper_api_key" value="" autocomplete="new-password" placeholder="<?php echo esc_attr($hasSerperKey ? '••••••••' : ''); ?>" />
                            <label style="margin-left:10px;">
                                <input type="checkbox" name="wpsn_serper_api_key_clear" value="1" />
                                <?php echo esc_html__('Clear saved key', 'wp-seo-next'); ?>
                            </label>
                            <p class="description">
                                <?php if ($hasSerperKey) : ?>
                                    <span style="color:#0a7; font-weight:600;">✔ <?php echo esc_html__('Key is configured', 'wp-seo-next'); ?></span>
                                <?php else : ?>
                                    <span style="color:#a00; font-weight:600;">✖ <?php echo esc_html__('Key is not set', 'wp-seo-next'); ?></span>
                                <?php endif; ?>
                            </p>
                        </td>
                    </tr>
                    
                    <tr>
                        <th scope="row"><?php echo esc_html__('Connection & status', 'wp-seo-next'); ?></th>
                        <td>
                            <?php
                                // Non-AJAX fallback link (admin-post) — JS will enhance to AJAX when possible.
                                $serperTestUrl = wp_nonce_url(
                                    admin_url('admin-post.php?action=wpsn_serper_test_connection&gl=' . rawurlencode($serperGl) . '&hl=' . rawurlencode($serperHl)),
                                    'wpsn_serper_test_connection'
                                );
                                $serperClearUrl = wp_nonce_url(
                                    admin_url('admin-post.php?action=wpsn_serper_clear_backoff'),
                                    'wpsn_serper_clear_backoff'
                                );
                            ?>

                            <a class="button" id="wpsn-serper-test-btn" href="<?php echo esc_url($serperTestUrl); ?>"><?php echo esc_html__('Test connection', 'wp-seo-next'); ?></a>
                            <span id="wpsn-serper-test-result" class="description" style="margin-left:10px;"></span>

                            <div style="margin-top:10px;">
                                <strong><?php echo esc_html__('Backoff', 'wp-seo-next'); ?>:</strong>
                                <code id="wpsn-serper-backoff-status"><?php echo $serperBackoffActive ? esc_html(sprintf(__('Active — retry in %d seconds.', 'wp-seo-next'), $serperBackoffRetry)) : esc_html__('Not active.', 'wp-seo-next'); ?></code>
                                <a class="button button-secondary" id="wpsn-serper-backoff-clear" href="<?php echo esc_url($serperClearUrl); ?>" style="margin-left:8px; <?php echo $serperBackoffActive ? '' : 'display:none;'; ?>"><?php echo esc_html__('Clear backoff', 'wp-seo-next'); ?></a>
                            </div>

                            <p class="description" style="margin-top:8px;">
                                <?php if ($serperRpm > 0) : ?>
                                    <?php echo esc_html(sprintf(__('RPM limiter: %1$d/min. Recent hits: %2$d. Remaining: %3$d.', 'wp-seo-next'), $serperRpm, $serperRpmHits, $serperRpmRemaining)); ?>
                                <?php else : ?>
                                    <?php echo esc_html__('RPM limiter: disabled (0).', 'wp-seo-next'); ?>
                                <?php endif; ?>
                            </p>
                        </td>
                    </tr>

                    <tr>
                        <th scope="row"><?php echo esc_html__('Endpoint', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="url" class="large-text" name="wpsn[serp_gap][serper][endpoint]" value="<?php echo esc_attr($serperEndpoint); ?>" placeholder="https://google.serper.dev/search" />
                            <p class="description"><?php echo esc_html__('Default: https://google.serper.dev/search', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Default country (gl)', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" name="wpsn[serp_gap][serper][gl]" value="<?php echo esc_attr($serperGl); ?>" placeholder="us" />
                            <p class="description"><?php echo esc_html__('Optional ISO-3166 country code. Example: us, gb, de.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Default language (hl)', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="text" name="wpsn[serp_gap][serper][hl]" value="<?php echo esc_attr($serperHl); ?>" placeholder="en" />
                            <p class="description"><?php echo esc_html__('Optional language code. Example: en, en-us, ru.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Results to fetch (num)', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="1" max="20" name="wpsn[serp_gap][serper][num]" value="<?php echo esc_attr((string) $serperNum); ?>" />
                            <p class="description"><?php echo esc_html__('We will still only compare Top N from SERP Gap settings above.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Requests per minute (RPM) limiter', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="0" max="10000" name="wpsn[serp_gap][serper][rpm_limit]" value="<?php echo esc_attr((string) $serperRpm); ?>" />
                            <p class="description"><?php echo esc_html__('Best-effort plugin limiter per user. Set 0 to disable.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('Backoff seconds (on HTTP 429)', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="5" max="3600" name="wpsn[serp_gap][serper][backoff_seconds]" value="<?php echo esc_attr((string) $serperBackoff); ?>" />
                            <p class="description"><?php echo esc_html__('Used when Serper does not send a Retry-After header.', 'wp-seo-next'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html__('HTTP timeout (seconds)', 'wp-seo-next'); ?></th>
                        <td>
                            <input type="number" min="3" max="60" name="wpsn[serp_gap][serper][timeout]" value="<?php echo esc_attr((string) $serperTimeout); ?>" />
                        </td>
                    </tr>
                </table>

                

                </div>

                <h2 class="title" id="wpsn-modules"><?php echo esc_html__('Modules', 'wp-seo-next'); ?></h2>

                <?php if ($enforceModules) : ?>
                    <div class="notice notice-info"><p><?php echo esc_html__('Module toggles are enforced by Network Policies and cannot be changed on this site.', 'wp-seo-next'); ?></p></div>
                <?php endif; ?>

                <?php if ($uiMode === UI::MODE_SIMPLE) : ?>
                    <p class="description">
                        <?php echo esc_html__('In Simple mode we hide advanced modules from this list to keep the UI clean. Switch to Pro mode to view/manage everything.', 'wp-seo-next'); ?>
                    </p>
                <?php endif; ?>

                <?php if ($licensingEnforced) : ?>
                    <div class="notice notice-info"><p>
                        <?php
                            $planMessage = sprintf(
                                /* translators: %s is the normalized plan tier label. */
                                __('Plan gating is enabled. Current licensed tier: %s.', 'wp-seo-next'),
                                PlanMatrix::tierLabel($currentPlanTier)
                            );
                            echo esc_html($planMessage);
                        ?>
                        <?php if (!$licenseRuntimeReady) : ?>
                            <?php echo ' ' . esc_html__('Premium modules stay locked until the license is active and signature requirements (if enabled) pass.', 'wp-seo-next'); ?>
                        <?php endif; ?>
                    </p></div>
                <?php endif; ?>

                <table class="form-table" role="presentation">
                    <?php $proOnlyModules = UI::proOnlyModules(); ?>
                    <?php $buildTier = PlanMatrix::buildTier(); ?>
                    <?php $showLockedModules = (bool) apply_filters('wpsn/settings/show_locked_modules', false, $buildTier, $currentPlanTier); ?>
                    <?php foreach ($this->modules->all() as $id => $module) : ?>
                        <?php
                            $planTier = PlanMatrix::moduleTier($id);
                            $enabled = $this->settings->moduleEnabled($id, $module->defaultEnabled());
                            $planAccess = PlanMatrix::moduleAccess($id, $currentPlanTier, $licenseEntitlements, $buildTier);
                            $configSyncForcedOpen = ($id === 'config_sync') && !empty($configSyncStored['lock_settings']);
                            $lockedByPlan = $licensingEnforced && !$configSyncForcedOpen && ($planTier !== PlanMatrix::TIER_FREE) && (!$licenseRuntimeReady || empty($planAccess['allowed']));
                            $includedInBuild = !empty($planAccess['included_in_build']);
                            if (!$includedInBuild) {
                                continue;
                            }
                            if ($lockedByPlan && !$showLockedModules) {
                                continue;
                            }
                            $rowClass = in_array($id, $proOnlyModules, true) ? 'wpsn-ui-pro-only' : '';
                        ?>
                        <tr id="wpsn-module-<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($rowClass); ?>">
                            <th scope="row">
                                <?php echo esc_html($module->name()); ?>
                                <?php if ($planTier !== PlanMatrix::TIER_FREE) : ?>
                                    <span style="display:inline-block;margin-left:8px;padding:2px 8px;border-radius:999px;background:#f0f6fc;border:1px solid #c3d4e6;font-size:11px;line-height:1.8;font-weight:600;vertical-align:middle;"><?php echo esc_html(PlanMatrix::tierLabel($planTier)); ?></span>
                                <?php endif; ?>
                            </th>
                            <td>
                                <label>
                                    <?php // Hidden field ensures unchecked modules are explicitly saved as disabled. ?>
                                    <input type="hidden" name="wpsn[modules][<?php echo esc_attr($id); ?>]" value="0" <?php disabled($enforceModules); ?> />
                                    <input type="checkbox" name="wpsn[modules][<?php echo esc_attr($id); ?>]" value="1" <?php checked($enabled); ?> <?php disabled($enforceModules); ?> />
                                    <?php echo esc_html($module->description()); ?>
                                </label>
                                <?php if ($planTier !== PlanMatrix::TIER_FREE) : ?>
                                    <p class="description" style="margin-top:6px;">
                                        <?php
                                            echo esc_html(sprintf(
                                                /* translators: %s is a plan tier label such as Pro or Agency. */
                                                __('Requires %s when entitlement enforcement is enabled.', 'wp-seo-next'),
                                                PlanMatrix::tierLabel($planTier)
                                            ));
                                        ?>
                                        <?php if ($lockedByPlan) : ?>
                                            <br /><?php echo esc_html__('Currently locked by the active plan state.', 'wp-seo-next'); ?>
                                        <?php endif; ?>
                                    </p>
                                <?php endif; ?>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                </table>

                <?php submit_button(__('Save settings', 'wp-seo-next')); ?>
            </form>
        </div>
        <?php
    }

    public function handleSave(): void
    {
        if (!Capabilities::canManageSettings()) {
            wp_die(esc_html__('You do not have permission to perform this action.', 'wp-seo-next'));
        }

        check_admin_referer('wpsn_save_settings', 'wpsn_nonce');

        $incoming = $_POST['wpsn'] ?? [];
        if (!is_array($incoming)) {
            $incoming = [];
        } else {
            /** @var array $incoming */
            $incoming = (array) wp_unslash($incoming);
        }

        $quickAction = isset($_POST['wpsn_quick_action']) ? sanitize_key((string) wp_unslash($_POST['wpsn_quick_action'])) : '';

        $current = $this->repo->getAll();
        $locked = !empty($current['config_sync']['lock_settings']);

        // Quick action: Save key (optional) + run an OpenAI connection test.
        // This avoids admin-ajax and helps users validate API keys quickly.
        if ($quickAction === 'ai_test_openai') {
            $secrets = new AISecretsRepository();
            $clear = !empty($_POST['wpsn_ai_openai_key_clear']);
            $keyPosted = isset($_POST['wpsn_ai_openai_key']) ? trim((string) wp_unslash($_POST['wpsn_ai_openai_key'])) : '';

            $keySaved = false;
            if ($clear) {
                $secrets->clearOpenAIKey();
            } elseif ($keyPosted !== '') {
                $secrets->setOpenAIKey($keyPosted);
                $keySaved = true;
            }

            $keyToUse = $keyPosted !== '' ? $keyPosted : $secrets->getOpenAIKey();

            $result = [
                'ok' => false,
                'error' => '',
                'http_status' => 0,
                'retry_after' => 0,
                'latency_ms' => 0,
                'usage_total' => 0,
                'model' => '',
                'key_saved' => $keySaved,
            ];

            // Respect local-only mode.
            $localOnly = (bool) $this->settings->get('privacy.local_only', false);
            if ($localOnly) {
                $result['error'] = __('Local-only mode is enabled. Disable it in Privacy settings to test external services.', 'wp-seo-next');
            } elseif ($keyToUse === '') {
                $result['error'] = __('OpenAI API key is not set. Paste it above and try again.', 'wp-seo-next');
            } else {
                $logger = $this->container->get('logger');

                $org = '';
                $project = '';
                $model = 'gpt-4o-mini';

                // Prefer posted values (user might be tweaking model/org/project) but fall back to stored settings.
                if (isset($incoming['ai']['external']) && is_array($incoming['ai']['external'])) {
                    $ext = $incoming['ai']['external'];
                    $org = isset($ext['openai_org']) ? trim(sanitize_text_field((string) $ext['openai_org'])) : '';
                    $project = isset($ext['openai_project']) ? trim(sanitize_text_field((string) $ext['openai_project'])) : '';
                    $m = isset($ext['model']) ? trim(sanitize_text_field((string) $ext['model'])) : '';
                    if ($m !== '') {
                        $model = $m;
                    }
                } else {
                    $org = trim((string) $this->settings->get('ai.external.openai_org', ''));
                    $project = trim((string) $this->settings->get('ai.external.openai_project', ''));
                    $m = trim((string) $this->settings->get('ai.external.model', ''));
                    if ($m !== '') {
                        $model = $m;
                    }
                }

                $client = new OpenAIClient($keyToUse, $org, $project, $logger);
                $resp = $client->generate($model, 'Reply with the single word: OK', 16, 0.0);

                $result['ok'] = !empty($resp['ok']);
                $result['error'] = (string) ($resp['error'] ?? '');
                $result['http_status'] = (int) ($resp['http_status'] ?? 0);
                $result['retry_after'] = (int) ($resp['retry_after'] ?? 0);
                $result['latency_ms'] = (int) ($resp['latency_ms'] ?? 0);
                $result['usage_total'] = isset($resp['usage']['total']) ? (int) $resp['usage']['total'] : 0;
                $result['model'] = $model;
            }

            $uid = (int) get_current_user_id();
            set_transient('wpsn_ai_test_result_' . $uid, $result, 5 * MINUTE_IN_SECONDS);

            $url = admin_url('admin.php?page=wp-seo-next');
            $url = add_query_arg(['wpsn_notice' => 'ai_test_result'], $url);
            wp_safe_redirect($url);
            exit;
        }

        // Quick action: apply a safe, cheap default config for external AI.
        if ($quickAction === 'ai_apply_cheap_preset') {
            if ($locked) {
                // Still allow API key save via the normal flow below, but do not update settings.
                // We'll set a redirect notice later.
            } else {
                // Snapshot before we apply preset (for easy rollback).
                ConfigSnapshotService::createAutoSnapshot(__('Auto: before AI preset', 'wp-seo-next'), [
                    'kind' => 'auto',
                    'reason' => 'ai_preset',
                    'preset' => 'cheap',
                ]);

                if (!isset($incoming['ai']) || !is_array($incoming['ai'])) {
                    $incoming['ai'] = [];
                }
                if (!isset($incoming['ai']['local']) || !is_array($incoming['ai']['local'])) {
                    $incoming['ai']['local'] = [];
                }
                if (!isset($incoming['ai']['privacy']) || !is_array($incoming['ai']['privacy'])) {
                    $incoming['ai']['privacy'] = [];
                }
                if (!isset($incoming['ai']['external']) || !is_array($incoming['ai']['external'])) {
                    $incoming['ai']['external'] = [];
                }
                if (!isset($incoming['ai']['external']['ratelimit']) || !is_array($incoming['ai']['external']['ratelimit'])) {
                    $incoming['ai']['external']['ratelimit'] = [];
                }

                // Keep local suggestions enabled; just make external AI cheap and safe.
                $incoming['ai']['local']['enabled'] = 1;
                $incoming['ai']['local']['max_content_chars'] = $incoming['ai']['local']['max_content_chars'] ?? 12000;

                // Privacy defaults (safe).
                $incoming['ai']['privacy']['no_drafts'] = 1;
                $incoming['ai']['privacy']['redact_pii'] = 1;

                // External AI defaults.
                $incoming['ai']['external']['enabled'] = 1;
                $incoming['ai']['external']['provider'] = 'openai';
                $incoming['ai']['external']['model'] = 'gpt-4o-mini';
                $incoming['ai']['external']['max_output_tokens'] = 220;
                $incoming['ai']['external']['brief_max_output_tokens'] = 700;
                $incoming['ai']['external']['temperature'] = 0.4;
                $incoming['ai']['external']['store_responses'] = 0;

                // Gentle server-side limiter to prevent rapid clicking.
                $incoming['ai']['external']['ratelimit']['enabled'] = 1;
                $incoming['ai']['external']['ratelimit']['per_user'] = 1;
                $incoming['ai']['external']['ratelimit']['requests_per_minute'] = 20;
            }
        }

        // Multisite: preserve values for sections that are enforced by network policies.
        // Disabled inputs are not posted, and we don't want to overwrite per-site storage.
        if ($this->settings->networkPolicyIsEnforced('modules')) {
            $incoming['modules'] = isset($current['modules']) && is_array($current['modules']) ? $current['modules'] : [];
        }
        if ($this->settings->networkPolicyIsEnforced('white_label')) {
            $incoming['white_label'] = isset($current['white_label']) && is_array($current['white_label']) ? $current['white_label'] : [];
        }
        if ($this->settings->networkPolicyIsEnforced('integrations')) {
            $incoming['integrations'] = isset($current['integrations']) && is_array($current['integrations']) ? $current['integrations'] : [];
        }

        // Save main settings (unless locked by Config Sync).
        if (!$locked) {
            // Preserve tool-managed lists that are not part of the Settings UI.
            // Without this, saving Settings would wipe rules added from the Tools centers.

            // URL Rules (wp_robots noindex patterns).
            if (!isset($incoming['robots']) || !is_array($incoming['robots'])) {
                $incoming['robots'] = [];
            }
            if (!isset($incoming['robots']['url_noindex_rules'])) {
                $incoming['robots']['url_noindex_rules'] = $current['robots']['url_noindex_rules'] ?? [];
            }

            // Managed robots.txt Allow/Disallow rules.
            if (!isset($incoming['robots_txt']) || !is_array($incoming['robots_txt'])) {
                $incoming['robots_txt'] = [];
            }
            if (!isset($incoming['robots_txt']['disallow_rules'])) {
                $incoming['robots_txt']['disallow_rules'] = $current['robots_txt']['disallow_rules'] ?? [];
            }
            if (!isset($incoming['robots_txt']['agent_groups'])) {
                $incoming['robots_txt']['agent_groups'] = $current['robots_txt']['agent_groups'] ?? [];
            }

            $this->repo->update($incoming);
        }

        // Save OpenAI key separately (not part of export/import).
        $secrets = new AISecretsRepository();
        $clear = !empty($_POST['wpsn_ai_openai_key_clear']);
        $key = isset($_POST['wpsn_ai_openai_key']) ? trim((string) wp_unslash($_POST['wpsn_ai_openai_key'])) : '';

        if ($clear) {
            $secrets->clearOpenAIKey();
        } elseif ($key !== '') {
            $secrets->setOpenAIKey($key);
        }

        // Save Serper.dev key separately (not part of export/import).
        $serpSecrets = new SerpSecretsRepository();
        $serpClear = !empty($_POST['wpsn_serper_api_key_clear']);
        $serpKey = isset($_POST['wpsn_serper_api_key']) ? trim((string) wp_unslash($_POST['wpsn_serper_api_key'])) : '';

        if ($serpClear) {
            $serpSecrets->clearSerperKey();
        } elseif ($serpKey !== '') {
            $serpSecrets->setSerperKey($serpKey);
        }

        // Role-based OpenAI access control (without external role editor plugins).
        // Only administrators can modify role capabilities.
        if (current_user_can('manage_options') && !empty($_POST['wpsn_ai_role_caps_present'])) {
            $postedUse = $_POST['wpsn_ai_role_caps_use'] ?? [];
            $postedManage = $_POST['wpsn_ai_role_caps_manage'] ?? [];

            if (!is_array($postedUse)) {
                $postedUse = [];
            } else {
                /** @var array $postedUse */
                $postedUse = (array) wp_unslash($postedUse);
            }

            if (!is_array($postedManage)) {
                $postedManage = [];
            } else {
                /** @var array $postedManage */
                $postedManage = (array) wp_unslash($postedManage);
            }

            $allowUseRoles = [];
            foreach (array_keys($postedUse) as $rid) {
                $rid = sanitize_key((string) $rid);
                if ($rid !== '') {
                    $allowUseRoles[] = $rid;
                }
            }
            $allowUseRoles = array_values(array_unique($allowUseRoles));

            $allowManageRoles = [];
            foreach (array_keys($postedManage) as $rid) {
                $rid = sanitize_key((string) $rid);
                if ($rid !== '') {
                    $allowManageRoles[] = $rid;
                }
            }
            $allowManageRoles = array_values(array_unique($allowManageRoles));

            $roles = function_exists('get_editable_roles') ? get_editable_roles() : [];
            if (!is_array($roles)) {
                $roles = [];
            }

            $changed = [
                'granted' => [],
                'revoked' => [],
                'granted_manage' => [],
                'revoked_manage' => [],
            ];

            foreach (array_keys($roles) as $roleId) {
                $roleId = sanitize_key((string) $roleId);
                if ($roleId === '' || $roleId === 'administrator') {
                    continue;
                }

                $roleObj = get_role($roleId);
                if (!$roleObj) {
                    continue;
                }

                // Can use OpenAI
                $shouldUse = in_array($roleId, $allowUseRoles, true);
                $hasUse = $roleObj->has_cap(Capabilities::CAP_USE_AI);

                if ($shouldUse && !$hasUse) {
                    $roleObj->add_cap(Capabilities::CAP_USE_AI);
                    $changed['granted'][] = $roleId;
                }

                if (!$shouldUse && $hasUse) {
                    $roleObj->remove_cap(Capabilities::CAP_USE_AI);
                    $changed['revoked'][] = $roleId;
                }

                // Can manage AI (Tools → SEO AI)
                $shouldManage = in_array($roleId, $allowManageRoles, true);
                $hasManage = $roleObj->has_cap(Capabilities::CAP_AI_ADMIN);

                if ($shouldManage && !$hasManage) {
                    $roleObj->add_cap(Capabilities::CAP_AI_ADMIN);
                    $changed['granted_manage'][] = $roleId;
                }

                if (!$shouldManage && $hasManage) {
                    $roleObj->remove_cap(Capabilities::CAP_AI_ADMIN);
                    $changed['revoked_manage'][] = $roleId;
                }
            }

            if (!empty($changed['granted']) || !empty($changed['revoked']) || !empty($changed['granted_manage']) || !empty($changed['revoked_manage'])) {
                /**
                 * Fired when role-based AI permissions are updated.
                 *
                 * @param int $userId
                 * @param array<string,mixed> $changed
                 */
                do_action('wpsn/ai/roles_updated', (int) get_current_user_id(), $changed);
            }
        }

        // Flush runtime cache.
        $this->settings->flush();

        // Some settings change rewrite rules (sitemaps). Flush once on save.
        if (!$locked) {
            flush_rewrite_rules(false);
        }

        /**
         * Fired after WP SEO Next settings are saved in the admin.
         *
         *  int  $userId
         *  bool $locked
         */
        do_action('wpsn/settings/saved', (int) get_current_user_id(), (bool) $locked);

        $redirectArgs = [];
        if ($locked) {
            $redirectArgs['wpsn_locked'] = '1';
        } else {
            $redirectArgs['wpsn_saved'] = '1';
        }

        if ($quickAction === 'ai_apply_cheap_preset') {
            $redirectArgs['wpsn_notice'] = $locked ? 'ai_preset_locked' : 'ai_preset_applied';
        }

        wp_safe_redirect(add_query_arg($redirectArgs, admin_url('admin.php?page=wp-seo-next')));
        exit;
    }
}
