<?php
// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
if (!defined('ABSPATH')) exit;

// --- Enqueue progress bar JS only for the Visibility Scanner page ---
add_action('admin_enqueue_scripts', function($hook) {
    if ($hook === 'searchshifter_page_searchshifter-visibility-scanner') {
        wp_enqueue_script(
            'ss-scanner-progress',
            SEARCHSHIFTER_PLUGIN_URL . 'assets/js/scanner-progress.js',
            ['jquery'],
            SEARCHSHIFTER_VERSION,
            true
        );
        wp_localize_script('ss-scanner-progress', 'SS_Scanner_Ajax', [
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce'    => wp_create_nonce('ss_scanner_refresh'),
        ]);
    }
});
add_action('admin_init', function() {

    if (!isset($_POST['ss_export_csv_scanner']) && 
        !isset($_POST['ss_export_pdf_scanner'])) {
        return;
    }

    if (
        !isset($_POST['_wpnonce']) ||
        !wp_verify_nonce(
            sanitize_text_field(
                wp_unslash($_POST['_wpnonce'])
            ),
            'ss_export_scanner'
        )
    ) {
        wp_die('Security check failed.');
    }


    global $wpdb;

    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $rows = $wpdb->get_results(
        "SELECT * FROM {$wpdb->prefix}ss_scans ORDER BY id DESC"
    );

    require_once SEARCHSHIFTER_PLUGIN_DIR . 'includes/class-ss-export.php';

    if (isset($_POST['ss_export_csv_scanner'])) {
        SS_Export::csv('AI-Visibility-Report.csv', $rows);
    }

    if (isset($_POST['ss_export_pdf_scanner'])) {
        SS_Export::pdf('AI-Visibility-Report.pdf', $rows);
    }

    exit;
});

/**
 * Admin Page: AI Visibility Scanner (Pro Feature)
 * Automatically lists site pages/posts with AI visibility scan results.
 */
class SS_Admin_Visibility_Scanner {

    /**
     * Render admin page
     */
    public static function render_page() {
        global $wpdb;
        $table = $wpdb->prefix . SS_Scanner::TABLE;

        echo '<div class="wrap"><h1>AI Visibility Scanner</h1>';

        echo '<p>This tool automatically scans your site’s public pages and posts for AI visibility signals, schema presence, and quotability.</p>';

        // Auto-enqueue all published URLs (first load only)
        self::maybe_enqueue_site_urls($table);

        // Fetch recent scans
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $rows = $wpdb->get_results(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "SELECT * FROM {$wpdb->prefix}ss_scans
            ORDER BY id DESC
            LIMIT 50"
        );

        // --- Handle export actions ---

        // Rescan all button
        echo '<form method="post" style="margin:15px 0;">';
        wp_nonce_field('ss_rescan_all');
        echo '<button class="button button-primary" name="rescan_all">🔄 Re-scan All Pages</button>';

        echo '</form>';
        // --- Export buttons (CSV / PDF) ---
        echo '<form method="post" style="margin:15px 0;">';
        wp_nonce_field('ss_export_scanner');
        echo '<button class="button" name="ss_export_csv_scanner">📊 Export CSV</button> ';
        echo '<button class="button" name="ss_export_pdf_scanner">🧾 Export PDF</button>';
        echo '</form>';
        if ( isset( $_POST['rescan_all'] ) && check_admin_referer( 'ss_rescan_all' ) ) {

            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->query(
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                "UPDATE {$wpdb->prefix}ss_scans
                SET status = 'queued',
                    attempts = 0,
                    finished_at = NULL"
            );

            echo '<div class="updated notice"><p>✅ All pages have been re-queued for a new scan.</p></div>';

            // Reload rows
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $rows = $wpdb->get_results(
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                "SELECT * FROM {$wpdb->prefix}ss_scans
                ORDER BY id DESC
                LIMIT 50"
            );
        }
        // Progress
        echo '<div id="ss-scan-progress" style="margin:15px 0; background:#f1f1f1; border-radius:6px; height:22px; overflow:hidden;">
                <div id="ss-scan-progress-bar" style="background:#2271b1; width:0%; height:100%; transition:width 0.6s ease;"></div>
              </div>
              <p id="ss-scan-progress-text" style="font-weight:500;">Waiting for scan progress...</p>';

        // Table header
        echo '<h2>Recent Scans</h2>';
        echo '<table class="widefat fixed striped">';
        echo '<thead><tr>
                <th width="5%">ID</th>
                <th width="30%">URL</th>
                <th width="15%">Status</th>
                <th width="20%">Log</th>
                <th width="13%">Finished At</th>
                <th width="22%">Actions</th>
              </tr></thead><tbody>';

        if ($rows) {
            foreach ($rows as $r) {
                echo '<tr>';
                echo '<td>' . intval($r->id) . '</td>';
                echo '<td><a href="' . esc_url($r->url) . '" target="_blank">' . esc_html($r->url) . '</a></td>';
                echo '<td>' . esc_html($r->status) . '</td>';
                $log_entries = explode("\n", trim($r->log));
                $latest_log = end($log_entries);
                echo '<td>' . esc_html($latest_log ?: '(no recent log)') . '</td>';
                echo '<td>' . esc_html($r->finished_at) . '</td>';
                // If already optimized (we check 'fix applied' presence) show badge instead of button
                $logLower = strtolower($r->log ?? '');
                $isOptimized = (strpos($logLower, 'fix applied:') !== false && strpos($logLower, 'fix applied:') !== false);
                if ($isOptimized) {
                    echo '<td><span class="button" style="background:#4CAF50;color:#fff;cursor:default;">✅ Optimized</span></td>';
                } else {
                    echo '<td>
                        <button class="button view-recommendations" data-scan-id="' . intval($r->id) . '">View Recommendations</button>
                

                    </td>';
                }
                echo '</tr>';

                // hidden row for recommendations
                echo '<tr id="recommendations-' . intval($r->id) . '" class="recommendation-row" style="display:none;background:#f9f9f9;">';
                echo '<td colspan="6" class="recommendation-content"><em>Loading recommendations...</em></td>';
                echo '</tr>';
            }
        } else {
                echo '<tr><td colspan="6" style="text-align:center;">No scans found yet.</td></tr>';
        }

        echo '</tbody></table></div>'; // Close wrap

        // ✅ Create persistent modal zone outside the main admin content area
        echo '<div id="ss-modal-root" style="position:relative;z-index:999999;"></div>';

    }

