<?php
if (!defined('ABSPATH')) exit;

class AIVT_Admin {

    public static function init() {
        add_action('in_admin_header', [__CLASS__, 'suppress_foreign_notices'], 1000);
        add_action('admin_menu', [__CLASS__, 'menu']);
        add_action('admin_enqueue_scripts', [__CLASS__, 'assets']);
        add_filter('plugin_action_links_' . plugin_basename(AIVT_FILE), [__CLASS__, 'links']);

        add_action('wp_ajax_aivt_save_settings', [__CLASS__, 'ajax_save_settings']);
        add_action('wp_ajax_aivt_test_api', [__CLASS__, 'ajax_test_api']);
        add_action('wp_ajax_aivt_analyze', [__CLASS__, 'ajax_analyze']);
        add_action('wp_ajax_aivt_generate', [__CLASS__, 'ajax_generate']);
        add_action('wp_ajax_aivt_insert_content', [__CLASS__, 'ajax_insert_content']);
        add_action('wp_ajax_aivt_run_prompt', [__CLASS__, 'ajax_run_prompt']);
        add_action('wp_ajax_aivt_suggest_prompts', [__CLASS__, 'ajax_suggest_prompts']);
        add_action('wp_ajax_aivt_save_prompts', [__CLASS__, 'ajax_save_prompts']);
        add_action('wp_ajax_aivt_run_competitors', [__CLASS__, 'ajax_run_competitors']);
        add_action('wp_ajax_aivt_start_bulk', [__CLASS__, 'ajax_start_bulk']);
        add_action('wp_ajax_aivt_job_status', [__CLASS__, 'ajax_job_status']);
        add_action('wp_ajax_aivt_job_control', [__CLASS__, 'ajax_job_control']);
        add_action('wp_ajax_aivt_finish_onboarding', [__CLASS__, 'ajax_finish_onboarding']);
        add_action('wp_ajax_aivt_approve_suggestion', [__CLASS__, 'ajax_approve_suggestion']);
        add_action('wp_ajax_aivt_dismiss_suggestion', [__CLASS__, 'ajax_dismiss_suggestion']);
        add_action('wp_ajax_aivt_autopilot_preview', [__CLASS__, 'ajax_autopilot_preview']);
        add_action('wp_ajax_aivt_autopilot_apply', [__CLASS__, 'ajax_autopilot_apply']);
        add_action('wp_ajax_aivt_autopilot_revert', [__CLASS__, 'ajax_autopilot_revert']);

        add_action('admin_post_aivt_export_geo', [__CLASS__, 'export_geo_csv']);
        add_action('admin_init', [__CLASS__, 'maybe_onboarding_redirect']);
    }

    public static function links($links) {
        array_unshift($links, '<a href="' . esc_url(aivt_admin_url('dashboard')) . '">' . esc_html__('Dashboard', 'pewit-geo-analysis-tool') . '</a>');
        return $links;
    }

    public static function menu() {
        $brand = aivt_brand_name();
        add_menu_page($brand, $brand, 'manage_options', 'pewit-geo-analysis-tool', [__CLASS__, 'page_dashboard'], 'dashicons-visibility', 58);
        add_submenu_page('pewit-geo-analysis-tool', __('Dashboard', 'pewit-geo-analysis-tool'), __('Dashboard', 'pewit-geo-analysis-tool'), 'manage_options', 'pewit-geo-analysis-tool', [__CLASS__, 'page_dashboard']);
        add_submenu_page('pewit-geo-analysis-tool', __('Content', 'pewit-geo-analysis-tool'), __('Content', 'pewit-geo-analysis-tool'), 'manage_options', 'pewit-geo-analysis-tool-content', [__CLASS__, 'page_content']);
        add_submenu_page('pewit-geo-analysis-tool', __('Prompt testing', 'pewit-geo-analysis-tool'), __('Prompt testing', 'pewit-geo-analysis-tool'), 'manage_options', 'pewit-geo-analysis-tool-prompts', [__CLASS__, 'page_prompts']);
        add_submenu_page('pewit-geo-analysis-tool', __('Competitors', 'pewit-geo-analysis-tool'), __('Competitors', 'pewit-geo-analysis-tool'), 'manage_options', 'pewit-geo-analysis-tool-competitors', [__CLASS__, 'page_competitors']);
        add_submenu_page('pewit-geo-analysis-tool', __('Jobs', 'pewit-geo-analysis-tool'), __('Jobs', 'pewit-geo-analysis-tool'), 'manage_options', 'pewit-geo-analysis-tool-jobs', [__CLASS__, 'page_jobs']);
        add_submenu_page('pewit-geo-analysis-tool', __('Suggestions', 'pewit-geo-analysis-tool'), __('Suggestions', 'pewit-geo-analysis-tool'), 'manage_options', 'pewit-geo-analysis-tool-suggestions', [__CLASS__, 'page_suggestions']);
        add_submenu_page('pewit-geo-analysis-tool', __('Settings', 'pewit-geo-analysis-tool'), __('Settings', 'pewit-geo-analysis-tool'), 'manage_options', 'pewit-geo-analysis-tool-settings', [__CLASS__, 'page_settings']);
        // Hidden welcome/onboarding screen (no menu item).
        add_submenu_page(null, __('Welcome', 'pewit-geo-analysis-tool'), __('Welcome', 'pewit-geo-analysis-tool'), 'manage_options', 'pewit-geo-analysis-tool-welcome', [__CLASS__, 'page_onboarding']);
    }

    /** One-time redirect to the welcome wizard right after activation. */
    public static function maybe_onboarding_redirect() {
        if (!get_option('aivt_do_redirect')) {
            return;
        }
        delete_option('aivt_do_redirect');
        if (wp_doing_ajax() || (defined('DOING_CRON') && DOING_CRON) || is_network_admin()) {
            return;
        }
        if (!current_user_can('manage_options')) {
            return;
        }
        wp_safe_redirect(admin_url('admin.php?page=pewit-geo-analysis-tool-welcome'));
        exit;
    }

    public static function assets($hook) {
        if (strpos($hook, 'pewit-geo-analysis-tool') === false) {
            return;
        }
        self::enqueue_core();
    }

    /** Enqueue + localize the shared admin shell/scripts (used by plugin pages and the post editor). */
    public static function enqueue_core() {
        if (wp_script_is('aivt-admin', 'enqueued')) {
            return;
        }
        wp_enqueue_style('pewit-shell', AIVT_URL . 'assets/css/pewit-admin-shell.css', [], AIVT_VERSION);
        wp_enqueue_style('aivt-admin', AIVT_URL . 'assets/css/admin.css', ['pewit-shell'], AIVT_VERSION);
        wp_enqueue_script('aivt-admin', AIVT_URL . 'assets/js/admin.js', ['jquery'], AIVT_VERSION, true);
        wp_localize_script('aivt-admin', 'AIVT', [
            'ajax'        => admin_url('admin-ajax.php'),
            'nonce'       => wp_create_nonce('aivt_nonce'),
            'version'     => AIVT_VERSION,
            'plan'        => aivt_plan(),
            'canAutomate' => aivt_can_automate() ? 1 : 0,
            'apiReady'    => aivt_api_ready() ? 1 : 0,
            'upgrade_url' => aivt_upgrade_url(),
            'dashboard'   => aivt_admin_url('dashboard'),
            'i18n'        => AIVT_I18n::js_strings(),
        ]);
    }

