<?php
/**
 * AI Recommend admin screen and autonomous recommendation settings.
 */

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

add_action('admin_menu', 'askagento_recommend_upsell_add_admin_page', 5);
add_action('admin_init', 'askagento_recommend_upsell_register_settings');
add_action('admin_notices', 'askagento_recommend_upsell_suppress_default_saved_notice', 0);

/**
 * Hide generic “Settings saved.” when Upsell or Cross-sell Setup shows “Setup saved.”
 */
function askagento_recommend_upsell_suppress_default_saved_notice() {
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only navigation parameter; sanitized and compared against a fixed string.
    if (!is_admin() || !isset($_GET['page']) || sanitize_key((string) wp_unslash($_GET['page'])) !== 'askagento-recommendations') {
        return;
    }

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only display parameter; sanitized and allowlist-validated below.
    $tab = isset($_GET['tab']) ? sanitize_key((string) wp_unslash($_GET['tab'])) : 'upsell-setup';
    if ('setup' === $tab) {
        $tab = 'upsell-setup';
    }

    if (!in_array($tab, ['upsell-setup', 'cross-sell-setup'], true)) {
        return;
    }

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only WordPress settings-updated flag; set by WordPress core after options.php save.
    if (!isset($_GET['settings-updated']) || sanitize_text_field((string) wp_unslash($_GET['settings-updated'])) === '') {
        return;
    }

    global $wp_settings_errors;

    if (!is_array($wp_settings_errors)) {
        return;
    }

    foreach ($wp_settings_errors as $index => $entry) {
        if (isset($entry['code']) && $entry['code'] === 'settings_updated') {
            unset($wp_settings_errors[$index]);
        }
    }
}

function askagento_recommend_upsell_add_admin_page() {
    add_submenu_page(
        'edit.php?post_type=' . ASKAGENTO_POST_TYPE,
        __('AI Recommend', 'askagento'),
        __('AI Recommend', 'askagento'),
        'manage_options',
        'askagento-recommendations',
        'askagento_recommend_upsell_render_admin_page',
        null
    );
}