    /**
     * Automatically enqueue all published site URLs
     */
    private static function maybe_enqueue_site_urls($table) {
        global $wpdb;

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $existing = $wpdb->get_col(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "SELECT url FROM {$wpdb->prefix}ss_scans"
        );

        $existing = array_map('trim', (array) $existing);

        // ✅ Only get real content (no Elementor templates, no system pages)
        $allowed_types = ['page', 'post', 'project', 'service'];
        
        $query = new WP_Query([
            'post_type'      => $allowed_types,
            'post_status'    => 'publish',
            'posts_per_page' => -1,
            'fields'         => 'ids'
        ]);

        if (empty($query->posts)) return;

        foreach ($query->posts as $post_id) {
            $url = get_permalink($post_id);
            if (!$url || in_array($url, $existing, true)) continue;

            // 🚫 Skip unwanted URLs
            if (
                strpos($url, '?') !== false || // query URLs like ?elementor_library
                strpos($url, '/wp-json') !== false ||
                strpos($url, '/feed') !== false ||
                strpos($url, '/attachment') !== false
            ) {
                continue;
            }

            // ✅ Insert only real content URLs
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
            $wpdb->insert(
                "{$wpdb->prefix}ss_scans",
                [
                    'url'        => esc_url_raw( $url ),
                    'status'     => 'queued',
                    'attempts'   => 0,
                    'log'        => 'Waiting for background scan...',
                    'started_at' => current_time( 'mysql' ),
                ],
                [
                    '%s',
                    '%s',
                    '%d',
                    '%s',
                    '%s',
                ]
            );
        }
    }

}

// --- AJAX endpoint for progress bar ---
add_action('wp_ajax_ss_scanner_status', function() {
    check_ajax_referer('ss_scanner_refresh', 'nonce');
    global $wpdb;
    $table = $wpdb->prefix . 'ss_scans';

    // Total scans
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $total = (int) $wpdb->get_var(
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        "SELECT COUNT(*) FROM {$wpdb->prefix}ss_scans"
    );

    // Done scans
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $done = (int) $wpdb->get_var(
        $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "SELECT COUNT(*) FROM {$wpdb->prefix}ss_scans WHERE status = %s",
            'done'
        )
    );

    // Queued scans
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $queued = (int) $wpdb->get_var(
        $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "SELECT COUNT(*) FROM {$wpdb->prefix}ss_scans WHERE status = %s",
            'queued'
        )
    );

    // Running scans
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $running = (int) $wpdb->get_var(
        $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "SELECT COUNT(*) FROM {$wpdb->prefix}ss_scans WHERE status = %s",
            'running'
        )
    );


    wp_send_json([
        'total'   => $total,
        'done'    => $done,
        'queued'  => $queued,
        'running' => $running,
        'percent' => ($total ? round(($done / $total) * 100) : 0),
    ]);
});