    private static function shell_open($active = 'dashboard') {
        $plan = aivt_plan();
        $can_auto = true;
        $tabs = [
            'dashboard'   => [__('Dashboard', 'pewit-geo-analysis-tool'), aivt_admin_url('dashboard'), false],
            'content'     => [__('Content', 'pewit-geo-analysis-tool'), aivt_admin_url('content'), false],
            'prompts'     => [__('Prompt testing', 'pewit-geo-analysis-tool'), aivt_admin_url('prompts'), false],
            'competitors' => [__('Competitors', 'pewit-geo-analysis-tool'), aivt_admin_url('competitors'), !$can_auto],
            'jobs'        => [__('Jobs', 'pewit-geo-analysis-tool'), aivt_admin_url('jobs'), !$can_auto],
            'suggestions' => [__('Suggestions', 'pewit-geo-analysis-tool'), aivt_admin_url('suggestions'), false],
            'settings'    => [__('Settings', 'pewit-geo-analysis-tool'), aivt_admin_url('settings'), false],
        ];
        ?>
        <div class="wrap pewit-wrap pewit-geo-analysis-tool">
            <div class="pewit-app-body">
                <div class="pewit-app-toolbar">
                    <div class="pewit-app-brand">
                        <div class="pewit-app-icon" aria-hidden="true">
                            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linejoin="round"><path d="M2 12.5c2.2-3.6 5.4-5.5 9-5.5s6.8 1.9 9 5.5c-2.2 3.6-5.4 5.5-9 5.5s-6.8-1.9-9-5.5z"/><circle cx="11" cy="12.5" r="2.6" fill="#fff" stroke="none"/><path d="M19.5 2.5l.7 1.8 1.8.7-1.8.7-.7 1.8-.7-1.8L17 5l1.8-.7z" fill="#fff" stroke="none"/></svg>
                        </div>
                        <div>
                            <div class="pewit-app-title-row">
                                <span class="pewit-app-title"><?php echo esc_html(aivt_brand_name()); ?></span>
                                <span class="pewit-badge pewit-badge-plan pewit-plan-<?php echo esc_attr($plan); ?>">
                                    <?php echo esc_html(sprintf(/* translators: %s: plan name */ __('Plan · %s', 'pewit-geo-analysis-tool'), aivt_plan_label())); ?>
                                </span>
                                <span class="pewit-version"><?php echo esc_html(AIVT_VERSION); ?></span>
                            </div>
                            <div class="pewit-app-subtitle">pewit-labs · pewit-geo-analysis-tool</div>
                        </div>
                    </div>
                </div>

                <nav class="pewit-tabs" aria-label="<?php esc_attr_e('Admin navigation', 'pewit-geo-analysis-tool'); ?>">
                    <?php foreach ($tabs as $key => $tab): ?>
                        <a class="pewit-tab <?php echo $active === $key ? 'is-active' : ''; ?>" href="<?php echo esc_url($tab[1]); ?>">
                            <?php echo esc_html($tab[0]); ?>
                            <?php if (!empty($tab[2])): ?><span class="pewit-tab-badge">Pro</span><?php endif; ?>
                        </a>
                    <?php endforeach; ?>
                </nav>

                <div id="aivt-notice" class="aivt-notice-bar" aria-live="polite"></div>
        <?php
    }

    private static function shell_close() {
        ?>
                <p class="pewit-footer-note">
                    <?php printf(
                        /* translators: %s: PEWIT Labs link */ esc_html__('Part of the %s suite.', 'pewit-geo-analysis-tool'),
                        '<a href="https://pewitlabs.com/" target="_blank" rel="noopener">PEWIT Labs</a>'
                    ); ?>
                </p>
            </div>
        </div>
        <?php
    }

    /* ---------------- Dashboard ---------------- */

    public static function page_dashboard() {
        self::shell_open('dashboard');
        $stats = AIVT_Store::site_geo_stats();
        $api_ready = aivt_api_ready();
        $can_auto = true;
        if ($can_auto && $stats['analyzed'] > 0) {
            AIVT_Store::maybe_snapshot_site((int) $stats['avg_score']);
        }
        $snapshots = $can_auto ? AIVT_Store::site_geo_snapshots(30) : [];
        ?>
        <div class="pewit-grid pewit-grid-stats">
            <div class="pewit-card pewit-stat-card pewit-killer-card">
                <div class="pewit-stat-value"><?php echo (int) $stats['avg_score']; ?><span class="aivt-unit">/100</span></div>
                <div class="pewit-stat-label"><?php esc_html_e('Avg GEO Score', 'pewit-geo-analysis-tool'); ?></div>
                <p class="description"><?php
                    /* translators: %d: number of pages below score 70 */
                    echo esc_html(sprintf(__('%d analyzed pages below 70', 'pewit-geo-analysis-tool'), (int) $stats['below_70'])); ?></p>
            </div>
            <div class="pewit-card pewit-stat-card">
                <div class="pewit-stat-value"><?php echo esc_html(number_format_i18n($stats['analyzed'])); ?></div>
                <div class="pewit-stat-label"><?php esc_html_e('Pages analyzed', 'pewit-geo-analysis-tool'); ?></div>
            </div>
            <div class="pewit-card pewit-stat-card">
                <div class="pewit-stat-value"><?php echo esc_html(number_format_i18n(max(0, $stats['total'] - $stats['analyzed']))); ?></div>
                <div class="pewit-stat-label"><?php esc_html_e('Not analyzed yet', 'pewit-geo-analysis-tool'); ?></div>
            </div>
            <div class="pewit-card pewit-stat-card">
                <div class="pewit-stat-value"><?php echo $api_ready ? '✓' : '—'; ?></div>
                <div class="pewit-stat-label"><?php esc_html_e('API status', 'pewit-geo-analysis-tool'); ?></div>
            </div>
        </div>

        <?php if (count($snapshots) >= 2): $last_snap = end($snapshots); ?>
        <div class="pewit-card aivt-trend-card">
            <div class="aivt-trend-head">
                <h2><?php esc_html_e('Avg GEO Score trend', 'pewit-geo-analysis-tool'); ?></h2>
            </div>
            <div class="aivt-trend-chart aivt-trend-lg">
                <?php AIVT_Render::sparkline(wp_list_pluck($snapshots, 'avg'), 'aivt-ok'); ?>
                <span class="aivt-trend-now"><?php echo (int) ($last_snap['avg'] ?? 0); ?><span class="aivt-unit">/100</span></span>
            </div>
            <p class="description"><?php
                /* translators: %d: number of daily data points */
                echo esc_html(sprintf(_n('%d day of history', '%d days of history', count($snapshots), 'pewit-geo-analysis-tool'), count($snapshots))); ?></p>
        </div>
        <?php endif; ?>

        <div class="pewit-hero-card">
            <h1><?php esc_html_e('Get found by AI answer engines', 'pewit-geo-analysis-tool'); ?></h1>
            <p class="pewit-lead"><?php esc_html_e('Score, optimize and monitor how ChatGPT, Perplexity, Gemini and Google AI Overviews see your content — GEO Score, entities, E-E-A-T, citability, FAQ/Q&A, schema, prompt testing and competitor share-of-voice.', 'pewit-geo-analysis-tool'); ?></p>
            <div class="pewit-actions">
                <a class="pewit-btn pewit-btn-primary" href="<?php echo esc_url(aivt_admin_url('content')); ?>"><?php esc_html_e('Analyze content', 'pewit-geo-analysis-tool'); ?></a>
                <a class="pewit-btn pewit-btn-secondary" href="<?php echo esc_url(aivt_admin_url('prompts')); ?>"><?php esc_html_e('Test AI prompts', 'pewit-geo-analysis-tool'); ?></a>
                <a class="pewit-btn pewit-btn-secondary" href="<?php echo esc_url(aivt_admin_url('settings')); ?>"><?php esc_html_e('Settings', 'pewit-geo-analysis-tool'); ?></a>
            </div>
        </div>

        <?php if (!$api_ready): ?>
        <div class="pewit-callout pewit-callout-free">
            <strong><?php esc_html_e('Connect your AI key', 'pewit-geo-analysis-tool'); ?></strong>
            <?php esc_html_e('Bring your own OpenAI, Claude or Gemini key to start analyzing. You pay your provider directly.', 'pewit-geo-analysis-tool'); ?>
            <a class="pewit-btn pewit-btn-secondary" href="<?php echo esc_url(aivt_admin_url('settings')); ?>"><?php esc_html_e('Open settings', 'pewit-geo-analysis-tool'); ?></a>
        </div>
        <?php endif; ?>

        <?php
        self::shell_close();
    }

    /* ---------------- Content ---------------- */