function askagento_recommend_upsell_render_admin_page() {
    if (!current_user_can('manage_options')) return;
    $auto_enabled = (bool) get_option('askagento_ai_recommend_auto', false);
    $auto_mode = get_option('askagento_ai_recommend_auto_mode', 'replace_all');
    $auto_mode = ('fill_missing' === $auto_mode) ? 'fill_missing' : 'replace_all';
    $cross_sell_auto_enabled = (bool) get_option('askagento_ai_cross_sell_auto', false);
    $cross_sell_auto_mode = get_option('askagento_ai_cross_sell_auto_mode', 'replace_all');
    $cross_sell_auto_mode = ('fill_missing' === $cross_sell_auto_mode) ? 'fill_missing' : 'replace_all';
    $has_stored_upsell = function_exists('askagento_recommend_upsell_get_stored_payload_raw')
        && '' !== trim(askagento_recommend_upsell_get_stored_payload_raw());
    $has_stored_cross_sell = function_exists('askagento_recommend_cross_sell_get_stored_payload_raw')
        && '' !== trim(askagento_recommend_cross_sell_get_stored_payload_raw());

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only display parameter; sanitized and allowlist-validated below.
    $rec_tab_raw = isset($_GET['tab']) ? sanitize_key((string) wp_unslash($_GET['tab'])) : '';
    $rec_tabs_allowed = ['upsell-setup', 'upsell-test', 'cross-sell-setup', 'cross-sell-test'];
    if ('setup' === $rec_tab_raw) {
        $rec_tab_raw = 'upsell-setup';
    } elseif ('test' === $rec_tab_raw) {
        $rec_tab_raw = 'upsell-test';
    }
    $rec_tab = in_array($rec_tab_raw, $rec_tabs_allowed, true) ? $rec_tab_raw : 'upsell-setup';
    // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Read-only WordPress settings-updated flag; set by WordPress core after options.php save.
    $upsell_setup_saved = isset($_GET['settings-updated'])
        && sanitize_text_field((string) wp_unslash($_GET['settings-updated'])) !== ''
        && $rec_tab === 'upsell-setup';
    $cross_sell_setup_saved = isset($_GET['settings-updated'])
        && sanitize_text_field((string) wp_unslash($_GET['settings-updated'])) !== ''
        && $rec_tab === 'cross-sell-setup';
    // phpcs:enable WordPress.Security.NonceVerification.Recommended
    $rec_tab_base = add_query_arg(
        [
            'post_type' => ASKAGENTO_POST_TYPE,
            'page'      => 'askagento-recommendations',
        ],
        admin_url('edit.php')
    );
    $rec_tab_url_upsell_setup       = add_query_arg('tab', 'upsell-setup', $rec_tab_base);
    $rec_tab_url_upsell_test        = add_query_arg('tab', 'upsell-test', $rec_tab_base);
    $rec_tab_url_cross_sell_setup   = add_query_arg('tab', 'cross-sell-setup', $rec_tab_base);
    $rec_tab_url_cross_sell_test    = add_query_arg('tab', 'cross-sell-test', $rec_tab_base);
    ?>
    <div class="wrap askagento-rec-admin-wrap">
        <h1><?php esc_html_e('AI Recommend', 'askagento'); ?></h1>

        <h2 class="nav-tab-wrapper askagento-rec-tabs">
            <a
                href="<?php echo esc_url($rec_tab_url_upsell_setup); ?>"
                class="nav-tab<?php echo esc_attr($rec_tab === 'upsell-setup' ? ' nav-tab-active' : ''); ?>"
                id="askagento-rec-tab-upsell-setup-link"
                <?php if ($rec_tab === 'upsell-setup') : ?>aria-current="true"<?php endif; ?>
            ><?php echo esc_html__('Upsell - Setup', 'askagento'); ?></a>
            <a
                href="<?php echo esc_url($rec_tab_url_upsell_test); ?>"
                class="nav-tab<?php echo esc_attr($rec_tab === 'upsell-test' ? ' nav-tab-active' : ''); ?>"
                id="askagento-rec-tab-upsell-test-link"
                <?php if ($rec_tab === 'upsell-test') : ?>aria-current="true"<?php endif; ?>
            ><?php echo esc_html__('Upsell - Test', 'askagento'); ?></a>
            <a
                href="<?php echo esc_url($rec_tab_url_cross_sell_setup); ?>"
                class="nav-tab<?php echo esc_attr($rec_tab === 'cross-sell-setup' ? ' nav-tab-active' : ''); ?>"
                id="askagento-rec-tab-cross-sell-setup-link"
                <?php if ($rec_tab === 'cross-sell-setup') : ?>aria-current="true"<?php endif; ?>
            ><?php echo esc_html__('Cross-sell - Setup', 'askagento'); ?></a>
            <a
                href="<?php echo esc_url($rec_tab_url_cross_sell_test); ?>"
                class="nav-tab<?php echo esc_attr($rec_tab === 'cross-sell-test' ? ' nav-tab-active' : ''); ?>"
                id="askagento-rec-tab-cross-sell-test-link"
                <?php if ($rec_tab === 'cross-sell-test') : ?>aria-current="true"<?php endif; ?>
            ><?php echo esc_html__('Cross-sell - Test', 'askagento'); ?></a>
        </h2>

        <div
            class="askagento-rec-tab-panel"
            id="askagento-rec-tab-panel-upsell-setup"
            <?php if ($rec_tab !== 'upsell-setup') : ?>hidden<?php endif; ?>
            role="tabpanel"
            aria-labelledby="askagento-rec-tab-upsell-setup-link"
        >
        <div class="askagento-rec-section">
            <h2><?php esc_html_e('Install manually', 'askagento'); ?></h2>
            <p><?php esc_html_e('Writes upsell product links from the downloaded recommendation bundle to your catalog (product page “You may also like”).', 'askagento'); ?></p>
            <fieldset class="askagento-rec-install-modes">
                <legend class="screen-reader-text"><?php esc_html_e('Installation scope', 'askagento'); ?></legend>
                <label class="askagento-rec-mode-label">
                    <input type="radio" name="askagento_install_mode" value="fill_missing" class="askagento-install-mode-input">
                    <?php esc_html_e('Add missing only', 'askagento'); ?>
                </label>
                <span class="description" style="display:block;margin:-4px 0 10px 24px;"><?php esc_html_e('Update only products that do not have recommendation links yet. Existing links are left unchanged.', 'askagento'); ?></span>
                <label class="askagento-rec-mode-label">
                    <input type="radio" name="askagento_install_mode" value="replace_all" class="askagento-install-mode-input" checked>
                    <?php esc_html_e('Replace existing', 'askagento'); ?>
                </label>
                <span class="description" style="display:block;margin:-4px 0 12px 24px;"><?php esc_html_e('Rebuild links for every product in the fetched bundle each run, overwriting earlier recommendation links.', 'askagento'); ?></span>
            </fieldset>
            <p class="askagento-rec-install-actions">
                <button type="button" class="button button-primary" id="askagento-install-recommendations-manual"><?php esc_html_e('Install recommendations', 'askagento'); ?></button>
                <button type="button" class="button" id="askagento-clear-recommendations-links"><?php esc_html_e('Clear recommendations links', 'askagento'); ?></button>
            </p>
            <div id="askagento-install-help" style="margin-top:8px;"></div>
        </div>

        <div class="askagento-rec-section">
            <h2><?php esc_html_e('Autonomous mode', 'askagento'); ?></h2>
            <?php if ($upsell_setup_saved) : ?>
                <div
                    id="askagento-rec-upsell-setup-saved"
                    class="notice notice-success askagento-rec-setup-saved"
                    role="status"
                >
                    <p><?php echo esc_html__('Setup saved.', 'askagento'); ?></p>
                </div>
            <?php endif; ?>
            <form method="post" action="options.php" id="askagento-rec-autonomous-form">
                <?php settings_fields('askagento_ai_recommend_group'); ?>
                <input type="hidden" name="askagento_ai_recommend_auto" value="0" />
                <p class="description" style="margin-top:0;max-width:52em;">
                    <?php esc_html_e(
                        'When enabled, the shop pulls fresh upsell recommendations from AskAgento at most once per calendar day and installs them using the scope below. When disabled, use manual install on this screen or the Test tab.',
                        'askagento'
                    ); ?>
                </p>
                <div class="askagento-ai-text-live-switch-wrap<?php echo esc_attr($auto_enabled ? ' askagento-ai-text-live-switch-wrap--on' : ''); ?>">
                    <label class="askagento-ai-text-live-switch" for="askagento-ai-rec-auto-enabled">
                        <input
                            type="checkbox"
                            id="askagento-ai-rec-auto-enabled"
                            name="askagento_ai_recommend_auto"
                            value="1"
                            class="askagento-ai-text-live-switch__input"
                            <?php checked($auto_enabled); ?>
                        />
                        <span class="askagento-ai-text-live-switch__track" aria-hidden="true">
                            <span class="askagento-ai-text-live-switch__thumb"></span>
                        </span>
                        <span class="askagento-ai-text-live-switch__text">
                            <?php esc_html_e('Enable autonomous mode', 'askagento'); ?>
                        </span>
                    </label>
                    <span
                        class="askagento-ai-text-live-switch__state"
                        id="askagento-ai-rec-auto-state"
                        data-on="<?php echo esc_attr__('On', 'askagento'); ?>"
                        data-off="<?php echo esc_attr__('Off', 'askagento'); ?>"
                        aria-live="polite"
                    ><?php echo $auto_enabled ? esc_html__('On', 'askagento') : esc_html__('Off', 'askagento'); ?></span>
                </div>
                <div id="askagento-ai-rec-auto-options"<?php if (!$auto_enabled) : ?> hidden<?php endif; ?>>
                <fieldset class="askagento-rec-install-modes askagento-rec-auto-modes">
                    <legend><?php esc_html_e('Installation scope', 'askagento'); ?></legend>
                    <label class="askagento-rec-mode-label">
                        <input type="radio" name="askagento_ai_recommend_auto_mode" value="fill_missing" <?php checked($auto_mode, 'fill_missing'); ?> />
                        <?php esc_html_e('Add missing only', 'askagento'); ?>
                    </label>
                    <span class="description" style="display:block;margin:-4px 0 10px 24px;"><?php esc_html_e('Update only products that do not have recommendation links yet. Existing links are left unchanged.', 'askagento'); ?></span>
                    <label class="askagento-rec-mode-label">
                        <input type="radio" name="askagento_ai_recommend_auto_mode" value="replace_all" <?php checked($auto_mode, 'replace_all'); ?> />
                        <?php esc_html_e('Replace existing', 'askagento'); ?>
                    </label>
                    <span class="description" style="display:block;margin:-4px 0 14px 24px;"><?php esc_html_e('Rebuild links for every product in the fetched bundle each run, overwriting earlier recommendation links.', 'askagento'); ?></span>
                </fieldset>
                </div>
                <p class="askagento-rec-autonomous-actions">
                    <button type="button" class="button button-primary" id="askagento-ai-rec-autonomous-check-status"><?php esc_html_e('Check status', 'askagento'); ?></button>
                    <?php submit_button(__('Save', 'askagento'), 'primary', 'submit', false, ['id' => 'askagento-rec-autonomous-submit']); ?>
                </p>
                <div id="askagento-ai-rec-autonomous-status" style="margin-top:10px;"></div>
            </form>
        </div>
        </div>

        <div
            class="askagento-rec-tab-panel"
            id="askagento-rec-tab-panel-upsell-test"
            <?php if ($rec_tab !== 'upsell-test') : ?>hidden<?php endif; ?>
            role="tabpanel"
            aria-labelledby="askagento-rec-tab-upsell-test-link"
        >
        <div class="askagento-rec-section">
            <h2><?php echo esc_html__('Status', 'askagento'); ?></h2>
            <p class="description" style="margin:0 0 10px 0;"><?php esc_html_e('Fetches the latest recommendation bundle and saves it on this site.', 'askagento'); ?></p>
            <p class="askagento-rec-download-actions">
                <button type="button" class="button button-primary" id="askagento-download-recommendations"><?php esc_html_e('Check status', 'askagento'); ?></button>
                <button type="button" class="button" id="askagento-export-recommendations-json" <?php disabled(!$has_stored_upsell); ?>><?php esc_html_e('Save JSON file to computer', 'askagento'); ?></button>
            </p>
            <p class="description" style="margin-top:8px;margin-bottom:0;"><?php esc_html_e('Optional: save the full recommendation payload stored in WordPress as a .json file in your Downloads folder.', 'askagento'); ?></p>
            <div id="askagento-recommend-status" style="margin-top:8px;"></div>
            <div id="askagento-recommend-preview" style="margin-top:10px;"></div>
        </div>
        </div>

        <div
            class="askagento-rec-tab-panel"
            id="askagento-rec-tab-panel-cross-sell-setup"
            <?php if ($rec_tab !== 'cross-sell-setup') : ?>hidden<?php endif; ?>
            role="tabpanel"
            aria-labelledby="askagento-rec-tab-cross-sell-setup-link"
        >
        <div class="askagento-rec-section">
            <h2><?php esc_html_e('Install manually', 'askagento'); ?></h2>
            <p><?php esc_html_e('Writes cross-sell product links from the downloaded recommendation bundle to your catalog (Linked products → Cross-sells on the product edit screen; cart and checkout suggestions).', 'askagento'); ?></p>
            <fieldset class="askagento-rec-install-modes">
                <legend class="screen-reader-text"><?php esc_html_e('Installation scope', 'askagento'); ?></legend>
                <label class="askagento-rec-mode-label">
                    <input type="radio" name="askagento_cross_sell_install_mode" value="fill_missing" class="askagento-cross-sell-install-mode-input">
                    <?php esc_html_e('Add missing only', 'askagento'); ?>
                </label>
                <span class="description" style="display:block;margin:-4px 0 10px 24px;"><?php esc_html_e('Update only products that do not have cross-sell links yet. Existing links are left unchanged.', 'askagento'); ?></span>
                <label class="askagento-rec-mode-label">
                    <input type="radio" name="askagento_cross_sell_install_mode" value="replace_all" class="askagento-cross-sell-install-mode-input" checked>
                    <?php esc_html_e('Replace existing', 'askagento'); ?>
                </label>
                <span class="description" style="display:block;margin:-4px 0 12px 24px;"><?php esc_html_e('Rebuild cross-sell links for every product in the fetched bundle each run, overwriting earlier links.', 'askagento'); ?></span>
            </fieldset>
            <p class="askagento-rec-install-actions">
                <button type="button" class="button button-primary" id="askagento-cross-sell-install-recommendations-manual"><?php esc_html_e('Install recommendations', 'askagento'); ?></button>
                <button type="button" class="button" id="askagento-cross-sell-clear-recommendations-links"><?php esc_html_e('Clear recommendations links', 'askagento'); ?></button>
            </p>
            <div id="askagento-cross-sell-install-help" style="margin-top:8px;"></div>
        </div>

        <div class="askagento-rec-section">
            <h2><?php esc_html_e('Autonomous mode', 'askagento'); ?></h2>
            <?php if ($cross_sell_setup_saved) : ?>
                <div
                    id="askagento-rec-cross-sell-setup-saved"
                    class="notice notice-success askagento-rec-setup-saved"
                    role="status"
                >
                    <p><?php echo esc_html__('Setup saved.', 'askagento'); ?></p>
                </div>
            <?php endif; ?>
            <form method="post" action="options.php" id="askagento-rec-cross-sell-autonomous-form">
                <?php settings_fields('askagento_ai_cross_sell_group'); ?>
                <input type="hidden" name="askagento_ai_cross_sell_auto" value="0" />
                <p class="description" style="margin-top:0;max-width:52em;">
                    <?php esc_html_e(
                        'When enabled, the shop pulls fresh cross-sell recommendations from AskAgento at most once per calendar day and installs them using the scope below. When disabled, use manual install on this screen or the Test tab.',
                        'askagento'
                    ); ?>
                </p>
                <div class="askagento-ai-text-live-switch-wrap<?php echo esc_attr($cross_sell_auto_enabled ? ' askagento-ai-text-live-switch-wrap--on' : ''); ?>">
                    <label class="askagento-ai-text-live-switch" for="askagento-ai-cross-sell-auto-enabled">
                        <input
                            type="checkbox"
                            id="askagento-ai-cross-sell-auto-enabled"
                            name="askagento_ai_cross_sell_auto"
                            value="1"
                            class="askagento-ai-text-live-switch__input"
                            <?php checked($cross_sell_auto_enabled); ?>
                        />
                        <span class="askagento-ai-text-live-switch__track" aria-hidden="true">
                            <span class="askagento-ai-text-live-switch__thumb"></span>
                        </span>
                        <span class="askagento-ai-text-live-switch__text">
                            <?php esc_html_e('Enable autonomous mode', 'askagento'); ?>
                        </span>
                    </label>
                    <span
                        class="askagento-ai-text-live-switch__state"
                        id="askagento-ai-cross-sell-auto-state"
                        data-on="<?php echo esc_attr__('On', 'askagento'); ?>"
                        data-off="<?php echo esc_attr__('Off', 'askagento'); ?>"
                        aria-live="polite"
                    ><?php echo $cross_sell_auto_enabled ? esc_html__('On', 'askagento') : esc_html__('Off', 'askagento'); ?></span>
                </div>
                <div id="askagento-ai-cross-sell-auto-options"<?php if (!$cross_sell_auto_enabled) : ?> hidden<?php endif; ?>>
                <fieldset class="askagento-rec-install-modes askagento-rec-auto-modes">
                    <legend><?php esc_html_e('Installation scope', 'askagento'); ?></legend>
                    <label class="askagento-rec-mode-label">
                        <input type="radio" name="askagento_ai_cross_sell_auto_mode" value="fill_missing" <?php checked($cross_sell_auto_mode, 'fill_missing'); ?> />
                        <?php esc_html_e('Add missing only', 'askagento'); ?>
                    </label>
                    <span class="description" style="display:block;margin:-4px 0 10px 24px;"><?php esc_html_e('Update only products that do not have cross-sell links yet. Existing links are left unchanged.', 'askagento'); ?></span>
                    <label class="askagento-rec-mode-label">
                        <input type="radio" name="askagento_ai_cross_sell_auto_mode" value="replace_all" <?php checked($cross_sell_auto_mode, 'replace_all'); ?> />
                        <?php esc_html_e('Replace existing', 'askagento'); ?>
                    </label>
                    <span class="description" style="display:block;margin:-4px 0 14px 24px;"><?php esc_html_e('Rebuild cross-sell links for every product in the bundle each run, overwriting earlier links.', 'askagento'); ?></span>
                </fieldset>
                </div>
                <p class="askagento-rec-autonomous-actions">
                    <button type="button" class="button button-primary" id="askagento-ai-cross-sell-autonomous-check-status"><?php esc_html_e('Check status', 'askagento'); ?></button>
                    <?php submit_button(__('Save', 'askagento'), 'primary', 'submit', false, ['id' => 'askagento-cross-sell-autonomous-submit']); ?>
                </p>
                <div id="askagento-ai-cross-sell-autonomous-status" style="margin-top:10px;"></div>
            </form>
        </div>
        </div>

        <div
            class="askagento-rec-tab-panel"
            id="askagento-rec-tab-panel-cross-sell-test"
            <?php if ($rec_tab !== 'cross-sell-test') : ?>hidden<?php endif; ?>
            role="tabpanel"
            aria-labelledby="askagento-rec-tab-cross-sell-test-link"
        >
        <div class="askagento-rec-section">
            <h2><?php echo esc_html__('Status', 'askagento'); ?></h2>
            <p class="description" style="margin:0 0 10px 0;"><?php esc_html_e('Fetches the latest cross-sell bundle and saves it on this site.', 'askagento'); ?></p>
            <p class="askagento-rec-download-actions">
                <button type="button" class="button button-primary" id="askagento-cross-sell-download-recommendations"><?php esc_html_e('Check status', 'askagento'); ?></button>
                <button type="button" class="button" id="askagento-cross-sell-export-recommendations-json" <?php disabled(!$has_stored_cross_sell); ?>><?php esc_html_e('Save JSON file to computer', 'askagento'); ?></button>
            </p>
            <p class="description" style="margin-top:8px;margin-bottom:0;"><?php esc_html_e('Optional: save the full recommendation payload stored in WordPress as a .json file in your Downloads folder.', 'askagento'); ?></p>
            <div id="askagento-cross-sell-recommend-status" style="margin-top:8px;"></div>
            <div id="askagento-cross-sell-recommend-preview" style="margin-top:10px;"></div>
        </div>
        </div>

        <style>
            .askagento-rec-admin-wrap h2.askagento-rec-tabs.nav-tab-wrapper {
                margin-top: 8px;
                margin-bottom: 0;
                max-width: 1024px;
            }
            .askagento-rec-section{background:#fff;border:1px solid #dcdcde;padding:16px;margin:0 0 14px 0;max-width:780px;}
            .askagento-rec-section h2{margin-top:0;}
            .askagento-rec-download-actions{display:flex;flex-wrap:wrap;align-items:center;gap:8px;width:100%;max-width:100%;}
            .askagento-rec-download-actions #askagento-export-recommendations-json{margin-left:auto;}
            .askagento-rec-install-modes{border:0;padding:0;margin:0 0 12px 0;max-width:52em;}
            .askagento-rec-install-modes .askagento-rec-mode-label{display:flex;align-items:flex-start;gap:6px;font-weight:600;}
            .askagento-rec-install-modes .askagento-rec-mode-label input{margin-top:3px;}
            .askagento-rec-install-actions{display:flex;flex-wrap:wrap;align-items:center;gap:8px;width:100%;max-width:100%;}
            .askagento-rec-install-actions #askagento-clear-recommendations-links,
            .askagento-rec-install-actions #askagento-cross-sell-clear-recommendations-links{margin-left:auto;}
            .askagento-rec-autonomous-actions{display:flex;flex-wrap:wrap;align-items:center;gap:8px;width:100%;max-width:100%;}
            .askagento-rec-autonomous-actions #askagento-rec-autonomous-submit,
            .askagento-rec-autonomous-actions #askagento-cross-sell-autonomous-submit{margin-left:auto;}
            .askagento-rec-auto-modes{margin-top:8px;padding-top:2px;border-top:none;}
            .askagento-rec-auto-modes > legend{font-weight:600;padding:0;margin:0 0 8px 0;font-size:inherit;}
            .askagento-ai-text-live-switch-wrap{display:flex;align-items:center;flex-wrap:wrap;gap:12px 16px;margin:14px 0 4px;}
            .askagento-ai-text-live-switch{display:inline-flex;align-items:center;gap:12px;margin:0;cursor:pointer;user-select:none;}
            .askagento-ai-text-live-switch__input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}
            .askagento-ai-text-live-switch__track{position:relative;flex-shrink:0;width:48px;height:26px;background:#c3c4c7;border-radius:13px;transition:background 0.2s ease;}
            .askagento-ai-text-live-switch__thumb{position:absolute;top:3px;left:3px;width:20px;height:20px;background:#fff;border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,0.28);transition:transform 0.2s ease;}
            .askagento-ai-text-live-switch__input:checked + .askagento-ai-text-live-switch__track{background:#2271b1;}
            .askagento-ai-text-live-switch__input:checked + .askagento-ai-text-live-switch__track .askagento-ai-text-live-switch__thumb{transform:translateX(22px);}
            .askagento-ai-text-live-switch__input:focus-visible + .askagento-ai-text-live-switch__track{outline:2px solid #2271b1;outline-offset:2px;}
            .askagento-ai-text-live-switch__text{font-weight:600;font-size:14px;line-height:1.3;color:#1d2327;}
            .askagento-ai-text-live-switch__state{font-size:13px;font-weight:600;text-transform:uppercase;letter-spacing:0.04em;color:#646970;min-width:2.5em;}
            .askagento-ai-text-live-switch-wrap--on .askagento-ai-text-live-switch__state{color:#2271b1;}
            #askagento-ai-rec-auto-options{margin-top:8px;}
            .askagento-rec-setup-saved{margin:0 0 12px;padding:8px 12px;transition:opacity 0.32s ease;}
            .askagento-rec-setup-saved--hide{opacity:0;}
            #askagento-ai-rec-autonomous-status .askagento-rec-status-out,
            #askagento-ai-rec-autonomous-status.askagento-rec-status-out{font-size:13px;line-height:1.55;color:#2c3338;}
            #askagento-ai-rec-autonomous-status .askagento-rec-status-line{margin-top:8px;}
            .askagento-rec-status-install-ok{font-weight:600;color:#1d7f1d;}
            #askagento-recommend-preview .askagento-rec-preview-side,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-side{display:inline-flex;align-items:center;gap:10px;min-width:0;}
            #askagento-recommend-preview .askagento-rec-preview-src,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-src{flex:0 1 auto;}
            #askagento-recommend-preview .askagento-rec-preview-tgt,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-tgt{flex:0 1 auto;justify-content:flex-end;text-align:right;}
            #askagento-recommend-preview .askagento-rec-preview-tgt .askagento-rec-preview-label,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-tgt .askagento-rec-preview-label{text-align:right;}
            #askagento-recommend-preview .askagento-rec-preview-cols-3,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-cols-3{display:grid;grid-template-columns:minmax(120px,auto) 36px minmax(0,1fr);gap:8px 12px;align-items:start;max-width:100%;}
            #askagento-recommend-preview .askagento-rec-preview-multi,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-multi{margin-top:4px;max-width:100%;}
            #askagento-recommend-preview .askagento-rec-preview-grid-head,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-grid-head{margin-bottom:6px;}
            #askagento-recommend-preview .askagento-rec-preview-grid-head .askagento-rec-preview-grid-label-query,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-grid-head .askagento-rec-preview-grid-label-query{grid-column:1;grid-row:1;}
            #askagento-recommend-preview .askagento-rec-preview-grid-head .askagento-rec-preview-grid-label-results,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-grid-head .askagento-rec-preview-grid-label-results{grid-column:3;grid-row:1;}
            #askagento-recommend-preview .askagento-rec-preview-grid-data .askagento-rec-preview-grid-query,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-grid-data .askagento-rec-preview-grid-query{grid-column:1;grid-row:1;max-width:min(280px,100%);}
            #askagento-recommend-preview .askagento-rec-preview-grid-data .askagento-rec-preview-grid-arrow,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-grid-data .askagento-rec-preview-grid-arrow{grid-column:2;grid-row:1;align-self:center;text-align:center;color:#646970;font-size:20px;line-height:1;padding:0 2px;}
            #askagento-recommend-preview .askagento-rec-preview-grid-data .askagento-rec-preview-grid-matches,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-grid-data .askagento-rec-preview-grid-matches{grid-column:3;grid-row:1;min-width:0;}
            #askagento-recommend-preview .askagento-rec-preview-grid-data + .askagento-rec-preview-grid-data,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-grid-data + .askagento-rec-preview-grid-data{border-top:1px solid #dcdcde;padding-top:14px;margin-top:14px;}
            #askagento-recommend-preview .askagento-rec-preview-grid-label,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-grid-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.03em;color:#50575e;line-height:1.3;}
            #askagento-recommend-preview .askagento-rec-preview-grid-query .askagento-rec-preview-side,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-grid-query .askagento-rec-preview-side{flex-direction:column;align-items:flex-start;}
            #askagento-recommend-preview .askagento-rec-preview-matches,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-matches{display:flex;flex-wrap:wrap;align-items:flex-start;gap:18px 20px;}
            #askagento-recommend-preview .askagento-rec-preview-match-item,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-match-item{display:flex;flex-direction:column;align-items:center;gap:6px;max-width:140px;text-align:center;}
            #askagento-recommend-preview .askagento-rec-preview-match-item .askagento-rec-preview-side,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-match-item .askagento-rec-preview-side{flex-direction:column;align-items:center;}
            #askagento-recommend-preview .askagento-rec-preview-match-item .askagento-rec-preview-label,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-match-item .askagento-rec-preview-label{text-align:center;}
            
            .askagento-rec-download-actions #askagento-cross-sell-export-recommendations-json{margin-left:auto;}
            #askagento-recommend-preview .askagento-rec-preview-thumb,
            #askagento-cross-sell-recommend-preview .askagento-rec-preview-thumb{flex-shrink:0;width:100px;height:100px;object-fit:contain;object-position:center;vertical-align:middle;border-radius:4px;border:1px solid #dcdcde;background:#f6f7f7;box-sizing:border-box;}
        </style>
        <script>
        (function () {
            function initAutonomousToggle(cbId, panelId, stateId) {
                var cb = document.getElementById(cbId);
                var panel = document.getElementById(panelId);
                var stateEl = document.getElementById(stateId);
                var wrap = cb ? cb.closest('.askagento-ai-text-live-switch-wrap') : null;
                if (!cb || !panel) {
                    return;
                }
                function sync() {
                    panel.hidden = !cb.checked;
                    if (wrap) {
                        wrap.classList.toggle('askagento-ai-text-live-switch-wrap--on', cb.checked);
                    }
                    if (stateEl) {
                        stateEl.textContent = cb.checked
                            ? (stateEl.getAttribute('data-on') || 'On')
                            : (stateEl.getAttribute('data-off') || 'Off');
                    }
                }
                sync();
                cb.addEventListener('change', sync);
            }
            initAutonomousToggle('askagento-ai-rec-auto-enabled', 'askagento-ai-rec-auto-options', 'askagento-ai-rec-auto-state');
            initAutonomousToggle('askagento-ai-cross-sell-auto-enabled', 'askagento-ai-cross-sell-auto-options', 'askagento-ai-cross-sell-auto-state');
        })();
        <?php if ($upsell_setup_saved) : ?>
        (function () {
            var saved = document.getElementById('askagento-rec-upsell-setup-saved');
            if (!saved) {
                return;
            }
            window.setTimeout(function () {
                saved.classList.add('askagento-rec-setup-saved--hide');
                window.setTimeout(function () {
                    saved.remove();
                }, 320);
            }, 5000);
            if (window.history.replaceState) {
                try {
                    var url = new URL(window.location.href);
                    url.searchParams.delete('settings-updated');
                    window.history.replaceState({}, '', url.toString());
                } catch (e) { /* ignore */ }
            }
        })();
        <?php endif; ?>
        <?php if ($cross_sell_setup_saved) : ?>
        (function () {
            var saved = document.getElementById('askagento-rec-cross-sell-setup-saved');
            if (!saved) {
                return;
            }
            window.setTimeout(function () {
                saved.classList.add('askagento-rec-setup-saved--hide');
                window.setTimeout(function () {
                    saved.remove();
                }, 320);
            }, 5000);
            if (window.history.replaceState) {
                try {
                    var url = new URL(window.location.href);
                    url.searchParams.delete('settings-updated');
                    window.history.replaceState({}, '', url.toString());
                } catch (e) { /* ignore */ }
            }
        })();
        <?php endif; ?>
        </script>
        <script>
        jQuery(function($) {
            function escapeHtml(value) {
                return $('<div>').text(value == null ? '' : String(value)).html();
            }

            function buildPreviewRowsFromPayload(payload) {
                var recommendations = payload && payload.recommendations ? payload.recommendations : {};
                var keys = Object.keys(recommendations);
                var rows = [];
                for (var k = 0; k < keys.length && rows.length < 3; k++) {
                    var sourceId = keys[k];
                    var list = recommendations[sourceId];
                    if (!Array.isArray(list) || list.length === 0) {
                        continue;
                    }
                    var matches = [];
                    for (var i = 0; i < list.length && matches.length < 3; i++) {
                        var rec = list[i];
                        if (!rec || rec.product_id == null || rec.product_id === '') {
                            continue;
                        }
                        matches.push({
                            target_id: rec.product_id,
                            target_title: rec.title ? String(rec.title) : '',
                            target_image_url: ''
                        });
                    }
                    if (matches.length) {
                        rows.push({
                            source_id: sourceId,
                            source_title: '',
                            source_image_url: '',
                            matches: matches
                        });
                    }
                }
                return rows;
            }

            function previewThumbTag(imageUrl, label) {
                var u = imageUrl == null ? '' : String(imageUrl).trim();
                if (!u) {
                    return '';
                }
                var alt = label == null ? '' : String(label).trim();
                return '<img class="askagento-rec-preview-thumb" src="' + escapeHtml(u) + '" alt="' + escapeHtml(alt) + '" loading="lazy" />';
            }

            function previewSideHtml(title, id, imageUrl, sideClass) {
                var t = title && String(title).trim() ? escapeHtml(String(title).trim()) : '';
                var idPart = '#' + escapeHtml(String(id));
                var text = t ? (t + ' ' + idPart) : idPart;
                var rawLabel = title && String(title).trim() ? String(title).trim() : ('#' + String(id));
                var img = previewThumbTag(imageUrl, rawLabel);
                var cls = 'askagento-rec-preview-side' + (sideClass ? ' ' + sideClass : '');
                if (img) {
                    return '<span class="' + cls + '">' + img + '<span class="askagento-rec-preview-label">' + text + '</span></span>';
                }
                return '<span class="' + cls + '"><span class="askagento-rec-preview-label">' + text + '</span></span>';
            }

            function previewDataRowHtml(block, labels) {
                labels = labels || {};
                var queryWord = labels.query != null ? String(labels.query) : 'Query';
                var resultsWord = labels.results != null ? String(labels.results) : 'Results';
                var left = previewSideHtml(block.source_title, block.source_id, block.source_image_url, 'askagento-rec-preview-src');
                var parts = [];
                block.matches.forEach(function(m) {
                    parts.push(
                        '<div class="askagento-rec-preview-match-item">' +
                        previewSideHtml(m.target_title, m.target_id, m.target_image_url, 'askagento-rec-preview-tgt') +
                        '</div>'
                    );
                });
                return '<div class="askagento-rec-preview-cols-3 askagento-rec-preview-grid-data">' +
                    '<div class="askagento-rec-preview-grid-query">' + left + '</div>' +
                    '<div class="askagento-rec-preview-grid-arrow" aria-hidden="true" title="' + escapeHtml(queryWord + ' → ' + resultsWord) + '">→</div>' +
                    '<div class="askagento-rec-preview-grid-matches"><div class="askagento-rec-preview-matches">' + parts.join('') + '</div></div>' +
                    '</div>';
            }

            function previewMultiHtml(blocks, labels) {
                if (!blocks || !blocks.length) {
                    return '';
                }
                labels = labels || {};
                var queryWord = escapeHtml(labels.query != null ? String(labels.query) : 'Query');
                var resultsWord = escapeHtml(labels.results != null ? String(labels.results) : 'Results');
                var head = '<div class="askagento-rec-preview-cols-3 askagento-rec-preview-grid-head">' +
                    '<div class="askagento-rec-preview-grid-label askagento-rec-preview-grid-label-query">' + queryWord + '</div>' +
                    '<span class="askagento-rec-preview-grid-head-mid" aria-hidden="true"></span>' +
                    '<div class="askagento-rec-preview-grid-label askagento-rec-preview-grid-label-results">' + resultsWord + '</div>' +
                    '</div>';
                var body = '';
                blocks.forEach(function(block) {
                    body += previewDataRowHtml(block, labels);
                });
                return '<div class="askagento-rec-preview-multi">' + head + body + '</div>';
            }

            function triggerJsonDownload(contents, filename) {
                try {
                    var blob = new Blob([contents], { type: 'application/json;charset=utf-8' });
                    var url = window.URL.createObjectURL(blob);
                    var a = document.createElement('a');
                    a.href = url;
                    a.download = filename || 'recommendations.json';
                    a.style.display = 'none';
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                    window.URL.revokeObjectURL(url);
                } catch (e) {}
            }

            $('#askagento-export-recommendations-json').on('click', function() {
                var $btn = $(this);
                var $status = $('#askagento-recommend-status');
                if ($btn.prop('disabled')) {
                    return;
                }
                $btn.prop('disabled', true);

                $.post(ajaxurl, {
                    action: 'askagento_recommend_upsell_export_stored_json',
                    nonce: '<?php echo esc_js(wp_create_nonce('askagento_admin')); ?>'
                }, function(resp) {
                    if (!resp.success) {
                        var message = resp.data && resp.data.message ? resp.data.message : '<?php echo esc_js(__('Export failed.', 'askagento')); ?>';
                        $status.append('<div style="margin-top:8px;"><span style="color:#b32d2e;">' + escapeHtml(message) + '</span></div>');
                        $btn.prop('disabled', false);
                        return;
                    }

                    var filename = resp.data && resp.data.filename ? resp.data.filename : 'recommendations.json';
                    var body = resp.data && resp.data.body ? resp.data.body : '';

                    triggerJsonDownload(body, filename);
                    var ok = '<div style="margin-top:8px;"><span style="color:green;">' +
                        escapeHtml('<?php echo esc_js(__('File download started:', 'askagento')); ?> ') +
                        escapeHtml(filename) +
                        '</span></div>';

                    var $note = $('#askagento-export-download-note');
                    if ($note.length) {
                        $note.remove();
                    }
                    $status.append(ok);

                    var $dur = $('<div>', { id: 'askagento-export-download-note', style: 'margin-top:6px;', class: 'description' });
                    $dur.text('<?php echo esc_js(__('If no file appeared, check your browser’s download blocker or Downloads folder.', 'askagento')); ?>');
                    $status.append($dur);

                    $btn.prop('disabled', false);
                }).fail(function(xhr) {
                    var message = '<?php echo esc_js(__('Request failed', 'askagento')); ?>';
                    var text = xhr && xhr.responseText ? String(xhr.responseText) : '';
                    if (text) {
                        try {
                            var parsed = JSON.parse(text);
                            if (parsed && parsed.data && parsed.data.message) {
                                message = parsed.data.message;
                            }
                        } catch (e) {
                            if (text.trim() === '-1') {
                                message = '<?php echo esc_js(__('Security check failed. Please reload the page.', 'askagento')); ?>';
                            }
                        }
                    }
                    $status.append('<div style="margin-top:8px;"><span style="color:#b32d2e;">' + escapeHtml(message) + '</span></div>');
                    $btn.prop('disabled', false);
                });
            });

            function countRecommendations(payload) {
                var totalProducts = 0;
                var totalRows = 0;
                var recommendations = {};
                if (payload && payload.cross_sells && typeof payload.cross_sells === 'object') {
                    recommendations = payload.cross_sells;
                } else if (payload && payload.recommendations) {
                    recommendations = payload.recommendations;
                }
                Object.keys(recommendations).forEach(function(productId) {
                    totalProducts += 1;
                    var list = recommendations[productId];
                    if (Array.isArray(list)) {
                        totalRows += list.length;
                    }
                });
                return { totalProducts: totalProducts, totalRows: totalRows };
            }

            function pfFormatPingSecCommaOne(msStart) {
                if (typeof msStart !== 'number') {
                    return '';
                }
                var sec = (Date.now() - msStart) / 1000;
                return sec.toFixed(1).replace('.', ',');
            }

            function renderUpsellDownloadSuccessUi(resp, $status, $preview, downloadStartMs) {
                var payload = resp.data && resp.data.payload ? resp.data.payload : {};
                var counters = countRecommendations(payload);
                var previewRows = [];
                var pft = resp.data.preview_first_three;
                if (Array.isArray(pft) && pft.length) {
                    pft.forEach(function(row) {
                        if (row && row.matches && Array.isArray(row.matches) && row.matches.length) {
                            previewRows.push(row);
                        }
                    });
                } else if (pft && typeof pft === 'object' && pft.matches && Array.isArray(pft.matches) && pft.matches.length) {
                    previewRows = [pft];
                }
                if (previewRows.length === 0) {
                    previewRows = buildPreviewRowsFromPayload(payload);
                }

                var pingLine = '';
                var pingStr = pfFormatPingSecCommaOne(downloadStartMs);
                if (pingStr !== '') {
                    pingLine = '<div class="description" style="margin-top:8px;margin-bottom:0;"><?php echo esc_js(__('Ping:', 'askagento')); ?> ' + pingStr + ' <?php echo esc_js(__('s', 'askagento')); ?></div>';
                }

                $status.html(
                    '<div><span style="color:green;"><?php echo esc_js(__('Downloaded and stored on this shop.', 'askagento')); ?></span> ' +
                    '<span><?php echo esc_js(__('Products with recommendations:', 'askagento')); ?> ' + counters.totalProducts + '</span>' +
                    ' | <span><?php echo esc_js(__('Total recommendation rows:', 'askagento')); ?> ' + counters.totalRows + '</span></div>' +
                    pingLine
                );

                if (previewRows.length > 0) {
                    var previewLegend = {
                        query: '<?php echo esc_js(__('Query', 'askagento')); ?>',
                        results: '<?php echo esc_js(__('Results', 'askagento')); ?>'
                    };
                    var html = '<p><strong><?php echo esc_js(__('Preview three random products: query → results', 'askagento')); ?></strong></p>' +
                        previewMultiHtml(previewRows, previewLegend);
                    $preview.html(html);
                } else {
                    $preview.html('<p><?php echo esc_js(__('No recommendations available to preview.', 'askagento')); ?></p>');
                }

                $('#askagento-export-recommendations-json').prop('disabled', false);
                askagentoHasStoredUpsell = true;
            }

            var askagentoHasStoredUpsell = <?php echo wp_json_encode($has_stored_upsell); ?>;

            $('#askagento-download-recommendations').on('click', function() {
                var $btn = $(this);
                var $status = $('#askagento-recommend-status');
                var $preview = $('#askagento-recommend-preview');
                var $installHelp = $('#askagento-install-help');
                var downloadStartMs = Date.now();
                setRecommendationsBusy(true);
                $status.html('<?php echo esc_js(__('Downloading...', 'askagento')); ?>');
                $preview.html('');
                $installHelp.html('');

                $.post(ajaxurl, {
                    action: 'askagento_recommend_upsell_download',
                    nonce: '<?php echo esc_js(wp_create_nonce('askagento_admin')); ?>'
                }, function(resp) {
                    if (!resp.success) {
                        var message = resp.data && resp.data.message ? resp.data.message : '<?php echo esc_js(__('Failed to download recommendations', 'askagento')); ?>';
                        $status.html('<span style="color:red;">' + escapeHtml(message) + '</span>');
                        setRecommendationsBusy(false);
                        return;
                    }

                    renderUpsellDownloadSuccessUi(resp, $status, $preview, downloadStartMs);
                    setRecommendationsBusy(false);
                }).fail(function(xhr) {
                    var fallback = '<?php echo esc_js(__('Request failed', 'askagento')); ?>';
                    var text = xhr && xhr.responseText ? String(xhr.responseText) : '';
                    var message = fallback;
                    if (text) {
                        try {
                            var parsed = JSON.parse(text);
                            if (parsed && parsed.data && parsed.data.message) {
                                message = parsed.data.message;
                            }
                        } catch (e) {
                            if (text.trim() === '-1') {
                                message = '<?php echo esc_js(__('Security check failed. Please reload the page.', 'askagento')); ?>';
                            }
                        }
                    }
                    $status.html('<span style="color:red;">' + escapeHtml(message) + '</span>');
                    setRecommendationsBusy(false);
                });
            });

            function setRecommendationsBusy(busy) {
                $('#askagento-download-recommendations').prop('disabled', busy);
                $('#askagento-install-recommendations-manual').prop('disabled', busy);
                $('.askagento-install-mode-input').prop('disabled', busy);
            }

            function recommendInstallFailMessage(xhr, fallback) {
                var status = xhr && typeof xhr.status !== 'undefined' ? parseInt(xhr.status, 10) : 0;
                if (status === 0 || status === 504 || status === 502) {
                    return '<?php echo esc_js(__('The request timed out or was interrupted. Try again; large catalogs install in batches automatically.', 'askagento')); ?>';
                }
                var text = xhr && xhr.responseText ? String(xhr.responseText) : '';
                if (text) {
                    try {
                        var parsed = JSON.parse(text);
                        if (parsed && parsed.data && parsed.data.message) {
                            return parsed.data.message;
                        }
                    } catch (e) {
                        if (text.trim() === '-1') {
                            return '<?php echo esc_js(__('Security check failed. Please reload the page.', 'askagento')); ?>';
                        }
                    }
                }
                return fallback;
            }

            function runBatchedRecommendInstall(config) {
                var offset = 0;
                var totals = {
                    updated_products: 0,
                    linked_rows: 0,
                    skipped_products: 0
                };

                function renderProgress(data) {
                    var total = data && data.batch_total ? parseInt(data.batch_total, 10) : 0;
                    var doneCount = 0;
                    if (data && typeof data.batch_offset !== 'undefined' && typeof data.batch_processed !== 'undefined') {
                        doneCount = parseInt(data.batch_offset, 10) + parseInt(data.batch_processed, 10);
                    }
                    if (total > 0) {
                        config.$help.html(
                            '<p>' + escapeHtml(config.progressLabel) + ' ' +
                            escapeHtml(String(doneCount)) + ' / ' + escapeHtml(String(total)) +
                            '</p>'
                        );
                    } else {
                        config.$help.html('<p>' + escapeHtml(config.progressLabel) + '</p>');
                    }
                }

                function renderSuccess(usedMode) {
                    var nothingChanged = (usedMode === 'fill_missing' && totals.updated_products === 0 && totals.skipped_products > 0);
                    if (nothingChanged) {
                        config.$help.html(
                            '<p class="description" style="margin-top:0;color:#2c3338;font-weight:600;">' +
                            escapeHtml(config.nothingChangedMessage) +
                            '</p>'
                        );
                        config.setBusy(false);
                        return;
                    }

                    var statsLine = '<?php echo esc_js(__('Products updated:', 'askagento')); ?> ' + totals.updated_products +
                        ' | <?php echo esc_js(__('Recommendation links written:', 'askagento')); ?> ' + totals.linked_rows;
                    if (usedMode === 'fill_missing' && totals.skipped_products > 0) {
                        statsLine += ' | <?php echo esc_js(__('Skipped (already had links):', 'askagento')); ?> ' + totals.skipped_products;
                    }

                    config.$help.html(
                        '<p style="color:#00a32a;font-weight:700;"><?php echo esc_js(__('Recommendations installed.', 'askagento')); ?></p>' +
                        '<p>' + escapeHtml(statsLine) + '</p>' +
                        '<p style="margin-top:10px;"><?php echo esc_js(__('Applied in shop:', 'askagento')); ?></p>' +
                        config.appliedHtml
                    );
                    config.setBusy(false);
                }

                function runBatch() {
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        timeout: 120000,
                        data: {
                            action: config.action,
                            nonce: '<?php echo esc_js(wp_create_nonce('askagento_admin')); ?>',
                            mode: config.mode,
                            offset: offset
                        }
                    }).done(function(resp) {
                        if (!resp.success) {
                            var message = resp.data && resp.data.message ? resp.data.message : config.failedMessage;
                            config.$help.html('<p style="color:red;">' + escapeHtml(message) + '</p>');
                            config.setBusy(false);
                            return;
                        }

                        var data = resp.data || {};
                        totals.updated_products += data.updated_products ? parseInt(data.updated_products, 10) : 0;
                        totals.linked_rows += data.linked_rows ? parseInt(data.linked_rows, 10) : 0;
                        totals.skipped_products += typeof data.skipped_products !== 'undefined' ? parseInt(data.skipped_products, 10) : 0;

                        var usedMode = data.mode ? data.mode : config.mode;
                        if (data.batch_done === false && data.next_offset != null) {
                            renderProgress(data);
                            offset = parseInt(data.next_offset, 10);
                            runBatch();
                            return;
                        }

                        renderSuccess(usedMode);
                    }).fail(function(xhr, textStatus) {
                        var fallback = config.requestFailedMessage;
                        if (textStatus === 'timeout') {
                            fallback = '<?php echo esc_js(__('The request timed out. Try again; large catalogs install in batches automatically.', 'askagento')); ?>';
                        }
                        config.$help.html(
                            '<p style="color:red;">' +
                            escapeHtml(recommendInstallFailMessage(xhr, fallback)) +
                            '</p>'
                        );
                        config.setBusy(false);
                    });
                }

                renderProgress(null);
                runBatch();
            }

            function runUpsellInstallAfterDownload(mode, $help) {
                runBatchedRecommendInstall({
                    action: 'askagento_recommend_upsell_install',
                    mode: mode,
                    $help: $help,
                    setBusy: setRecommendationsBusy,
                    progressLabel: '<?php echo esc_js(__('Installing upsell recommendations into WooCommerce…', 'askagento')); ?>',
                    failedMessage: '<?php echo esc_js(__('Installation failed.', 'askagento')); ?>',
                    requestFailedMessage: '<?php echo esc_js(__('Request failed', 'askagento')); ?>',
                    nothingChangedMessage: '<?php echo esc_js(__('Nothing was changed: every product in the bundle already had AI recommendation links.', 'askagento')); ?>',
                    appliedHtml: '<ul style="list-style:disc;margin-left:20px;">' +
                        '<li><?php echo esc_js(__('Upsells: Product page “You may also like”', 'askagento')); ?></li>' +
                        '<li><?php echo esc_js(__('Related products: Product detail recommendations', 'askagento')); ?></li>' +
                        '</ul>'
                });
            }

            $('#askagento-install-recommendations-manual').on('click', function() {
                var $help = $('#askagento-install-help');
                var $status = $('#askagento-recommend-status');
                var $preview = $('#askagento-recommend-preview');
                var mode = $('input[name="askagento_install_mode"]:checked').val() || 'replace_all';
                var downloadStartMs = Date.now();

                setRecommendationsBusy(true);

                if (askagentoHasStoredUpsell) {
                    runUpsellInstallAfterDownload(mode, $help);
                    return;
                }

                $help.html('<p><?php echo esc_js(__('Downloading latest upsell recommendations…', 'askagento')); ?></p>');
                $preview.html('');

                $.post(ajaxurl, {
                    action: 'askagento_recommend_upsell_download',
                    nonce: '<?php echo esc_js(wp_create_nonce('askagento_admin')); ?>'
                }, function(resp) {
                    if (!resp.success) {
                        var message = resp.data && resp.data.message ? resp.data.message : '<?php echo esc_js(__('Failed to download recommendations', 'askagento')); ?>';
                        $help.html('<p style="color:red;">' + escapeHtml(message) + '</p>');
                        setRecommendationsBusy(false);
                        return;
                    }

                    renderUpsellDownloadSuccessUi(resp, $status, $preview, downloadStartMs);
                    runUpsellInstallAfterDownload(mode, $help);
                }).fail(function(xhr) {
                    var fallback = '<?php echo esc_js(__('Request failed', 'askagento')); ?>';
                    var text = xhr && xhr.responseText ? String(xhr.responseText) : '';
                    var message = fallback;
                    if (text) {
                        try {
                            var parsed = JSON.parse(text);
                            if (parsed && parsed.data && parsed.data.message) {
                                message = parsed.data.message;
                            }
                        } catch (e) {
                            if (text.trim() === '-1') {
                                message = '<?php echo esc_js(__('Security check failed. Please reload the page.', 'askagento')); ?>';
                            }
                        }
                    }
                    $help.html('<p style="color:red;">' + escapeHtml(message) + '</p>');
                    setRecommendationsBusy(false);
                });
            });

            function pfFormatAdminDateTime(value) {
                if (value == null || value === '') {
                    return '';
                }
                var s = String(value).trim();
                if (!s) {
                    return '';
                }
                if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}/.test(s)) {
                    s = s.replace(' ', 'T');
                }
                var parsed = new Date(s);
                if (isNaN(parsed.getTime())) {
                    return s;
                }
                var y = parsed.getFullYear();
                var m = String(parsed.getMonth() + 1).padStart(2, '0');
                var d = String(parsed.getDate()).padStart(2, '0');
                var h = String(parsed.getHours()).padStart(2, '0');
                var min = String(parsed.getMinutes()).padStart(2, '0');
                return y + '-' + m + '-' + d + ' ' + h + ':' + min;
            }

            function pfFormatUnixLocal(ts) {
                if (!ts) {
                    return '';
                }
                var parsed = new Date(parseInt(ts, 10) * 1000);
                if (isNaN(parsed.getTime())) {
                    return '';
                }
                var y = parsed.getFullYear();
                var m = String(parsed.getMonth() + 1).padStart(2, '0');
                var d = String(parsed.getDate()).padStart(2, '0');
                var h = String(parsed.getHours()).padStart(2, '0');
                var min = String(parsed.getMinutes()).padStart(2, '0');
                return y + '-' + m + '-' + d + ' ' + h + ':' + min;
            }

            $('#askagento-ai-rec-autonomous-check-status').on('click', function() {
                var $btn = $(this);
                var $out = $('#askagento-ai-rec-autonomous-status');
                var timeStart = Date.now();
                $btn.prop('disabled', true);
                $out.html('<div class="askagento-rec-status-out"><p class="askagento-rec-status-line" style="margin-top:0;"><?php echo esc_js(__('Checking…', 'askagento')); ?></p></div>');

                $.post(ajaxurl, {
                    action: 'askagento_recommend_upsell_combined_admin_status',
                    nonce: '<?php echo esc_js(wp_create_nonce('askagento_admin')); ?>'
                }, function(resp) {
                    var pingSec = ((Date.now() - timeStart) / 1000).toFixed(1);
                    if (!resp.success) {
                        var message = resp.data && resp.data.message ? resp.data.message : '<?php echo esc_js(__('Could not fetch status.', 'askagento')); ?>';
                        $out.html('<p style="color:#b32d2e;">' + escapeHtml(message) + '</p>');
                        $btn.prop('disabled', false);
                        return;
                    }

                    var data = resp.data || {};
                    var inst = data.installation || {};
                    var auto = data.autonomous || {};

                    var block = '';

                    if (inst.ok && inst.payload) {
                        var p = inst.payload;
                        var st = typeof p.status !== 'undefined' && p.status !== null ? String(p.status) : '<?php echo esc_js(__('unknown', 'askagento')); ?>';
                        var lineOk = '<div class="askagento-rec-status-line" style="margin-top:0;"><strong><?php echo esc_js(__('Installation API:', 'askagento')); ?></strong> ';
                        lineOk += '<span class="askagento-rec-status-install-ok">' + escapeHtml(st) + '</span></div>';
                        block += lineOk;
                    } else if (!inst.ok) {
                        block += '<div class="askagento-rec-status-line" style="margin-top:0;"><strong><?php echo esc_js(__('Installation API:', 'askagento')); ?></strong> ';
                        block += '<span style="color:#b32d2e;">' + escapeHtml(inst.message || '<?php echo esc_js(__('Unavailable', 'askagento')); ?>') + '</span></div>';
                    }

                    block += '<div class="askagento-rec-status-line"><strong><?php echo esc_js(__('Autonomous:', 'askagento')); ?></strong> ';
                    block += escapeHtml(auto.enabled ? '<?php echo esc_js(__('On', 'askagento')); ?>' : '<?php echo esc_js(__('Off', 'askagento')); ?>');
                    block += ' · <?php echo esc_js(__('merge mode', 'askagento')); ?>: ';
                    block += escapeHtml(auto.install_mode === 'fill_missing'
                        ? '<?php echo esc_js(__('add missing only', 'askagento')); ?>'
                        : '<?php echo esc_js(__('replace existing', 'askagento')); ?>');
                    block += '</div>';

                    var nextCronTxt = pfFormatUnixLocal(auto.cron_next_unix);
                    if (auto.enabled && nextCronTxt) {
                        block += '<div class="askagento-rec-status-line"><strong><?php echo esc_js(__('Next scheduled refresh:', 'askagento')); ?></strong> ' +
                            escapeHtml(nextCronTxt) + '</div>';
                    } else if (auto.enabled && !nextCronTxt) {
                        block += '<div class="askagento-rec-status-line"><?php echo esc_js(__('Next cron run: not scheduled yet. Save settings or revisit this page.', 'askagento')); ?></div>';
                    }

                    if (auto.last_run && auto.last_run.time) {
                        var lr = ['<?php echo esc_js(__('Last autonomous merge:', 'askagento')); ?> ' + escapeHtml(pfFormatAdminDateTime(auto.last_run.time))];
                        if (typeof auto.last_run.updated_products !== 'undefined') {
                            lr.push('<?php echo esc_js(__('updated', 'askagento')); ?> ' + auto.last_run.updated_products);
                            lr.push('<?php echo esc_js(__('links', 'askagento')); ?> ' + auto.last_run.linked_rows);
                            if (auto.last_run.skipped_products > 0) {
                                lr.push('<?php echo esc_js(__('skipped', 'askagento')); ?> ' + auto.last_run.skipped_products);
                            }
                        }
                        block += '<div class="askagento-rec-status-line">' + escapeHtml(lr.join(' | ')) + '</div>';
                    }

                    if (auto.last_error && auto.last_error.message) {
                        block += '<div class="askagento-rec-status-line"><strong><?php echo esc_js(__('Last error:', 'askagento')); ?></strong> ';
                        block += '<span style="color:#b32d2e;">' + escapeHtml(String(auto.last_error.message));
                        if (auto.last_error.time) {
                            block += ' (' + escapeHtml(pfFormatAdminDateTime(auto.last_error.time)) + ')';
                        }
                        block += '</span></div>';
                    }

                    block += '<div class="askagento-rec-status-line">Ping: ' + pingSec + ' s</div>';
                    $out.html('<div class="askagento-rec-status-out">' + block + '</div>');
                    $btn.prop('disabled', false);
                }).fail(function() {
                    $out.html('<p style="color:#b32d2e;"><?php echo esc_js(__('Request failed', 'askagento')); ?></p>');
                    $btn.prop('disabled', false);
                });
            });

            $('#askagento-clear-recommendations-links').on('click', function() {
                var $btn = $(this);
                var $help = $('#askagento-install-help');
                if (!window.confirm('<?php echo esc_js(__('Clear all AI recommendation links from your products? You can install recommendations again later.', 'askagento')); ?>')) {
                    return;
                }
                $btn.prop('disabled', true);
                $help.html('<p><?php echo esc_js(__('Clearing recommendation links...', 'askagento')); ?></p>');

                $.post(ajaxurl, {
                    action: 'askagento_recommend_upsell_clear',
                    nonce: '<?php echo esc_js(wp_create_nonce('askagento_admin')); ?>'
                }, function(resp) {
                    if (!resp.success) {
                        var message = resp.data && resp.data.message ? resp.data.message : '<?php echo esc_js(__('Clear failed.', 'askagento')); ?>';
                        $help.html('<p style="color:red;">' + escapeHtml(message) + '</p>');
                        $btn.prop('disabled', false);
                        return;
                    }

                    var updatedProducts = resp.data && resp.data.updated_products ? resp.data.updated_products : 0;
                    var hint = resp.data && resp.data.hint ? resp.data.hint : '';
                    var clearedHtml = '<p style="color:green;"><strong><?php echo esc_js(__('Cleared.', 'askagento')); ?></strong> ' +
                        '<?php echo esc_js(__('Updated products:', 'askagento')); ?> ' + updatedProducts + '</p>';
                    if (hint) {
                        clearedHtml += '<p class="description" style="margin-top:8px;">' + escapeHtml(hint) + '</p>';
                    }
                    $help.html(clearedHtml);
                    $btn.prop('disabled', false);
                }).fail(function(xhr) {
                    var fallback = '<?php echo esc_js(__('Request failed', 'askagento')); ?>';
                    var text = xhr && xhr.responseText ? String(xhr.responseText) : '';
                    var message = fallback;
                    if (text) {
                        try {
                            var parsed = JSON.parse(text);
                            if (parsed && parsed.data && parsed.data.message) {
                                message = parsed.data.message;
                            }
                        } catch (e) {}
                    }
                    $help.html('<p style="color:red;">' + escapeHtml(message) + '</p>');
                    $btn.prop('disabled', false);
                });
            });


            // Cross-sell workflow (mirrors upsell; keep function names unique).
            function pfBoldCrossSellGenerateFirstPhrase(message) {
                var escaped = escapeHtml(message == null ? '' : String(message));
                var phrase = '<?php echo esc_js(__('Cross-sell recommendations are not available yet', 'askagento')); ?>';
                var phraseEscaped = escapeHtml(phrase);
                if (!phraseEscaped) {
                    return escaped;
                }
                var idx = escaped.indexOf(phraseEscaped);
                if (idx === -1) {
                    return escaped;
                }
                var end = idx + phraseEscaped.length;
                var tail = escaped.charAt(end);
                var punct = (tail === '.' || tail === ',') ? tail : '';
                var endPos = punct ? end + 1 : end;
                return escaped.slice(0, idx) +
                    '<strong>' + phraseEscaped + punct + '</strong>' +
                    escaped.slice(endPos);
            }

            function pfCrossSellAdminMessageHtml(respData, fallbackMessage, asParagraph) {
                var message = respData && respData.message ? respData.message : fallbackMessage;
                var code = respData && respData.code ? respData.code : '';
                if (code === 'not_published') {
                    var body = pfBoldCrossSellGenerateFirstPhrase(message);
                    if (asParagraph) {
                        return '<p class="description askagento-cross-sell-not-published" style="margin:0;color:#2c3338;">' + body + '</p>';
                    }
                    return '<span class="description askagento-cross-sell-not-published" style="color:#2c3338;">' + body + '</span>';
                }
                if (asParagraph) {
                    return '<p style="color:red;margin:0;">' + escapeHtml(message) + '</p>';
                }
                return '<span style="color:red;">' + escapeHtml(message) + '</span>';
            }

            $('#askagento-cross-sell-export-recommendations-json').on('click', function() {
                var $btn = $(this);
                var $status = $('#askagento-cross-sell-recommend-status');
                if ($btn.prop('disabled')) {
                    return;
                }
                $btn.prop('disabled', true);

                $.post(ajaxurl, {
                    action: 'askagento_recommend_cross_sell_export_stored_json',
                    nonce: '<?php echo esc_js(wp_create_nonce('askagento_admin')); ?>'
                }, function(resp) {
                    if (!resp.success) {
                        var message = resp.data && resp.data.message ? resp.data.message : '<?php echo esc_js(__('Export failed.', 'askagento')); ?>';
                        $status.append('<div style="margin-top:8px;"><span style="color:#b32d2e;">' + escapeHtml(message) + '</span></div>');
                        $btn.prop('disabled', false);
                        return;
                    }

                    var filename = resp.data && resp.data.filename ? resp.data.filename : 'recommendations.json';
                    var body = resp.data && resp.data.body ? resp.data.body : '';

                    triggerJsonDownload(body, filename);
                    var ok = '<div style="margin-top:8px;"><span style="color:green;">' +
                        escapeHtml('<?php echo esc_js(__('File download started:', 'askagento')); ?> ') +
                        escapeHtml(filename) +
                        '</span></div>';

                    var $note = $('#askagento-cross-sell-export-download-note');
                    if ($note.length) {
                        $note.remove();
                    }
                    $status.append(ok);

                    var $dur = $('<div>', { id: 'askagento-export-download-note', style: 'margin-top:6px;', class: 'description' });
                    $dur.text('<?php echo esc_js(__('If no file appeared, check your browser’s download blocker or Downloads folder.', 'askagento')); ?>');
                    $status.append($dur);

                    $btn.prop('disabled', false);
                }).fail(function(xhr) {
                    var message = '<?php echo esc_js(__('Request failed', 'askagento')); ?>';
                    var text = xhr && xhr.responseText ? String(xhr.responseText) : '';
                    if (text) {
                        try {
                            var parsed = JSON.parse(text);
                            if (parsed && parsed.data && parsed.data.message) {
                                message = parsed.data.message;
                            }
                        } catch (e) {
                            if (text.trim() === '-1') {
                                message = '<?php echo esc_js(__('Security check failed. Please reload the page.', 'askagento')); ?>';
                            }
                        }
                    }
                    $status.append('<div style="margin-top:8px;"><span style="color:#b32d2e;">' + escapeHtml(message) + '</span></div>');
                    $btn.prop('disabled', false);
                });
            });

            function countRecommendations(payload) {
                var totalProducts = 0;
                var totalRows = 0;
                var recommendations = {};
                if (payload && payload.cross_sells && typeof payload.cross_sells === 'object') {
                    recommendations = payload.cross_sells;
                } else if (payload && payload.recommendations) {
                    recommendations = payload.recommendations;
                }
                Object.keys(recommendations).forEach(function(productId) {
                    totalProducts += 1;
                    var list = recommendations[productId];
                    if (Array.isArray(list)) {
                        totalRows += list.length;
                    }
                });
                return { totalProducts: totalProducts, totalRows: totalRows };
            }

            function pfFormatPingSecCommaOne(msStart) {
                if (typeof msStart !== 'number') {
                    return '';
                }
                var sec = (Date.now() - msStart) / 1000;
                return sec.toFixed(1).replace('.', ',');
            }

            function renderCrossSellDownloadSuccessUi(resp, $status, $preview, downloadStartMs) {
                var payload = resp.data && resp.data.payload ? resp.data.payload : {};
                var counters = countRecommendations(payload);
                var previewRows = [];
                var pft = resp.data.preview_first_three;
                if (Array.isArray(pft) && pft.length) {
                    pft.forEach(function(row) {
                        if (row && row.matches && Array.isArray(row.matches) && row.matches.length) {
                            previewRows.push(row);
                        }
                    });
                } else if (pft && typeof pft === 'object' && pft.matches && Array.isArray(pft.matches) && pft.matches.length) {
                    previewRows = [pft];
                }
                if (previewRows.length === 0) {
                    previewRows = buildPreviewRowsFromPayload(payload);
                }

                var pingLine = '';
                var pingStr = pfFormatPingSecCommaOne(downloadStartMs);
                if (pingStr !== '') {
                    pingLine = '<div class="description" style="margin-top:8px;margin-bottom:0;"><?php echo esc_js(__('Ping:', 'askagento')); ?> ' + pingStr + ' <?php echo esc_js(__('s', 'askagento')); ?></div>';
                }

                $status.html(
                    '<div><span style="color:green;"><?php echo esc_js(__('Downloaded and stored on this shop.', 'askagento')); ?></span> ' +
                    '<span><?php echo esc_js(__('Products with recommendations:', 'askagento')); ?> ' + counters.totalProducts + '</span>' +
                    ' | <span><?php echo esc_js(__('Total recommendation rows:', 'askagento')); ?> ' + counters.totalRows + '</span></div>' +
                    pingLine
                );

                if (previewRows.length > 0) {
                    var previewLegend = {
                        query: '<?php echo esc_js(__('Query', 'askagento')); ?>',
                        results: '<?php echo esc_js(__('Results', 'askagento')); ?>'
                    };
                    var html = '<p><strong><?php echo esc_js(__('Preview three random products: query → results', 'askagento')); ?></strong></p>' +
                        previewMultiHtml(previewRows, previewLegend);
                    $preview.html(html);
                } else {
                    $preview.html('<p><?php echo esc_js(__('No recommendations available to preview.', 'askagento')); ?></p>');
                }

                $('#askagento-cross-sell-export-recommendations-json').prop('disabled', false);
                askagentoHasStoredCrossSell = true;
            }

            var askagentoHasStoredCrossSell = <?php echo wp_json_encode($has_stored_cross_sell); ?>;

            $('#askagento-cross-sell-download-recommendations').on('click', function() {
                var $btn = $(this);
                var $status = $('#askagento-cross-sell-recommend-status');
                var $preview = $('#askagento-cross-sell-recommend-preview');
                var $installHelp = $('#askagento-cross-sell-install-help');
                var downloadStartMs = Date.now();
                setCrossSellRecommendationsBusy(true);
                $status.html('<?php echo esc_js(__('Downloading...', 'askagento')); ?>');
                $preview.html('');
                $installHelp.html('');

                $.post(ajaxurl, {
                    action: 'askagento_recommend_cross_sell_download',
                    nonce: '<?php echo esc_js(wp_create_nonce('askagento_admin')); ?>'
                }, function(resp) {
                    if (!resp.success) {
                        $status.html(pfCrossSellAdminMessageHtml(
                            resp.data,
                            '<?php echo esc_js(__('Failed to download recommendations', 'askagento')); ?>',
                            false
                        ));
                        setCrossSellRecommendationsBusy(false);
                        return;
                    }

                    renderCrossSellDownloadSuccessUi(resp, $status, $preview, downloadStartMs);
                    setCrossSellRecommendationsBusy(false);
                }).fail(function(xhr) {
                    var fallback = '<?php echo esc_js(__('Request failed', 'askagento')); ?>';
                    var text = xhr && xhr.responseText ? String(xhr.responseText) : '';
                    var respData = null;
                    if (text) {
                        try {
                            var parsed = JSON.parse(text);
                            if (parsed && parsed.data) {
                                respData = parsed.data;
                            }
                        } catch (e) {
                            if (text.trim() === '-1') {
                                respData = { message: '<?php echo esc_js(__('Security check failed. Please reload the page.', 'askagento')); ?>' };
                            }
                        }
                    }
                    $status.html(pfCrossSellAdminMessageHtml(respData, fallback, false));
                    setCrossSellRecommendationsBusy(false);
                });
            });

            function setCrossSellRecommendationsBusy(busy) {
                $('#askagento-cross-sell-download-recommendations').prop('disabled', busy);
                $('#askagento-cross-sell-install-recommendations-manual').prop('disabled', busy);
                $('.askagento-cross-sell-install-mode-input').prop('disabled', busy);
            }

            function runCrossSellInstallAfterDownload(mode, $help) {
                runBatchedRecommendInstall({
                    action: 'askagento_recommend_cross_sell_install',
                    mode: mode,
                    $help: $help,
                    setBusy: setCrossSellRecommendationsBusy,
                    progressLabel: '<?php echo esc_js(__('Installing cross-sell recommendations into WooCommerce…', 'askagento')); ?>',
                    failedMessage: '<?php echo esc_js(__('Installation failed.', 'askagento')); ?>',
                    requestFailedMessage: '<?php echo esc_js(__('Request failed', 'askagento')); ?>',
                    nothingChangedMessage: '<?php echo esc_js(__('Nothing was changed: every product in the bundle already had cross-sell links.', 'askagento')); ?>',
                    appliedHtml: '<ul style="list-style:disc;margin-left:20px;">' +
                        '<li><?php echo esc_js(__('Cross-sells: Linked products on the product edit screen', 'askagento')); ?></li>' +
                        '<li><?php echo esc_js(__('Cart and checkout cross-sell suggestions', 'askagento')); ?></li>' +
                        '</ul>'
                });
            }

            $('#askagento-cross-sell-install-recommendations-manual').on('click', function() {
                var $help = $('#askagento-cross-sell-install-help');
                var $status = $('#askagento-cross-sell-recommend-status');
                var $preview = $('#askagento-cross-sell-recommend-preview');
                var mode = $('input[name="askagento_cross_sell_install_mode"]:checked').val() || 'replace_all';
                var downloadStartMs = Date.now();

                setCrossSellRecommendationsBusy(true);

                if (askagentoHasStoredCrossSell) {
                    runCrossSellInstallAfterDownload(mode, $help);
                    return;
                }

                $help.html('<p><?php echo esc_js(__('Downloading latest cross-sell recommendations…', 'askagento')); ?></p>');
                $preview.html('');

                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    timeout: 120000,
                    data: {
                        action: 'askagento_recommend_cross_sell_download',
                        nonce: '<?php echo esc_js(wp_create_nonce('askagento_admin')); ?>'
                    }
                }).done(function(resp) {
                    if (!resp.success) {
                        $help.html(pfCrossSellAdminMessageHtml(
                            resp.data,
                            '<?php echo esc_js(__('Failed to download cross-sell recommendations', 'askagento')); ?>',
                            true
                        ));
                        setCrossSellRecommendationsBusy(false);
                        return;
                    }

                    renderCrossSellDownloadSuccessUi(resp, $status, $preview, downloadStartMs);
                    runCrossSellInstallAfterDownload(mode, $help);
                }).fail(function(xhr, textStatus) {
                    var fallback = '<?php echo esc_js(__('Request failed', 'askagento')); ?>';
                    if (textStatus === 'timeout') {
                        fallback = '<?php echo esc_js(__('The request timed out. Try again; large catalogs install in batches automatically.', 'askagento')); ?>';
                    }
                    var respData = null;
                    var text = xhr && xhr.responseText ? String(xhr.responseText) : '';
                    if (text) {
                        try {
                            var parsed = JSON.parse(text);
                            if (parsed && parsed.data) {
                                respData = parsed.data;
                            }
                        } catch (e) {
                            if (text.trim() === '-1') {
                                respData = { message: '<?php echo esc_js(__('Security check failed. Please reload the page.', 'askagento')); ?>' };
                            }
                        }
                    }
                    if (!respData || !respData.message) {
                        respData = { message: recommendInstallFailMessage(xhr, fallback) };
                    }
                    $help.html(pfCrossSellAdminMessageHtml(respData, fallback, true));
                    setCrossSellRecommendationsBusy(false);
                });
            });

            $('#askagento-cross-sell-clear-recommendations-links').on('click', function() {
                var $btn = $(this);
                var $help = $('#askagento-cross-sell-install-help');
                if (!window.confirm('<?php echo esc_js(__('Clear all cross-sell recommendation links from your products? You can install recommendations again later.', 'askagento')); ?>')) {
                    return;
                }
                $btn.prop('disabled', true);
                $help.html('<p><?php echo esc_js(__('Clearing cross-sell links...', 'askagento')); ?></p>');

                $.post(ajaxurl, {
                    action: 'askagento_recommend_cross_sell_clear',
                    nonce: '<?php echo esc_js(wp_create_nonce('askagento_admin')); ?>'
                }, function(resp) {
                    if (!resp.success) {
                        var message = resp.data && resp.data.message ? resp.data.message : '<?php echo esc_js(__('Clear failed.', 'askagento')); ?>';
                        $help.html('<p style="color:red;">' + escapeHtml(message) + '</p>');
                        $btn.prop('disabled', false);
                        return;
                    }

                    var updatedProducts = resp.data && resp.data.updated_products ? resp.data.updated_products : 0;
                    var hint = resp.data && resp.data.hint ? resp.data.hint : '';
                    var clearedHtml = '<p style="color:green;"><strong><?php echo esc_js(__('Cleared.', 'askagento')); ?></strong> ' +
                        '<?php echo esc_js(__('Updated products:', 'askagento')); ?> ' + updatedProducts + '</p>';
                    if (hint) {
                        clearedHtml += '<p class="description" style="margin-top:8px;">' + escapeHtml(hint) + '</p>';
                    }
                    $help.html(clearedHtml);
                    $btn.prop('disabled', false);
                }).fail(function(xhr) {
                    var fallback = '<?php echo esc_js(__('Request failed', 'askagento')); ?>';
                    var text = xhr && xhr.responseText ? String(xhr.responseText) : '';
                    var message = fallback;
                    if (text) {
                        try {
                            var parsed = JSON.parse(text);
                            if (parsed && parsed.data && parsed.data.message) {
                                message = parsed.data.message;
                            }
                        } catch (e) {}
                    }
                    $help.html('<p style="color:red;">' + escapeHtml(message) + '</p>');
                    $btn.prop('disabled', false);
                });
            });

            $('#askagento-ai-cross-sell-autonomous-check-status').on('click', function() {
                var $btn = $(this);
                var $out = $('#askagento-ai-cross-sell-autonomous-status');
                var timeStart = Date.now();
                $btn.prop('disabled', true);
                $out.html('<div class="askagento-rec-status-out"><p class="askagento-rec-status-line" style="margin-top:0;"><?php echo esc_js(__('Checking…', 'askagento')); ?></p></div>');

                $.post(ajaxurl, {
                    action: 'askagento_recommend_cross_sell_combined_admin_status',
                    nonce: '<?php echo esc_js(wp_create_nonce('askagento_admin')); ?>'
                }, function(resp) {
                    var pingSec = ((Date.now() - timeStart) / 1000).toFixed(1);
                    if (!resp.success) {
                        var message = resp.data && resp.data.message ? resp.data.message : '<?php echo esc_js(__('Could not fetch status.', 'askagento')); ?>';
                        $out.html('<p style="color:#b32d2e;">' + escapeHtml(message) + '</p>');
                        $btn.prop('disabled', false);
                        return;
                    }

                    var data = resp.data || {};
                    var inst = data.installation || {};
                    var auto = data.autonomous || {};

                    var block = '';

                    if (inst.ok && inst.payload) {
                        var p = inst.payload;
                        var st = typeof p.status !== 'undefined' && p.status !== null ? String(p.status) : '<?php echo esc_js(__('unknown', 'askagento')); ?>';
                        var lineOk = '<div class="askagento-rec-status-line" style="margin-top:0;"><strong><?php echo esc_js(__('Installation API:', 'askagento')); ?></strong> ';
                        lineOk += '<span class="askagento-rec-status-install-ok">' + escapeHtml(st) + '</span></div>';
                        block += lineOk;
                    } else if (!inst.ok) {
                        block += '<div class="askagento-rec-status-line" style="margin-top:0;"><strong><?php echo esc_js(__('Installation API:', 'askagento')); ?></strong> ';
                        block += '<span style="color:#b32d2e;">' + escapeHtml(inst.message || '<?php echo esc_js(__('Unavailable', 'askagento')); ?>') + '</span></div>';
                    }

                    block += '<div class="askagento-rec-status-line"><strong><?php echo esc_js(__('Autonomous:', 'askagento')); ?></strong> ';
                    block += escapeHtml(auto.enabled ? '<?php echo esc_js(__('On', 'askagento')); ?>' : '<?php echo esc_js(__('Off', 'askagento')); ?>');
                    block += ' · <?php echo esc_js(__('merge mode', 'askagento')); ?>: ';
                    block += escapeHtml(auto.install_mode === 'fill_missing'
                        ? '<?php echo esc_js(__('add missing only', 'askagento')); ?>'
                        : '<?php echo esc_js(__('replace existing', 'askagento')); ?>');
                    block += '</div>';

                    var nextCronTxt = pfFormatUnixLocal(auto.cron_next_unix);
                    if (auto.enabled && nextCronTxt) {
                        block += '<div class="askagento-rec-status-line"><strong><?php echo esc_js(__('Next scheduled refresh:', 'askagento')); ?></strong> ' +
                            escapeHtml(nextCronTxt) + '</div>';
                    } else if (auto.enabled && !nextCronTxt) {
                        block += '<div class="askagento-rec-status-line"><?php echo esc_js(__('Next cron run: not scheduled yet. Save settings or revisit this page.', 'askagento')); ?></div>';
                    }

                    if (auto.last_run && auto.last_run.time) {
                        var lr = ['<?php echo esc_js(__('Last autonomous merge:', 'askagento')); ?> ' + escapeHtml(pfFormatAdminDateTime(auto.last_run.time))];
                        if (typeof auto.last_run.updated_products !== 'undefined') {
                            lr.push('<?php echo esc_js(__('updated', 'askagento')); ?> ' + auto.last_run.updated_products);
                            lr.push('<?php echo esc_js(__('links', 'askagento')); ?> ' + auto.last_run.linked_rows);
                            if (auto.last_run.skipped_products > 0) {
                                lr.push('<?php echo esc_js(__('skipped', 'askagento')); ?> ' + auto.last_run.skipped_products);
                            }
                        }
                        block += '<div class="askagento-rec-status-line">' + escapeHtml(lr.join(' | ')) + '</div>';
                    }

                    if (auto.last_error && auto.last_error.message) {
                        block += '<div class="askagento-rec-status-line"><strong><?php echo esc_js(__('Last error:', 'askagento')); ?></strong> ';
                        block += '<span style="color:#b32d2e;">' + escapeHtml(String(auto.last_error.message));
                        if (auto.last_error.time) {
                            block += ' (' + escapeHtml(pfFormatAdminDateTime(auto.last_error.time)) + ')';
                        }
                        block += '</span></div>';
                    }

                    block += '<div class="askagento-rec-status-line">Ping: ' + pingSec + ' s</div>';
                    $out.html('<div class="askagento-rec-status-out">' + block + '</div>');
                    $btn.prop('disabled', false);
                }).fail(function() {
                    $out.html('<p style="color:#b32d2e;"><?php echo esc_js(__('Request failed', 'askagento')); ?></p>');
                    $btn.prop('disabled', false);
                });
            });

        });
        </script>
    </div>
    <?php
}

/**
 * Register AI Recommend autonomous settings (saved from the AI Recommend admin form).
 */
function askagento_recommend_upsell_register_settings() {
    register_setting(
        'askagento_ai_recommend_group',
        'askagento_ai_recommend_auto',
        [
            'type' => 'boolean',
            'sanitize_callback' => static function ($value) {
                return ! empty($value) && ! in_array((string) $value, ['0', 'false', 'off'], true);
            },
            'default' => false,
        ]
    );
    register_setting(
        'askagento_ai_recommend_group',
        'askagento_ai_recommend_auto_mode',
        [
            'type' => 'string',
            'sanitize_callback' => static function ($value) {
                $v = sanitize_key((string) $value);

                return 'fill_missing' === $v ? 'fill_missing' : 'replace_all';
            },
            'default' => 'replace_all',
        ]
    );
    register_setting(
        'askagento_ai_cross_sell_group',
        'askagento_ai_cross_sell_auto',
        [
            'type' => 'boolean',
            'sanitize_callback' => static function ($value) {
                return ! empty($value) && ! in_array((string) $value, ['0', 'false', 'off'], true);
            },
            'default' => false,
        ]
    );
    register_setting(
        'askagento_ai_cross_sell_group',
        'askagento_ai_cross_sell_auto_mode',
        [
            'type' => 'string',
            'sanitize_callback' => static function ($value) {
                $v = sanitize_key((string) $value);

                return 'fill_missing' === $v ? 'fill_missing' : 'replace_all';
            },
            'default' => 'replace_all',
        ]
    );
}