// --- AJAX endpoint for refreshing scan table ---
add_action('wp_ajax_ss_scanner_table', function() {
    check_ajax_referer('ss_scanner_refresh', 'nonce');
    global $wpdb;
    $table = $wpdb->prefix . 'ss_scans';

    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $rows = $wpdb->get_results(
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        "SELECT * FROM {$wpdb->prefix}ss_scans
        ORDER BY id DESC
        LIMIT 50"
    );

    ob_start();
    if ($rows) {
        foreach ($rows as $r) {
            echo '<tr>';
            echo '<td>' . intval($r->id) . '</td>';
            echo '<td><a href="' . esc_url($r->url) . '" target="_blank">' . esc_html($r->url) . '</a></td>';
            echo '<td>' . esc_html($r->status) . '</td>';
            $log_entries = explode("\n", trim($r->log));
            $latest_log = end($log_entries);
            echo '<td>' . esc_html($latest_log ?: '(no recent log)') . '</td>';

            echo '<td>' . esc_html($r->finished_at) . '</td>';

            $logLower = strtolower($r->log ?? '');
            // --- Detect applied fixes individually ---
            $hasGlossary = strpos($logLower, 'fix applied: link to glossary terms') !== false;
            $hasSchema   = strpos($logLower, 'fix applied: add structured data (schema.org)') !== false;
            $hasQA       = strpos($logLower, 'fix applied: add faq section') !== false;

            // Count how many total recommendations exist
            $totalFixes = 3; // glossary + schema + q&a
            $doneFixes  = intval($hasGlossary) + intval($hasSchema) + intval($hasQA);

            // If all done, show "Optimized", else "View Recommendations"
            if ($doneFixes >= $totalFixes) {
                echo '<td><span class="button" style="background:#4CAF50;color:#fff;cursor:default;">✅ Optimized</span>
            <button class="button ss-view-diff" style="margin-left:6px;" data-scan-id="' . intval($r->id) . '">🧾 View Diff</button></td>';
            } else {
                echo '<td>
                    <button class="button view-recommendations" data-scan-id="' . esc_attr( intval( $r->id ) ) . '">
                View Recommendations (' . esc_html( intval( $totalFixes - $doneFixes ) ) . ' left)
            </button>

                <button class="button ss-view-diff" data-scan-id="' . intval($r->id) . '">🧾 View Diff</button>
                </td>';
            }



            echo '</tr>';

            echo '<tr id="recommendations-' . intval($r->id) . '" class="recommendation-row" style="display:none;background:#f9f9f9;">';
            echo '<td colspan="6" class="recommendation-content"><em>Loading recommendations...</em></td>';
            echo '</tr>';
        }
    } else {
        echo '<tr><td colspan="6" style="text-align:center;">No scans found yet.</td></tr>';
    }

    wp_send_json_success(['html' => ob_get_clean()]);
});