    public static function page_content() {
        self::shell_open('content');
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only list paging/filter, no state change.
        $paged = max(1, absint(wp_unslash($_GET['paged'] ?? 1)));
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only list filter, no state change.
        $filter = sanitize_key(wp_unslash($_GET['filter'] ?? 'all'));
        $post_types = aivt_enabled_post_types();
        if (empty($post_types)) {
            $post_types = ['post', 'page'];
        }
        $args = [
            'post_type'      => $post_types,
            'post_status'    => 'publish',
            'posts_per_page' => 20,
            'paged'          => $paged,
            'orderby'        => 'modified',
            'order'          => 'DESC',
        ];
        if ($filter === 'missing') {
            // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Admin-only list filter, run on demand.
            $args['meta_query'] = [['key' => AIVT_Store::META_GEO, 'compare' => 'NOT EXISTS']];
        } elseif ($filter === 'analyzed') {
            // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Admin-only list filter, run on demand.
            $args['meta_query'] = [['key' => AIVT_Store::META_GEO, 'compare' => 'EXISTS']];
        }
        $query = new WP_Query($args);
        ?>
        <div class="pewit-card">
            <div class="aivt-list-toolbar">
                <h2><?php esc_html_e('GEO coverage', 'pewit-geo-analysis-tool'); ?></h2>
                <div class="aivt-filter-tabs">
                    <?php foreach (['all' => __('All', 'pewit-geo-analysis-tool'), 'analyzed' => __('Analyzed', 'pewit-geo-analysis-tool'), 'missing' => __('Not analyzed', 'pewit-geo-analysis-tool')] as $f => $label): ?>
                        <a class="pewit-btn pewit-btn-secondary <?php echo $filter === $f ? 'is-active' : ''; ?>" href="<?php echo esc_url(add_query_arg(['filter' => $f, 'paged' => false], aivt_admin_url('content'))); ?>"><?php echo esc_html($label); ?></a>
                    <?php endforeach; ?>
                </div>
            </div>
            <table class="widefat striped aivt-table">
                <thead><tr>
                    <th><?php esc_html_e('Title', 'pewit-geo-analysis-tool'); ?></th>
                    <th><?php esc_html_e('Type', 'pewit-geo-analysis-tool'); ?></th>
                    <th><?php esc_html_e('GEO Score', 'pewit-geo-analysis-tool'); ?></th>
                    <th></th>
                </tr></thead>
                <tbody>
                <?php if ($query->have_posts()): while ($query->have_posts()): $query->the_post();
                    $pid = get_the_ID();
                    $score = AIVT_Store::geo_score($pid);
                ?>
                    <tr data-post-id="<?php echo esc_attr($pid); ?>">
                        <td><a href="<?php echo esc_url(get_edit_post_link($pid)); ?>"><?php echo esc_html(get_the_title()); ?></a></td>
                        <td><?php echo esc_html(get_post_type()); ?></td>
                        <td class="aivt-score-cell">
                            <?php if ($score !== null): ?>
                                <span class="aivt-score-pill aivt-<?php echo esc_attr(AIVT_GEO_Score::score_class($score)); ?>"><?php echo esc_html($score); ?></span>
                            <?php else: ?>
                                <span class="aivt-score-pill aivt-none">—</span>
                            <?php endif; ?>
                        </td>
                        <td>
                            <button type="button" class="button button-small aivt-row-analyze" data-post-id="<?php echo esc_attr($pid); ?>"><?php esc_html_e('Analyze GEO', 'pewit-geo-analysis-tool'); ?></button>
                            <a class="button button-small" href="<?php echo esc_url(get_edit_post_link($pid)); ?>"><?php esc_html_e('Full analysis', 'pewit-geo-analysis-tool'); ?></a>
                        </td>
                    </tr>
                <?php endwhile; wp_reset_postdata(); else: ?>
                    <tr><td colspan="4"><?php esc_html_e('No posts found.', 'pewit-geo-analysis-tool'); ?></td></tr>
                <?php endif; ?>
                </tbody>
            </table>
            <?php if ($query->max_num_pages > 1): ?>
                <div class="tablenav bottom"><div class="tablenav-pages">
                    <?php echo wp_kses_post(paginate_links([
                        'base'    => add_query_arg('paged', '%#%', aivt_admin_url('content')),
                        'format'  => '',
                        'current' => $paged,
                        'total'   => $query->max_num_pages,
                    ])); ?>
                </div></div>
            <?php endif; ?>
        </div>
        <p class="description"><?php esc_html_e('Open “Full analysis” to run entities, E-E-A-T, citability, FAQ, Q&A and schema for a page in the editor.', 'pewit-geo-analysis-tool'); ?></p>
        <?php
        self::shell_close();
    }

    /* ---------------- Prompt testing ---------------- */

    public static function page_prompts() {
        self::shell_open('prompts');
        $s = aivt_get_settings();
        $monitored = AIVT_Prompt_Test::get_monitored_prompts();
        $history = AIVT_Store::prompt_history(20);
        $can_auto = true;
        $trend = $can_auto ? AIVT_Store::prompt_trend(30) : [];
        ?>
        <div class="pewit-card">
            <h2><?php esc_html_e('Does AI recommend your brand?', 'pewit-geo-analysis-tool'); ?></h2>
            <p class="description"><?php
                /* translators: %s: brand / business name */
                echo esc_html(sprintf(__('Ask a real customer-style question and we check whether “%s” appears in the answer. This queries your configured AI model.', 'pewit-geo-analysis-tool'), aivt_site_brand())); ?></p>
            <textarea id="aivt-prompt-input" rows="2" class="large-text" placeholder="<?php esc_attr_e('e.g. Recommend a car detailing company in Poznań', 'pewit-geo-analysis-tool'); ?>"></textarea>
            <div class="pewit-actions">
                <button type="button" class="pewit-btn pewit-btn-primary" id="aivt-run-prompt" <?php disabled(!aivt_api_ready()); ?>><?php esc_html_e('Test prompt', 'pewit-geo-analysis-tool'); ?></button>
                <button type="button" class="pewit-btn pewit-btn-secondary" id="aivt-suggest-prompts"><?php esc_html_e('Suggest prompts', 'pewit-geo-analysis-tool'); ?></button>
            </div>
            <div id="aivt-prompt-suggestions" class="aivt-suggestions"></div>
            <div id="aivt-prompt-result"></div>
        </div>

        <div class="pewit-card">
            <h2>
                <?php esc_html_e('Monitored prompts', 'pewit-geo-analysis-tool'); ?>
            </h2>
            <p class="description"><?php esc_html_e('Save prompts to track over time. Run them on a schedule and keep history so you can watch your AI visibility trend.', 'pewit-geo-analysis-tool'); ?></p>
            <textarea id="aivt-monitored" rows="5" class="large-text" placeholder="<?php esc_attr_e('One prompt per line', 'pewit-geo-analysis-tool'); ?>"><?php echo esc_textarea(implode("\n", $monitored)); ?></textarea>
            <div class="pewit-actions">
                <button type="button" class="pewit-btn pewit-btn-secondary" id="aivt-save-prompts"><?php esc_html_e('Save prompts', 'pewit-geo-analysis-tool'); ?></button>
            </div>
        </div>

        <?php if (count($trend) >= 2): $last_t = end($trend); ?>
        <div class="pewit-card aivt-trend-card">
            <div class="aivt-trend-head">
                <h2><?php esc_html_e('Brand presence trend', 'pewit-geo-analysis-tool'); ?></h2>
            </div>
            <div class="aivt-trend-chart aivt-trend-lg">
                <?php AIVT_Render::sparkline(wp_list_pluck($trend, 'pct'), 'aivt-ok'); ?>
                <span class="aivt-trend-now"><?php echo (int) ($last_t['pct'] ?? 0); ?>%</span>
            </div>
            <p class="description"><?php esc_html_e('Share of monitored prompts where your brand appeared in the AI answer, by day.', 'pewit-geo-analysis-tool'); ?></p>
        </div>
        <?php endif; ?>

        <?php if (!empty($history)): ?>
        <div class="pewit-card">
            <h2><?php esc_html_e('Recent runs', 'pewit-geo-analysis-tool'); ?></h2>
            <table class="widefat striped aivt-table">
                <thead><tr>
                    <th><?php esc_html_e('When', 'pewit-geo-analysis-tool'); ?></th>
                    <th><?php esc_html_e('Prompt', 'pewit-geo-analysis-tool'); ?></th>
                    <th><?php esc_html_e('Brand', 'pewit-geo-analysis-tool'); ?></th>
                    <th><?php esc_html_e('Competitors', 'pewit-geo-analysis-tool'); ?></th>
                </tr></thead>
                <tbody>
                <?php foreach ($history as $h): ?>
                    <tr>
                        <td><?php echo esc_html(human_time_diff((int) $h['ts']) . ' ' . __('ago', 'pewit-geo-analysis-tool')); ?></td>
                        <td><?php echo esc_html($h['prompt']); ?></td>
                        <td><?php echo !empty($h['mentioned']) ? '<span class="aivt-score-pill aivt-ok">✓</span>' : '<span class="aivt-score-pill aivt-bad">✗</span>'; ?></td>
                        <td><?php echo esc_html(!empty($h['competitors_found']) ? implode(', ', $h['competitors_found']) : '—'); ?></td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
        </div>
        <?php endif; ?>
        <?php
        self::shell_close();
    }

    /* ---------------- Competitors ---------------- */

    public static function page_competitors() {
        self::shell_open('competitors');
        $report = AIVT_Store::competitor_report();
        $competitors = aivt_competitors_list();
        ?>
        <div class="pewit-card">
            <h2><?php esc_html_e('AI share-of-voice', 'pewit-geo-analysis-tool'); ?></h2>
            <?php if (empty($competitors)): ?>
                <p class="description"><?php esc_html_e('Add competitors in Settings to compare AI visibility.', 'pewit-geo-analysis-tool'); ?> <a href="<?php echo esc_url(aivt_admin_url('settings')); ?>"><?php esc_html_e('Open settings', 'pewit-geo-analysis-tool'); ?></a></p>
            <?php else: ?>
                <p class="description"><?php echo esc_html(implode(' · ', $competitors)); ?></p>
                <div class="pewit-actions">
                    <button type="button" class="pewit-btn pewit-btn-primary" id="aivt-run-competitors" <?php disabled(!aivt_api_ready()); ?>><?php esc_html_e('Run competitor analysis', 'pewit-geo-analysis-tool'); ?></button>
                </div>
            <?php endif; ?>
            <div id="aivt-competitor-report"><?php if ($report) self::render_competitor_report($report); ?></div>
        </div>
        <?php
        self::shell_close();
    }

    public static function render_competitor_report($report) {
        if (empty($report['share'])) {
            return;
        }
        $max = max(1, max($report['share']));
        ?>
        <div class="aivt-result">
            <p class="description"><?php
                /* translators: %d: number of prompts tested */
                echo esc_html(sprintf(__('Based on %d prompts.', 'pewit-geo-analysis-tool'), (int) $report['total_runs'])); ?></p>
            <div class="aivt-bars">
                <?php foreach ($report['share'] as $name => $pct):
                    $is_brand = ($name === ($report['brand'] ?? '')); ?>
                    <div class="aivt-bar-row">
                        <span class="aivt-bar-label<?php echo $is_brand ? ' aivt-bar-brand' : ''; ?>"><?php echo esc_html($name); ?></span>
                        <span class="aivt-bar-track"><span class="aivt-bar-fill <?php echo $is_brand ? 'aivt-ok' : 'aivt-neutral'; ?>" style="width:<?php echo esc_attr((int) round(($pct / $max) * 100)); ?>%"></span></span>
                        <span class="aivt-bar-num"><?php echo esc_html((int) $pct); ?>%</span>
                    </div>
                <?php endforeach; ?>
            </div>
            <?php if (!empty($report['gap']['actions'])): ?>
                <h4><?php esc_html_e('How to get recommended more', 'pewit-geo-analysis-tool'); ?></h4>
                <ul class="aivt-tips"><?php foreach ($report['gap']['actions'] as $a): ?><li><?php echo esc_html($a); ?></li><?php endforeach; ?></ul>
            <?php endif; ?>
            <?php if (!empty($report['gap']['gaps'])): ?>
                <h4><?php esc_html_e('Biggest gaps', 'pewit-geo-analysis-tool'); ?></h4>
                <ul class="aivt-tips"><?php foreach ($report['gap']['gaps'] as $g): ?><li><?php echo esc_html($g); ?></li><?php endforeach; ?></ul>
            <?php endif; ?>
        </div>
        <?php
    }

    /* ---------------- Jobs ---------------- */

    public static function page_jobs() {
        self::shell_open('jobs');
        $job = AIVT_Queue::get_job();
        $missing = AIVT_Store::count_unanalyzed();
        $export_url = wp_nonce_url(admin_url('admin-post.php?action=aivt_export_geo'), 'aivt_export_geo');
        ?>
        <div class="pewit-card">
            <h2><?php esc_html_e('Bulk jobs', 'pewit-geo-analysis-tool'); ?></h2>
            <p class="description"><?php esc_html_e('Process every published page that is missing the selected output. Runs in small batches via WP-Cron.', 'pewit-geo-analysis-tool'); ?></p>
            <label for="aivt-job-type"><?php esc_html_e('Job type', 'pewit-geo-analysis-tool'); ?></label>
            <select id="aivt-job-type">
                <option value="geo"><?php esc_html_e('GEO Score — analyze pages', 'pewit-geo-analysis-tool'); ?></option>
                <option value="faq"><?php esc_html_e('FAQ — generate &amp; store', 'pewit-geo-analysis-tool'); ?></option>
                <option value="qa"><?php esc_html_e('Q&amp;A — generate &amp; store', 'pewit-geo-analysis-tool'); ?></option>
                <option value="schema"><?php esc_html_e('Schema — generate &amp; store', 'pewit-geo-analysis-tool'); ?></option>
            </select>
            <p><strong><?php echo esc_html(number_format_i18n($missing)); ?></strong> <?php esc_html_e('pages without a GEO Score.', 'pewit-geo-analysis-tool'); ?></p>
            <div class="pewit-actions">
                <button type="button" class="pewit-btn pewit-btn-primary" id="aivt-start-bulk" <?php disabled(!aivt_api_ready()); ?>><?php esc_html_e('Start bulk job', 'pewit-geo-analysis-tool'); ?></button>
            </div>
            <p class="description"><?php esc_html_e('FAQ/Q&A/Schema jobs generate and store output for each page. Review and insert FAQ/Q&A per page in the editor; schema is output automatically.', 'pewit-geo-analysis-tool'); ?></p>
            <?php if (!aivt_api_ready()): ?>
                <p class="aivt-notice aivt-notice-warn"><?php esc_html_e('Connect your API key in Settings first.', 'pewit-geo-analysis-tool'); ?></p>
            <?php endif; ?>
        </div>
        <div class="pewit-card" id="aivt-job-panel"><?php self::render_job_panel($job); ?></div>
        <div class="pewit-card">
            <h2><?php esc_html_e('Site GEO report', 'pewit-geo-analysis-tool'); ?></h2>
            <p class="description"><?php esc_html_e('Export GEO coverage for every published page (score, label, top improvement) as CSV — ready for clients or audits.', 'pewit-geo-analysis-tool'); ?></p>
            <div class="pewit-actions">
                <a class="pewit-btn pewit-btn-secondary" href="<?php echo esc_url($export_url); ?>"><?php esc_html_e('Download CSV report', 'pewit-geo-analysis-tool'); ?></a>
            </div>
        </div>
        <?php
        self::shell_close();
    }

    public static function render_job_panel($job) {
        if (!$job) {
            echo '<p class="description">' . esc_html__('No active job.', 'pewit-geo-analysis-tool') . '</p>';
            return;
        }
        $done = (int) ($job['done'] ?? 0);
        $total = (int) ($job['total'] ?? 0);
        $pct = $total ? min(100, round(($done / $total) * 100)) : 0;
        ?>
        <h3><?php esc_html_e('Current job', 'pewit-geo-analysis-tool'); ?></h3>
        <p><strong><?php esc_html_e('Status:', 'pewit-geo-analysis-tool'); ?></strong> <?php echo esc_html(ucfirst($job['status'] ?? '')); ?>
            · <?php echo esc_html($done . ' / ' . $total); ?></p>
        <div class="aivt-progress"><div class="aivt-progress-bar" style="width:<?php echo esc_attr($pct); ?>%"></div></div>
        <?php if (in_array($job['status'] ?? '', ['running', 'paused'], true)): ?>
        <div class="pewit-actions">
            <button type="button" class="pewit-btn pewit-btn-secondary aivt-job-control" data-action="<?php echo ($job['status'] === 'paused') ? 'resume' : 'pause'; ?>"><?php echo $job['status'] === 'paused' ? esc_html__('Resume', 'pewit-geo-analysis-tool') : esc_html__('Pause', 'pewit-geo-analysis-tool'); ?></button>
            <button type="button" class="pewit-btn pewit-btn-secondary aivt-job-control" data-action="stop"><?php esc_html_e('Stop', 'pewit-geo-analysis-tool'); ?></button>
        </div>
        <?php endif; ?>
        <?php if (!empty($job['log'])): ?>
            <details class="aivt-job-log"><summary><?php esc_html_e('Activity log', 'pewit-geo-analysis-tool'); ?></summary><ul>
                <?php foreach (array_reverse(array_slice($job['log'], -20)) as $entry): ?>
                    <li class="aivt-log-<?php echo esc_attr($entry['level'] ?? 'info'); ?>">[<?php echo esc_html($entry['time'] ?? ''); ?>] <?php echo esc_html($entry['message'] ?? ''); ?></li>
                <?php endforeach; ?>
            </ul></details>
        <?php endif; ?>
        <?php
    }

    private static function locked_card() {
        ?>
        <div class="pewit-callout pewit-callout-locked">
            <strong><?php esc_html_e('Pro feature', 'pewit-geo-analysis-tool'); ?></strong>
            <?php echo esc_html(aivt_automation_upgrade_message()); ?>
            <a class="pewit-btn pewit-btn-primary" href="<?php echo esc_url(aivt_upgrade_url()); ?>"><?php esc_html_e('Upgrade to Pro', 'pewit-geo-analysis-tool'); ?></a>
        </div>
        <?php
    }