// --- AJAX endpoint for recommendations ---
add_action('wp_ajax_ss_get_recommendations', function() {
    check_ajax_referer('ss_scanner_refresh', 'nonce');

    global $wpdb;
    $scan_id = intval($_POST['scan_id'] ?? 0);
    $table = $wpdb->prefix . 'ss_scans';
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $scan = $wpdb->get_row(
        $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "SELECT * FROM {$wpdb->prefix}ss_scans WHERE id = %d",
            (int) $scan_id
        )
    );


    if (!$scan) {
        wp_send_json_error(['message' => 'Scan not found']);
    }

    $recs = [];
    $log = strtolower($scan->log ?? '');
    $score = intval($scan->score ?? 0);

    // --- Smart threshold logic ---
    if ($score >= 85) {
        // High score = "All good" if schema/glossary already found
        if (strpos($log, 'found: glossary linked') !== false || strpos($log, 'found: schema added') !== false) {
            $recs[] = ['title' => '✅ All Good!', 'desc' => 'This page is already optimized based on the latest scan results.'];
        } else {
            $recs[] = ['title' => 'Minor Tweaks Suggested', 'desc' => 'You can optionally add a FAQ section or glossary links for even higher visibility.'];
        }
    } else {
        // --- Regular candidate recommendations ---
        $candidates = [
            'add structured data (schema.org)' => 'This page lacks structured data markup. Adding schema.org JSON-LD helps AI bots and search engines understand your content.',
            'add faq section'                => 'Include a short FAQ section to improve AI summarization and ranking in answers.',
            'link to glossary terms'           => 'Link key niche terms to your glossary for better AI contextual understanding.'
        ];

        foreach ($candidates as $title => $desc) {
            // Skip already applied or found optimizations
            if (
                strpos($log, 'fix applied: ' . $title) !== false ||
                strpos($log, 'found: glossary linked') !== false && $title === 'link to glossary terms' ||
                strpos($log, 'found: schema added') !== false && $title === 'add structured data (schema.org)' ||
                strpos($log, 'found: content length ok') !== false && $title === 'add faq section'
            ) {
                continue;
            }

            $recs[] = ['title' => $title, 'desc' => $desc];
        }

        // If everything looks good but score < 85
        if (empty($recs)) {
            $recs[] = ['title' => '✅ All Good!', 'desc' => 'This page already includes schema, glossary terms, and FAQ section.'];
        }
    }

    ob_start();
    echo '<div class="ss-recommendations">';
    foreach ($recs as $r) {
        echo '<div class="ss-recommendation-item" style="margin-bottom:10px;padding:10px;border:1px solid #ddd;border-radius:6px;background:#f9f9f9;">';
        echo '<strong>' . esc_html(ucwords($r['title'])) . '</strong>';
        echo '<p style="margin:5px 0;">' . esc_html($r['desc']) . '</p>';

        if ($r['title'] !== '✅ All Good!' && strpos($r['title'], 'Minor') === false) {
            echo '<button class="button button-primary ss-apply-rec" data-action="' . esc_attr($r['title']) . '" data-scan="' . intval($scan_id) . '">Apply Fix</button>';
        }
        echo '</div>';
    }
    echo '<div style="margin-top:15px;">
            <button class="button ss-close-recommendations">✕ Close Recommendations</button>
        </div>';

    echo '</div>';

    wp_send_json_success(['html' => ob_get_clean()]);
});