    /* ---------------- Suggestions (approval queue) ---------------- */

    public static function page_suggestions() {
        self::shell_open('suggestions');
        $items = AIVT_Store::get_approvals(100);
        ?>
        <div class="pewit-card">
            <h2><?php esc_html_e('Suggestions awaiting review', 'pewit-geo-analysis-tool'); ?></h2>
            <p class="description"><?php esc_html_e('FAQ and Q&A generated by bulk jobs land here for review. Approve to append the blocks to the page (a revision is saved), or dismiss.', 'pewit-geo-analysis-tool'); ?></p>
            <?php if (empty($items)): ?>
                <p class="aivt-empty"><?php esc_html_e('Nothing to review. Run a bulk FAQ or Q&A job to generate suggestions.', 'pewit-geo-analysis-tool'); ?>
                    <a href="<?php echo esc_url(aivt_admin_url('jobs')); ?>"><?php esc_html_e('Go to Jobs', 'pewit-geo-analysis-tool'); ?></a></p>
            <?php else: ?>
                <div id="aivt-approvals">
                <?php foreach ($items as $item):
                    $pid = (int) $item['post_id'];
                    $kind_label = $item['kind'] === 'qa' ? __('Q&A', 'pewit-geo-analysis-tool') : __('FAQ', 'pewit-geo-analysis-tool'); ?>
                    <div class="aivt-approval" data-id="<?php echo esc_attr($item['id']); ?>">
                        <div class="aivt-approval-head">
                            <div>
                                <strong><?php echo esc_html(get_the_title($pid) ?: ('#' . $pid)); ?></strong>
                                <span class="pewit-tab-badge"><?php echo esc_html($kind_label); ?></span>
                                <span class="description"><?php
                                    /* translators: %d: number of generated items */
                                    echo esc_html(sprintf(_n('%d item', '%d items', (int) $item['count'], 'pewit-geo-analysis-tool'), (int) $item['count'])); ?></span>
                            </div>
                            <div class="pewit-actions">
                                <a class="button button-small" href="<?php echo esc_url(get_edit_post_link($pid)); ?>" target="_blank" rel="noopener"><?php esc_html_e('Open editor', 'pewit-geo-analysis-tool'); ?></a>
                                <button type="button" class="button button-small aivt-approval-dismiss"><?php esc_html_e('Dismiss', 'pewit-geo-analysis-tool'); ?></button>
                                <button type="button" class="button button-primary button-small aivt-approval-approve"><?php esc_html_e('Approve & insert', 'pewit-geo-analysis-tool'); ?></button>
                            </div>
                        </div>
                    </div>
                <?php endforeach; ?>
                </div>
            <?php endif; ?>
        </div>
        <?php
        self::shell_close();
    }