// --- AJAX endpoint for showing before/after content diff ---
add_action('wp_ajax_ss_get_diff', function() {
    check_ajax_referer('ss_scanner_refresh', 'nonce');
    global $wpdb;

    $scan_id = intval($_POST['scan_id'] ?? 0);
    $table = $wpdb->prefix . 'ss_scans';
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $scan = $wpdb->get_row(
        $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "SELECT * FROM {$wpdb->prefix}ss_scans WHERE id = %d",
            (int) $scan_id
        )
    );

    if (!$scan) {
        wp_send_json_error(['message' => 'Scan not found']);
    }

    // Find related post
    $post_id = url_to_postid($scan->url);
    if ( ! $post_id ) {

        $parsed = wp_parse_url( $scan->url );
        $path   = $parsed['path'] ?? '';
        $slug   = basename( untrailingslashit( $path ) );

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $post_id = $wpdb->get_var(
            $wpdb->prepare(
                "
                SELECT ID
                FROM {$wpdb->posts}
                WHERE post_name = %s
                AND post_status = 'publish'
                LIMIT 1
                ",
                $slug
            )
        );
    }

    if (!$post_id) wp_send_json_error(['message' => 'No matching post found.']);

    $content = apply_filters('the_content', get_post_field('post_content', $post_id));
    $content = wp_kses_post($content);


    // Retrieve log history (old log before fix)
    $log = esc_html($scan->log ?? '(no log data)');
    $log_html = nl2br($log);

    wp_send_json_success([
        'html' => "
            <div style='padding:10px;'>
                <h3>Post: " . esc_html(get_the_title($post_id)) . "</h3>
                <hr/>
                <h4>🔹 Current Content (after fixes)</h4>
                <div style='border:1px solid #ddd; padding:10px; background:#fafafa; max-height:250px; overflow:auto;'>
                    {$content}
                </div>
                <h4 style='margin-top:20px;'>🕓 Scan Log (history)</h4>
                <div style='border:1px solid #ddd; padding:10px; background:#fff; max-height:200px; overflow:auto;'>
                    {$log_html}
                </div>
            </div>
        "
    ]);
});
// --- AJAX endpoint: apply recommendation ---
add_action('wp_ajax_ss_apply_recommendation', function() {
    check_ajax_referer('ss_scanner_refresh', 'nonce');
    global $wpdb;

    $scan_id    = intval($_POST['scan_id'] ?? 0);
    $fix_action = '';

    if ( isset( $_POST['fix_action'] ) ) {
        $fix_action = sanitize_text_field(
            wp_unslash( $_POST['fix_action'] )
        );
    }

    $table = $wpdb->prefix . 'ss_scans'; // use dynamic prefix

    if (!$scan_id || !$fix_action) {
        wp_send_json_error(['message' => 'Missing parameters']);
    }

    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $scan = $wpdb->get_row(
        $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "SELECT * FROM {$wpdb->prefix}ss_scans WHERE id = %d",
            (int) $scan_id
        )
    );

    if (!$scan) wp_send_json_error(['message' => 'Scan not found']);

    $post_id = url_to_postid($scan->url);
    if (!$post_id) {
        $url_clean = strtok($scan->url, '?');
        $post_id = url_to_postid($url_clean);
    }
    if (!$post_id) wp_send_json_error(['message' => 'No matching post found']);

    $fix_key = strtolower(trim($fix_action));
    $message = '';

    // === Smart Glossary Fix ===
    if ($fix_key === 'link to glossary terms') {

        // ✅ Load glossary from wp_options (used by glossary-page.php)
        $option_key = 'ss_glossary_terms';
        $terms = get_option($option_key, []);

        // If no glossary or empty array
        if (empty($terms) || !is_array($terms)) {
            wp_send_json_error(['message' => 'No glossary terms found']);
        }

        // Prepare the post content for linking
        $content = apply_filters('the_content', get_post_field('post_content', $post_id));

        foreach ($terms as $t) {
            $term       = trim($t['term'] ?? '');
            $definition = trim($t['definition'] ?? '');
            $same_as    = trim($t['same_as'] ?? '');

            if (empty($term)) continue;

            // ✅ Avoid replacing inside HTML tags
            $pattern = '/\b(' . preg_quote($term, '/') . ')\b(?![^<]*>)/i';

            // ✅ Use same_as if available, else fallback to generated glossary URL
            $link = !empty($same_as)
                ? esc_url($same_as)
                : site_url('/glossary/' . sanitize_title($term));

            // ✅ Tooltip + clickable link
            $replacement = '<a href="' . $link . '" class="ss-glossary-term" title="' . esc_attr($definition) . '">' . $term . '</a>';

            // Only replace the first instance of each term (prevents overlinking)
            $content = preg_replace($pattern, $replacement, $content, 1);
        }

        // ✅ Save updated post content
        wp_update_post(['ID' => $post_id, 'post_content' => $content]);

        // ✅ Log which terms were linked for transparency
        $linked_terms = [];
        foreach ($terms as $t) {
            $term = $t['term'] ?? '';
            if ($term && stripos($content, $term) !== false) {
                $linked_terms[] = $term;
            }
        }

        $term_list = !empty($linked_terms) ? implode(', ', $linked_terms) : 'None';
        $message = 'Glossary terms linked successfully ✅ (' . $term_list . ')';

    }
    // === Smart Schema Fix ===
    elseif ($fix_key === 'add structured data (schema.org)') {
        $content = apply_filters('the_content', get_post_field('post_content', $post_id));

        $has_schema_script = (strpos($content, 'application/ld+json') !== false);
        $has_webpage_type  = (strpos($content, '"@type": "WebPage"') !== false);

        if ($has_schema_script && $has_webpage_type) {
            $message = 'Schema already present, skipped duplicate';
        } else {
      update_post_meta($post_id, '_ss_flag_add_schema', '1');

            $message = 'Structured data added (checked for duplicates)';
        }
    }
    // === Smart FAQ Fix ===
    elseif ($fix_key === 'add faq section') {
        $content = apply_filters('the_content', get_post_field('post_content', $post_id));
        $faq_exists = preg_match('/faq|frequently asked questions/i', $content);

        if ($faq_exists) {
            $message = 'FAQ section already exists, skipped duplicate';
        } else {
            $post_title = get_the_title($post_id);
            $qa = "<h2>Frequently Asked Questions</h2>\n<div class='ss-qa'>
                <p><strong>Q:</strong> What is the topic of '{$post_title}'?</p>
                <p><strong>A:</strong> This page titled '{$post_title}' has been optimized for AI visibility, structured data, and improved understanding by search engines.</p>
            </div>";

            $content .= "\n\n" . $qa;
            wp_update_post(['ID' => $post_id, 'post_content' => $content]);
            $message = 'Dynamic FAQ section added (customized per page)';
        }
    }
    else {
        $message = 'Fix logged';
    }

    // === Log update ===
    $log_append = "\nFix applied: " . $fix_action;
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $result = $wpdb->query(
        $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "UPDATE {$wpdb->prefix}ss_scans
            SET log = CONCAT(IFNULL(log, ''), %s),
                status = %s,
                finished_at = NOW()
            WHERE id = %d",
            $log_append,
            'queued',
            (int) $scan_id
        )
    );

    if ($result === false) {
        wp_send_json_error(['message' => 'Database update failed: ' . $wpdb->last_error]);
    }

    wp_send_json_success(['message' => $message . ' ✅ (Saved to DB)']);
});