    public static function ajax_approve_suggestion() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $id = sanitize_text_field(wp_unslash($_POST['id'] ?? ''));
        $item = AIVT_Store::get_approval($id);
        if (!$item) {
            wp_send_json_error(['message' => __('Suggestion not found.', 'pewit-geo-analysis-tool')]);
        }
        $post_id = (int) $item['post_id'];
        if (!current_user_can('edit_post', $post_id)) {
            wp_send_json_error(['message' => __('Permission denied for this post.', 'pewit-geo-analysis-tool')]);
        }
        $post = get_post($post_id);
        if (!$post) {
            AIVT_Store::remove_approval($id);
            wp_send_json_error(['message' => __('The target post no longer exists.', 'pewit-geo-analysis-tool')]);
        }
        $blocks = wp_kses_post($item['blocks']);
        $updated = trim($post->post_content) . "\n\n" . $blocks;
        wp_update_post(['ID' => $post_id, 'post_content' => $updated]);
        AIVT_Store::remove_approval($id);
        wp_send_json_success(['message' => __('Inserted into the post.', 'pewit-geo-analysis-tool')]);
    }

    public static function ajax_dismiss_suggestion() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $id = sanitize_text_field(wp_unslash($_POST['id'] ?? ''));
        AIVT_Store::remove_approval($id);
        wp_send_json_success(['message' => __('Dismissed.', 'pewit-geo-analysis-tool')]);
    }

    /* ---------------- Settings ---------------- */

    public static function page_settings() {
        self::shell_open('settings');
        $s = aivt_get_settings();
        $has_key = !empty($s['api_key']);
        $public_types = get_post_types(['public' => true], 'objects');
        ?>
        <div class="pewit-card aivt-settings-card">
            <h2><?php esc_html_e('Brand & business', 'pewit-geo-analysis-tool'); ?></h2>
            <label for="aivt_brand_name"><?php esc_html_e('Brand / business name', 'pewit-geo-analysis-tool'); ?></label>
            <input type="text" id="aivt_brand_name" class="regular-text" value="<?php echo esc_attr($s['brand_name']); ?>" />
            <label for="aivt_brand_aliases"><?php esc_html_e('Brand aliases (one per line)', 'pewit-geo-analysis-tool'); ?></label>
            <textarea id="aivt_brand_aliases" rows="2" class="large-text"><?php echo esc_textarea($s['brand_aliases']); ?></textarea>
            <label for="aivt_business_type"><?php esc_html_e('Business type', 'pewit-geo-analysis-tool'); ?></label>
            <input type="text" id="aivt_business_type" class="regular-text" placeholder="<?php esc_attr_e('e.g. car detailing studio', 'pewit-geo-analysis-tool'); ?>" value="<?php echo esc_attr($s['business_type']); ?>" />
            <label for="aivt_location"><?php esc_html_e('Location / market', 'pewit-geo-analysis-tool'); ?></label>
            <input type="text" id="aivt_location" class="regular-text" placeholder="<?php esc_attr_e('e.g. Poznań, Poland', 'pewit-geo-analysis-tool'); ?>" value="<?php echo esc_attr($s['location']); ?>" />
            <label for="aivt_target_keywords"><?php esc_html_e('Target topics / keywords', 'pewit-geo-analysis-tool'); ?></label>
            <input type="text" id="aivt_target_keywords" class="large-text" value="<?php echo esc_attr($s['target_keywords']); ?>" />
            <label for="aivt_competitors"><?php esc_html_e('Competitors (one per line)', 'pewit-geo-analysis-tool'); ?></label>
            <textarea id="aivt_competitors" rows="3" class="large-text"><?php echo esc_textarea($s['competitors']); ?></textarea>
            <p class="description"><?php esc_html_e('Track up to 10 competitors.', 'pewit-geo-analysis-tool'); ?></p>
        </div>

        <div class="pewit-card aivt-settings-card">
            <h2><?php esc_html_e('AI provider', 'pewit-geo-analysis-tool'); ?></h2>
            <?php
            if (class_exists('Pewit_Labs_Hub')) {
                Pewit_Labs_Hub::render_settings_notice('pewit-geo-analysis-tool');
            }
            $hub_mode = class_exists('Pewit_Labs_Hub') && Pewit_Labs_Hub::should_show_hub();
            if ($hub_mode) :
                ?>
            <p class="description"><?php esc_html_e('Provider, API key, model and global context are managed under PEWIT Labs shared settings. Options below stay local to this plugin.', 'pewit-geo-analysis-tool'); ?></p>
            <?php else : ?>
            <?php aivt_render_provider_select($s, [
                'id'          => 'aivt_provider',
                'pro_allowed' => aivt_is_pro() || aivt_is_trial(),
                'description' => __('OpenAI, Claude, or Gemini — use your own API key (BYOK).', 'pewit-geo-analysis-tool'),
            ]); ?>
            <label><?php esc_html_e('API key', 'pewit-geo-analysis-tool'); ?></label>
            <div class="aivt-api-key-field">
                <div id="aivt-api-key-saved" <?php echo $has_key ? '' : 'style="display:none"'; ?>>
                    <code id="aivt_api_key_mask"><?php echo esc_html(aivt_api_key_masked_label($s['api_key'])); ?></code>
                    <button type="button" class="button button-small" id="aivt-api-key-change"><?php esc_html_e('Change key', 'pewit-geo-analysis-tool'); ?></button>
                </div>
                <div id="aivt-api-key-edit" class="aivt-inline" <?php echo $has_key ? 'style="display:none"' : ''; ?>>
                    <input type="password" id="aivt_api_key" class="regular-text" placeholder="sk-..." autocomplete="new-password" />
                    <?php if ($has_key): ?><button type="button" class="button button-small" id="aivt-api-key-cancel"><?php esc_html_e('Cancel', 'pewit-geo-analysis-tool'); ?></button><?php endif; ?>
                </div>
                <button type="button" class="button" id="aivt-test-api"><?php esc_html_e('Save & Test', 'pewit-geo-analysis-tool'); ?></button>
            </div>
            <p id="aivt-api-status" class="aivt-status <?php echo !empty($s['api_key_verified']) ? 'ok' : ''; ?>">
                <?php
                if (!empty($s['api_key_verified'])) {
                    esc_html_e('API connected', 'pewit-geo-analysis-tool');
                } elseif ($has_key) {
                    esc_html_e('Key saved — click Save & Test to verify', 'pewit-geo-analysis-tool');
                } else {
                    esc_html_e('Not configured', 'pewit-geo-analysis-tool');
                }
                ?>
            </p>
            <label for="aivt_model"><?php esc_html_e('Model', 'pewit-geo-analysis-tool'); ?></label>
            <input type="text" id="aivt_model" class="regular-text" value="<?php echo esc_attr($s['model']); ?>" />
            <label for="aivt_global_context"><?php esc_html_e('Global context', 'pewit-geo-analysis-tool'); ?></label>
            <textarea id="aivt_global_context" rows="3" class="large-text"><?php echo esc_textarea($s['global_context']); ?></textarea>
            <?php endif; ?>
        </div>

        <div class="pewit-card aivt-settings-card">
            <h2><?php esc_html_e('Content scope', 'pewit-geo-analysis-tool'); ?></h2>
            <p class="description"><?php esc_html_e('Which post types are included in coverage stats and bulk jobs.', 'pewit-geo-analysis-tool'); ?></p>
            <?php foreach ($public_types as $name => $obj): if ($name === 'attachment') continue; ?>
                <label class="aivt-inline-check">
                    <input type="checkbox" class="aivt-cpt-enabled" value="<?php echo esc_attr($name); ?>" <?php checked(in_array($name, (array) $s['enabled_post_types'], true)); ?> />
                    <?php echo esc_html($obj->labels->name); ?> <code><?php echo esc_html($name); ?></code>
                </label>
            <?php endforeach; ?>
        </div>

        <div class="pewit-card aivt-settings-card">
            <h2><?php esc_html_e('Automation', 'pewit-geo-analysis-tool'); ?></h2>
            <label class="aivt-inline-check"><input type="checkbox" id="aivt_auto_analyze" value="1" <?php checked(!empty($s['auto_analyze'])); ?> /> <?php esc_html_e('Auto-analyze GEO Score on publish/update', 'pewit-geo-analysis-tool'); ?></label>
            <div class="aivt-inline-fields">
                <label for="aivt_batch_size"><?php esc_html_e('Batch size', 'pewit-geo-analysis-tool'); ?></label>
                <input type="number" id="aivt_batch_size" min="1" max="10" value="<?php echo esc_attr((int) $s['batch_size']); ?>" />
                <label for="aivt_batch_delay"><?php esc_html_e('Delay (s)', 'pewit-geo-analysis-tool'); ?></label>
                <input type="number" id="aivt_batch_delay" min="2" max="60" value="<?php echo esc_attr((int) $s['batch_delay']); ?>" />
            </div>
            <label for="aivt_prompt_schedule"><?php esc_html_e('Prompt monitoring schedule', 'pewit-geo-analysis-tool'); ?></label>
            <select id="aivt_prompt_schedule">
                <option value="off" <?php selected($s['prompt_schedule'], 'off'); ?>><?php esc_html_e('Off', 'pewit-geo-analysis-tool'); ?></option>
                <option value="weekly" <?php selected($s['prompt_schedule'], 'weekly'); ?>><?php esc_html_e('Weekly', 'pewit-geo-analysis-tool'); ?></option>
                <option value="monthly" <?php selected($s['prompt_schedule'], 'monthly'); ?>><?php esc_html_e('Monthly', 'pewit-geo-analysis-tool'); ?></option>
            </select>
            <label class="aivt-inline-check"><input type="checkbox" id="aivt_notify_email_enabled" value="1" <?php checked(!empty($s['notify_email_enabled'])); ?> /> <?php esc_html_e('Email me when bulk jobs finish', 'pewit-geo-analysis-tool'); ?></label>
            <label for="aivt_notify_email_to"><?php esc_html_e('Recipient', 'pewit-geo-analysis-tool'); ?></label>
            <input type="email" id="aivt_notify_email_to" class="regular-text" value="<?php echo esc_attr($s['notify_email_to']); ?>" />
        </div>

        <div class="pewit-card aivt-settings-card">
            <h2><?php esc_html_e('White-label', 'pewit-geo-analysis-tool'); ?></h2>
            <label class="aivt-inline-check"><input type="checkbox" id="aivt_whitelabel_enabled" value="1" <?php checked(!empty($s['whitelabel_enabled'])); ?> /> <?php esc_html_e('Enable white-label branding', 'pewit-geo-analysis-tool'); ?></label>
            <label for="aivt_whitelabel_brand"><?php esc_html_e('Brand name shown in admin', 'pewit-geo-analysis-tool'); ?></label>
            <input type="text" id="aivt_whitelabel_brand" class="regular-text" value="<?php echo esc_attr($s['whitelabel_brand']); ?>" />
        </div>

        <div class="pewit-actions">
            <button type="button" class="pewit-btn pewit-btn-primary" id="aivt-save-settings"><?php esc_html_e('Save settings', 'pewit-geo-analysis-tool'); ?></button>
        </div>
        <?php
        self::shell_close();
    }

    /* ---------------- Onboarding ---------------- */

    public static function page_onboarding() {
        $s = aivt_get_settings();
        ?>
        <div class="wrap pewit-wrap pewit-geo-analysis-tool">
            <div class="pewit-app-body">
                <div id="aivt-notice" class="aivt-notice-bar" aria-live="polite"></div>
                <div class="pewit-hero-card aivt-onboarding" id="aivt-onboarding">
                    <h1><?php esc_html_e('Welcome to GEO Analysis Tool', 'pewit-geo-analysis-tool'); ?></h1>
                    <p class="pewit-lead"><?php esc_html_e('Three quick steps and you can score any page for AI answer engines. Everything here works on Free with your own API key.', 'pewit-geo-analysis-tool'); ?></p>

                    <div class="aivt-step">
                        <h2><span class="aivt-step-num">1</span> <?php esc_html_e('Connect your AI provider', 'pewit-geo-analysis-tool'); ?></h2>
                        <?php aivt_render_provider_select($s, [
                            'id'          => 'aivt_provider',
                            'pro_allowed' => aivt_is_pro() || aivt_is_trial(),
                            'description' => __('OpenAI, Claude or Gemini — you bring your own key (BYOK).', 'pewit-geo-analysis-tool'),
                        ]); ?>
                        <label for="aivt_api_key"><?php esc_html_e('API key', 'pewit-geo-analysis-tool'); ?></label>
                        <input type="password" id="aivt_api_key" class="regular-text" placeholder="sk-..." autocomplete="new-password" value="" />
                        <label for="aivt_model"><?php esc_html_e('Model', 'pewit-geo-analysis-tool'); ?></label>
                        <input type="text" id="aivt_model" class="regular-text" value="<?php echo esc_attr($s['model']); ?>" />
                    </div>

                    <div class="aivt-step">
                        <h2><span class="aivt-step-num">2</span> <?php esc_html_e('Tell us about your brand', 'pewit-geo-analysis-tool'); ?></h2>
                        <label for="aivt_brand_name"><?php esc_html_e('Brand / business name', 'pewit-geo-analysis-tool'); ?></label>
                        <input type="text" id="aivt_brand_name" class="regular-text" value="<?php echo esc_attr($s['brand_name']); ?>" />
                        <label for="aivt_business_type"><?php esc_html_e('Business type', 'pewit-geo-analysis-tool'); ?></label>
                        <input type="text" id="aivt_business_type" class="regular-text" placeholder="<?php esc_attr_e('e.g. car detailing studio', 'pewit-geo-analysis-tool'); ?>" value="<?php echo esc_attr($s['business_type']); ?>" />
                        <label for="aivt_location"><?php esc_html_e('Location / market', 'pewit-geo-analysis-tool'); ?></label>
                        <input type="text" id="aivt_location" class="regular-text" placeholder="<?php esc_attr_e('e.g. Poznań, Poland', 'pewit-geo-analysis-tool'); ?>" value="<?php echo esc_attr($s['location']); ?>" />
                    </div>

                    <div class="aivt-step">
                        <h2><span class="aivt-step-num">3</span> <?php esc_html_e('Start optimizing', 'pewit-geo-analysis-tool'); ?></h2>
                        <p class="description"><?php esc_html_e('Save your setup, then analyze your first page from the Content screen.', 'pewit-geo-analysis-tool'); ?></p>
                        <div class="pewit-actions">
                            <button type="button" class="pewit-btn pewit-btn-primary" id="aivt-onboarding-finish"><?php esc_html_e('Save & finish setup', 'pewit-geo-analysis-tool'); ?></button>
                            <a class="pewit-btn pewit-btn-secondary" href="<?php echo esc_url(aivt_admin_url('dashboard')); ?>" id="aivt-onboarding-skip"><?php esc_html_e('Skip for now', 'pewit-geo-analysis-tool'); ?></a>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <?php
    }

    /* ---------------- CSV report ---------------- */

    private static function csv_cell($value) {
        $value = (string) $value;
        // Neutralize CSV/formula injection.
        if ($value !== '' && in_array($value[0], ['=', '+', '-', '@', "\t", "\r"], true)) {
            $value = "'" . $value;
        }
        return $value;
    }

    public static function export_geo_csv() {
        if (!current_user_can('manage_options')) {
            wp_die(esc_html__('Permission denied', 'pewit-geo-analysis-tool'), 403);
        }
        check_admin_referer('aivt_export_geo');
        $rows = AIVT_Store::geo_report_rows();
        $filename = 'ai-visibility-geo-' . gmdate('Ymd-His') . '.csv';

        nocache_headers();
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename=' . $filename);

        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- Streaming a CSV download to php://output; WP_Filesystem cannot stream HTTP responses.
        $out = fopen('php://output', 'w');
        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite -- Writing UTF-8 BOM to the output stream for spreadsheet apps.
        fwrite($out, "\xEF\xBB\xBF");
        fputcsv($out, ['ID', 'Title', 'Type', 'URL', 'GEO Score', 'Label', 'Analyzed', 'Top tip']);
        foreach ($rows as $r) {
            fputcsv($out, [
                self::csv_cell($r['id']),
                self::csv_cell($r['title']),
                self::csv_cell($r['type']),
                self::csv_cell($r['url']),
                self::csv_cell($r['score'] === null ? '' : $r['score']),
                self::csv_cell($r['label']),
                self::csv_cell($r['analyzed']),
                self::csv_cell($r['top_tip']),
            ]);
        }
        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Closing the php://output stream handle.
        fclose($out);
        exit;
    }

    /* ---------------- AJAX ---------------- */

    private static function require_cap($cap = 'edit_posts') {
        if (!current_user_can($cap)) {
            wp_send_json_error(['message' => __('Permission denied', 'pewit-geo-analysis-tool')], 403);
        }
    }

    public static function ajax_save_settings() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $s = aivt_get_settings();
        if (isset($_POST['api_key']) && $_POST['api_key'] !== '') {
            $s['api_key'] = sanitize_text_field(wp_unslash($_POST['api_key']));
        }
        if (isset($_POST['model'])) {
            $s['model'] = sanitize_text_field(wp_unslash($_POST['model']));
        }
        if (isset($_POST['brand_name'])) {
            $s['brand_name'] = sanitize_text_field(wp_unslash($_POST['brand_name']));
        }
        if (isset($_POST['business_type'])) {
            $s['business_type'] = sanitize_text_field(wp_unslash($_POST['business_type']));
        }
        if (isset($_POST['location'])) {
            $s['location'] = sanitize_text_field(wp_unslash($_POST['location']));
        }
        if (isset($_POST['target_keywords'])) {
            $s['target_keywords'] = sanitize_text_field(wp_unslash($_POST['target_keywords']));
        }
        if (isset($_POST['whitelabel_brand'])) {
            $s['whitelabel_brand'] = sanitize_text_field(wp_unslash($_POST['whitelabel_brand']));
        }
        if (isset($_POST['brand_aliases'])) {
            $s['brand_aliases'] = sanitize_textarea_field(wp_unslash($_POST['brand_aliases']));
        }
        if (isset($_POST['competitors'])) {
            $s['competitors'] = sanitize_textarea_field(wp_unslash($_POST['competitors']));
        }
        if (isset($_POST['global_context'])) {
            $s['global_context'] = sanitize_textarea_field(wp_unslash($_POST['global_context']));
        }
        if (isset($_POST['provider'])) {
            $s['provider'] = AIVT_LLM_API::sanitize_provider_setting(sanitize_key(wp_unslash($_POST['provider'])), aivt_is_pro() || aivt_is_trial());
        }
        if (isset($_POST['enabled_post_types']) && is_array($_POST['enabled_post_types'])) {
            $s['enabled_post_types'] = array_values(array_unique(array_map('sanitize_key', wp_unslash($_POST['enabled_post_types']))));
        }
        if (isset($_POST['notify_email_to'])) {
            $s['notify_email_to'] = sanitize_email(wp_unslash($_POST['notify_email_to']));
        }
            $s['auto_analyze'] = !empty($_POST['auto_analyze']) ? 1 : 0;
            $s['notify_email_enabled'] = !empty($_POST['notify_email_enabled']) ? 1 : 0;
            $s['batch_size'] = max(1, min(10, absint(wp_unslash($_POST['batch_size'] ?? 3))));
            $s['batch_delay'] = max(2, min(60, absint(wp_unslash($_POST['batch_delay'] ?? 5))));
            $sched = isset($_POST['prompt_schedule']) ? sanitize_key(wp_unslash($_POST['prompt_schedule'])) : 'off';
            $s['prompt_schedule'] = in_array($sched, ['off', 'weekly', 'monthly'], true) ? $sched : 'off';
            $s['whitelabel_enabled'] = !empty($_POST['whitelabel_enabled']) ? 1 : 0;
        aivt_update_settings($s);
        AIVT_Prompt_Test::maybe_schedule();
        wp_send_json_success(['message' => __('Settings saved.', 'pewit-geo-analysis-tool')]);
    }

    public static function ajax_test_api() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $key = isset($_POST['api_key']) ? sanitize_text_field(wp_unslash($_POST['api_key'])) : '';
        $s = aivt_get_settings();
        if ($key !== '') {
            $s['api_key'] = $key;
        }
        if (isset($_POST['model'])) {
            $s['model'] = sanitize_text_field(wp_unslash($_POST['model']));
        }
        if (isset($_POST['provider'])) {
            $s['provider'] = AIVT_LLM_API::sanitize_provider_setting(sanitize_key(wp_unslash($_POST['provider'])), aivt_is_pro() || aivt_is_trial());
        }
        aivt_update_settings($s);
        $test = AIVT_API::test($s['api_key']);
        $s['api_key_verified'] = !empty($test['ok']) ? 1 : 0;
        aivt_update_settings($s);
        if (!empty($test['ok'])) {
            wp_send_json_success(['message' => $test['message'], 'mask' => aivt_api_key_masked_label($s['api_key'])]);
        }
        wp_send_json_error(['message' => $test['message'] ?? __('Connection failed', 'pewit-geo-analysis-tool')]);
    }

    /** Run a per-post analysis (geo|entities|eeat|citability). */
    public static function ajax_analyze() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('edit_posts');
        $post_id = absint(wp_unslash($_POST['post_id'] ?? 0));
        $kind = sanitize_key(wp_unslash($_POST['kind'] ?? 'geo'));
        if (!$post_id || !current_user_can('edit_post', $post_id)) {
            wp_send_json_error(['message' => __('Invalid post.', 'pewit-geo-analysis-tool')]);
        }
        switch ($kind) {
            case 'entities':   $res = AIVT_Entities::analyze($post_id); $render = 'entities'; break;
            case 'eeat':       $res = AIVT_EEAT::analyze($post_id); $render = 'eeat'; break;
            case 'citability': $res = AIVT_Citability::analyze($post_id); $render = 'citability'; break;
            default:           $res = AIVT_GEO_Score::analyze($post_id); $render = 'geo'; $kind = 'geo'; break;
        }
        if (is_wp_error($res)) {
            wp_send_json_error(['message' => $res->get_error_message()]);
        }
        ob_start();
        if ($kind === 'geo') {
            AIVT_Render::geo($res, $post_id);
        } else {
            AIVT_Render::$render($res);
        }
        $score = isset($res['score']) ? (int) $res['score'] : (isset($res['overall']) ? (int) $res['overall'] : null);
        wp_send_json_success(['html' => ob_get_clean(), 'kind' => $kind, 'score' => $score]);
    }

    /** Generate FAQ / Q&A / schema. */
    public static function ajax_generate() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('edit_posts');
        $post_id = absint(wp_unslash($_POST['post_id'] ?? 0));
        $kind = sanitize_key(wp_unslash($_POST['kind'] ?? 'faq'));
        $count = max(2, min(12, absint(wp_unslash($_POST['count'] ?? 5))));
        if (!$post_id || !current_user_can('edit_post', $post_id)) {
            wp_send_json_error(['message' => __('Invalid post.', 'pewit-geo-analysis-tool')]);
        }
        if ($kind === 'qa') {
            $res = AIVT_QA::generate($post_id, $count);
            if (is_wp_error($res)) {
                wp_send_json_error(['message' => $res->get_error_message()]);
            }
            ob_start();
            AIVT_Render::pairs($res['items'], 'qa');
            wp_send_json_success(['html' => ob_get_clean(), 'kind' => 'qa', 'blocks' => AIVT_QA::render_blocks($res['items'], __('Q&A', 'pewit-geo-analysis-tool'))]);
        } elseif ($kind === 'schema') {
            $res = AIVT_Schema::generate($post_id);
            if (is_wp_error($res)) {
                wp_send_json_error(['message' => $res->get_error_message()]);
            }
            wp_send_json_success(['kind' => 'schema', 'json' => wp_json_encode($res, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)]);
        }
        $res = AIVT_FAQ::generate($post_id, $count);
        if (is_wp_error($res)) {
            wp_send_json_error(['message' => $res->get_error_message()]);
        }
        ob_start();
        AIVT_Render::pairs($res['pairs'], 'faq');
        wp_send_json_success(['html' => ob_get_clean(), 'kind' => 'faq', 'blocks' => AIVT_FAQ::render_blocks($res['pairs'], __('Frequently Asked Questions', 'pewit-geo-analysis-tool'))]);
    }

    /** Append generated blocks to the post content (manual, free). */
    public static function ajax_insert_content() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('edit_posts');
        $post_id = absint(wp_unslash($_POST['post_id'] ?? 0));
        if (!$post_id || !current_user_can('edit_post', $post_id)) {
            wp_send_json_error(['message' => __('Invalid post.', 'pewit-geo-analysis-tool')]);
        }
        $blocks = isset($_POST['blocks']) ? wp_kses_post(wp_unslash($_POST['blocks'])) : '';
        if ($blocks === '') {
            wp_send_json_error(['message' => __('Nothing to insert.', 'pewit-geo-analysis-tool')]);
        }
        $post = get_post($post_id);
        $updated = trim($post->post_content) . "\n\n" . $blocks;
        wp_update_post(['ID' => $post_id, 'post_content' => $updated]);
        wp_send_json_success(['message' => __('Inserted into the post.', 'pewit-geo-analysis-tool')]);
    }

    public static function ajax_run_prompt() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $prompt = isset($_POST['prompt']) ? sanitize_textarea_field(wp_unslash($_POST['prompt'])) : '';
        $res = aivt_prompt_history_enabled() ? AIVT_Prompt_Test::run_and_store($prompt) : AIVT_Prompt_Test::run($prompt);
        if (is_wp_error($res)) {
            wp_send_json_error(['message' => $res->get_error_message()]);
        }
        ob_start();
        AIVT_Render::prompt_result($res);
        wp_send_json_success(['html' => ob_get_clean()]);
    }

    public static function ajax_suggest_prompts() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $res = AIVT_Prompt_Test::suggest_prompts(6);
        if (is_wp_error($res)) {
            wp_send_json_error(['message' => $res->get_error_message()]);
        }
        wp_send_json_success(['prompts' => $res]);
    }

    public static function ajax_save_prompts() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $raw = isset($_POST['prompts']) ? sanitize_textarea_field(wp_unslash($_POST['prompts'])) : '';
        $lines = array_filter(array_map('trim', explode("\n", $raw)));
        AIVT_Prompt_Test::set_monitored_prompts($lines);
        wp_send_json_success(['message' => __('Prompts saved.', 'pewit-geo-analysis-tool')]);
    }

    public static function ajax_run_competitors() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $res = AIVT_Competitors::analyze(5);
        if (is_wp_error($res)) {
            wp_send_json_error(['message' => $res->get_error_message()]);
        }
        ob_start();
        self::render_competitor_report($res);
        wp_send_json_success(['html' => ob_get_clean()]);
    }

    public static function ajax_start_bulk() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $type = isset($_POST['job_type']) ? sanitize_key(wp_unslash($_POST['job_type'])) : 'geo';
        if (!array_key_exists($type, AIVT_Queue::job_types())) {
            $type = 'geo';
        }
        $job = AIVT_Queue::create_job($type);
        if (is_wp_error($job)) {
            wp_send_json_error(['message' => $job->get_error_message()]);
        }
        ob_start();
        self::render_job_panel($job);
        wp_send_json_success(['message' => __('Bulk job started.', 'pewit-geo-analysis-tool'), 'html' => ob_get_clean()]);
    }

    public static function ajax_job_status() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $job = AIVT_Queue::get_job();
        ob_start();
        self::render_job_panel($job);
        wp_send_json_success(['job' => $job, 'html' => ob_get_clean()]);
    }

    public static function ajax_job_control() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $action = sanitize_key(wp_unslash($_POST['job_action'] ?? ''));
        if ($action === 'pause') {
            $job = AIVT_Queue::pause();
        } elseif ($action === 'resume') {
            $job = AIVT_Queue::resume();
        } elseif ($action === 'stop') {
            $job = AIVT_Queue::stop();
        } else {
            wp_send_json_error(['message' => __('Invalid action', 'pewit-geo-analysis-tool')]);
        }
        ob_start();
        self::render_job_panel($job);
        wp_send_json_success(['job' => $job, 'html' => ob_get_clean()]);
    }

    /* ---------------- GEO Autopilot ---------------- */

    public static function ajax_autopilot_preview() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('edit_posts');
        $post_id = absint(wp_unslash($_POST['post_id'] ?? 0));
        if (!$post_id || !current_user_can('edit_post', $post_id)) {
            wp_send_json_error(['message' => __('Invalid post.', 'pewit-geo-analysis-tool')]);
        }
        $plan = AIVT_Autopilot::plan($post_id);
        if (is_wp_error($plan)) {
            wp_send_json_error(['message' => $plan->get_error_message()]);
        }
        set_transient('aivt_ap_' . $post_id, $plan, HOUR_IN_SECONDS);
        ob_start();
        AIVT_Render::autopilot_preview($plan);
        wp_send_json_success([
            'html'      => ob_get_clean(),
            'predicted' => (int) $plan['predicted_score'],
            'current'   => (int) $plan['current_score'],
        ]);
    }

    public static function ajax_autopilot_apply() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('edit_posts');
        $post_id = absint(wp_unslash($_POST['post_id'] ?? 0));
        if (!$post_id || !current_user_can('edit_post', $post_id)) {
            wp_send_json_error(['message' => __('Invalid post.', 'pewit-geo-analysis-tool')]);
        }
        $plan = get_transient('aivt_ap_' . $post_id);
        $res = AIVT_Autopilot::apply($post_id, is_array($plan) ? $plan : null);
        if (is_wp_error($res)) {
            wp_send_json_error(['message' => $res->get_error_message()]);
        }
        delete_transient('aivt_ap_' . $post_id);
        wp_send_json_success([
            'message'   => __('Autopilot applied. A revision was saved — you can revert below.', 'pewit-geo-analysis-tool'),
            'predicted' => (int) $res['predicted_score'],
        ]);
    }

    public static function ajax_autopilot_revert() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('edit_posts');
        $post_id = absint(wp_unslash($_POST['post_id'] ?? 0));
        if (!$post_id || !current_user_can('edit_post', $post_id)) {
            wp_send_json_error(['message' => __('Invalid post.', 'pewit-geo-analysis-tool')]);
        }
        $res = AIVT_Autopilot::revert($post_id);
        if (is_wp_error($res)) {
            wp_send_json_error(['message' => $res->get_error_message()]);
        }
        wp_send_json_success(['message' => __('Reverted to the pre-Autopilot content.', 'pewit-geo-analysis-tool')]);
    }

    public static function ajax_finish_onboarding() {
        check_ajax_referer('aivt_nonce', 'nonce');
        self::require_cap('manage_options');
        $s = aivt_get_settings();
        $s['onboarding_done'] = 1;
        aivt_update_settings($s);
        wp_send_json_success(['redirect' => aivt_admin_url('dashboard')]);
    }

    /**
     * Other plugins often print license nags on every admin screen.
     * Clear them on our UI so the PEWIT shell stays clean.
     */
    public static function suppress_foreign_notices() {
        $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : '';
        if ($page === '' || strpos($page, 'pewit-geo-analysis-tool') !== 0) {
            return;
        }
        remove_all_actions('admin_notices');
        remove_all_actions('all_admin_notices');
        remove_all_actions('user_admin_notices');
        remove_all_actions('network_admin_notices');
    }
}