add_filter('searchshifter_schema_graph', function($graph, $post_id){

    if (get_post_meta($post_id, '_ss_flag_add_schema', true)) {

        $graph[] = [
            "@type" => "WebPage",
            "@id"   => get_permalink($post_id) . "#webpage",
            "name"  => get_the_title($post_id),
            "url"   => get_permalink($post_id)
        ];
    }

    return $graph;
}, 10, 2);

add_action('wp_ajax_ss_reoptimize_scan', function() {
    check_ajax_referer('ss_scanner_refresh', 'nonce');
    global $wpdb;

    $scan_id = intval($_POST['scan_id'] ?? 0);
    $table = $wpdb->prefix . 'ss_scans';
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $scan = $wpdb->get_row(
        $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            "SELECT * FROM {$wpdb->prefix}ss_scans WHERE id = %d",
            (int) $scan_id
        )
    );

    if (!$scan) wp_send_json_error(['message' => 'Scan not found']);
    $post_id = url_to_postid($scan->url);
    if (!$post_id) wp_send_json_error(['message' => 'No post found for URL']);

    // 🔁 Re-run all auto optimizations
    $content = apply_filters('the_content', get_post_field('post_content', $post_id));
    $original = $content;

    // 🧠 Smart Schema Check (add if missing)
    if (strpos($content, 'application/ld+json') === false) {
        $schema = '<script type="application/ld+json">' . json_encode([
            "@context" => "https://schema.org",
            "@type"    => "WebPage",
            "name"     => get_the_title($post_id),
            "url"      => get_permalink($post_id)
        ], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . '</script>';
        $content .= "\n\n" . $schema;
    }

    // 💬 Smart FAQ Check
    if (!preg_match('/faq|frequently asked questions/i', $content)) {
        $qa = "<h2>Frequently Asked Questions</h2><div class='ss-qa'>
            <p><strong>Q:</strong> What is the topic of “" . esc_html(get_the_title($post_id)) . "”?</p>
            <p><strong>A:</strong> This page is optimized for AI visibility and structured data.</p>
        </div>";
        $content .= "\n\n" . $qa;
    }

    // 🧾 Smart Glossary Link Check
    $terms = get_option('ss_glossary_terms', []);
    // detect <div class='ss-qa'>
    if (strpos($content, 'ss-qa') !== false) {
        $faq_schema = [
            "@type" => "FAQPage",
            "mainEntity" => [
                [
                    "@type" => "Question",
                    "name" => "What is the topic of '{$post_title}'?",
                    "acceptedAnswer" => [
                        "@type" => "Answer",
                        "text" => "This page titled '{$post_title}' ..."
                    ]
                ]
            ]
        ];
    }


    // Only update if something changed
    if ($content !== $original) {
        wp_update_post(['ID' => $post_id, 'post_content' => $content]);
        $log_append = "\nRe-optimized on " . current_time('mysql');
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->query(
            $wpdb->prepare(
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                "UPDATE {$wpdb->prefix}ss_scans
                SET log = CONCAT(IFNULL(log, ''), %s),
                    finished_at = NOW()
                WHERE id = %d",
                $log_append,
                (int) $scan_id
            )
        );

        wp_send_json_success(['message' => '✅ Re-optimized successfully']);
    } else {
        wp_send_json_success(['message' => 'No changes detected (already optimized)']);
    }
});

add_action('admin_head', function() {
    echo '<style>
        /* --- Fix buttons layout in scanner table --- */
        .ss-actions {
            display: flex !important;
            gap: 8px !important;
            align-items: center;
            flex-wrap: nowrap;
            white-space: nowrap;
        }
        .ss-actions .button {
            margin: 0 !important;
            display: inline-flex !important;
        }
    </style>';
});
// phpcs:enable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
