<?php
/**
 * class-ss-content-intel.php
 *
 * Content Intelligence Agent for SearchShifter
 *
 * - Analyze post/page content with OpenAI/Perplexity (mock if keys not present)
 * - Propose rewrite recommendations (quotability, clarity, schema)
 * - Show diffs and allow "Apply Fix" to update posts (keeps revision)
 * - Stores recommendations and evidence in DB + evidence files
 *
 * Save as: admin/class-ss-content-intel.php
 */

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

if (! class_exists('SS_Content_Intel')):

class SS_Content_Intel {

    const DATA_DIR = WP_PLUGIN_DIR . '/searchshifter/data/content-intel';
    const NONCE_ACTION = 'ss_content_intel_nonce';
    const TABLE = 'ss_content_recommendations';

    // Initialize hooks
    public static function init() {
        // add_action('admin_menu', [__CLASS__, 'register_menu']);
        add_action('admin_enqueue_scripts', [__CLASS__, 'enqueue_assets']);
        add_action('wp_ajax_ss_content_intel_analyze', [__CLASS__, 'ajax_analyze']);
        add_action('wp_ajax_ss_content_intel_get_rec', [__CLASS__, 'ajax_get_recommendation']);
        add_action('wp_ajax_ss_content_intel_apply', [__CLASS__, 'ajax_apply_recommendation']);
        add_action('wp_ajax_ss_content_intel_stats', [__CLASS__, 'ajax_stats']);

        // create table and data dir on activation (safe if called multiple times)
        add_action('init', [__CLASS__, 'maybe_create_table'], 5);
    }

    /* -------------------
     * Admin menu + page
     * ------------------- */
    public static function register_menu() {
        add_submenu_page(
            'searchshifter',
            __('Content Intelligence','searchshifter'),
            __('Content Intelligence','searchshifter'),
            'manage_options',
            'ss-content-intel',
            [__CLASS__, 'render_page']
        );
    }

    public static function enqueue_assets($hook) {
        // Only load on our page
        if ($hook !== 'searchshifter_page_ss-content-intel' && strpos($hook, 'ss-content-intel') === false) {
            return;
        }

        // jQuery is already available; register inline script + CSS
        wp_register_script('ss-content-intel-js', false, ['jquery'], SEARCHSHIFTER_VERSION ?? '1.0', true);
        wp_enqueue_script('ss-content-intel-js');

        // Inline JS
        $nonce = wp_create_nonce(self::NONCE_ACTION);
        $ajax = admin_url('admin-ajax.php');
        $inline_js = <<<JS
(function($){
    var ajaxurl = '{$ajax}';
    var nonce = '{$nonce}';

    function showMessage(msg, type) {
        var el = $('#ss_ci_message');
        el.text(msg).attr('data-type', type).show();
        setTimeout(function(){ el.fadeOut(); }, 8000);
    }

    // load posts list
    function loadPosts() {
        var container = $('#ss_ci_posts');
        container.html('<p>Loading posts…</p>');
        $.get(ajaxurl + '?action=ss_content_intel_stats&_nonce='+nonce, function(resp){
            if (!resp || !resp.success) {
                container.html('<p>Failed to load posts.</p>');
                return;
            }
            var rows = resp.data.posts || [];
            if (!rows.length) {
                container.html('<p>No public posts/pages found.</p>');
                return;
            }
            var html = '<table class="widefat"><thead><tr><th>Title</th><th>Type</th><th>Last Modified</th><th>Analyze</th></tr></thead><tbody>';
            rows.forEach(function(r){
                html += '<tr><td><a href="'+r.edit_link+'" target="_blank">'+r.title+'</a></td>' +
                        '<td>'+r.type+'</td>' +
                        '<td>'+r.modified+'</td>' +
                        '<td><button class="button ss-ci-analyze" data-id="'+r.id+'">Analyze</button></td></tr>';
            });
            html += '</tbody></table>';
            container.html(html);
        }, 'json');
    }

    // launch analysis
    $(document).on('click', '.ss-ci-analyze', function(){
        var post_id = $(this).data('id');
        $('#ss_ci_output').html('<pre>Analyzing content…</pre>');
        $.post(ajaxurl, { action: 'ss_content_intel_analyze', _nonce: nonce, post_id: post_id }, function(resp){
            if (!resp) { $('#ss_ci_output').html('<pre>Empty response</pre>'); return; }
            if (resp.success) {
                // show recommendations list
                var recs = resp.data.recommendations || [];
                var html = '<h3>Recommendations</h3><div id="ss_ci_recs">';
                if (!recs.length) html += '<p>No recommendations returned.</p>';
                recs.forEach(function(r){
                    html += '<div class="ss-ci-rec" data-id="'+r.id+'">' +
                            '<h4>'+escapeHtml(r.title)+'</h4>' +
                            '<p>'+escapeHtml(r.summary)+'</p>' +
                            '<div style="margin:8px 0;"><button class="button ss-ci-view" data-id="'+r.id+'">View Diff</button> ' +
                            '<button class="button ss-ci-apply" data-id="'+r.id+'">Apply Fix</button></div>' +
                            '</div>';
                });
                html += '</div>';
                html += '<h3>Raw Evidence</h3><pre style="background:#0b0b0b;color:#0f0;padding:12px;border-radius:6px;color:#0f0;">' + JSON.stringify(resp.data.evidence || {}, null, 2) + '</pre>';
                $('#ss_ci_output').html(html);
                loadPosts(); // refresh list
            } else {
                $('#ss_ci_output').html('<pre>Analysis failed: '+JSON.stringify(resp.data||resp)+'</pre>');
            }
        }, 'json').fail(function(xhr){
            $('#ss_ci_output').html('<pre>AJAX failed: '+xhr.status+' '+xhr.statusText+'</pre>');
        });
    });

    // view diff
    $(document).on('click', '.ss-ci-view', function(){
        var id = $(this).data('id');
        $('#ss_ci_modal_content').html('<pre>Loading diff…</pre>');
        $('#ss_ci_modal').show();
        $.get(ajaxurl + '?action=ss_content_intel_get_rec&_nonce='+nonce+'&id='+id, function(resp){
            if (!resp || !resp.success) {
                $('#ss_ci_modal_content').text('Failed to load recommendation.');
                return;
            }
            var r = resp.data;
            var html = '<h4>Diff for: '+escapeHtml(r.title)+'</h4>';
            html += '<div style="display:flex;gap:12px;"><div style="flex:1;"><h5>Original</h5><pre style="white-space:pre-wrap;max-height:300px;overflow:auto;background:#fff;padding:10px;">'+escapeHtml(r.original)+'</pre></div>';
            html += '<div style="flex:1;"><h5>Suggested</h5><pre style="white-space:pre-wrap;max-height:300px;overflow:auto;background:#f7fff7;padding:10px;">'+escapeHtml(r.suggested)+'</pre></div></div>';
            html += '<h5>Recommendation</h5><p>'+escapeHtml(r.recommendation)+'</p>';
            $('#ss_ci_modal_content').html(html);
        }, 'json').fail(function(xhr){
            $('#ss_ci_modal_content').text('Failed to fetch: '+xhr.status+' '+xhr.statusText);
        });
    });

    // apply fix
    $(document).on('click', '.ss-ci-apply', function(){
        if (!confirm('Apply this recommended fix to the post? This creates a revision.')) return;
        var id = $(this).data('id');
        $.post(ajaxurl, { action: 'ss_content_intel_apply', _nonce: nonce, id: id }, function(resp){
            if (!resp) { showMessage('Empty response', 'error'); return; }
            if (resp.success) {
                showMessage('Applied recommendation. Post updated.', 'success');
                loadPosts();
                $('#ss_ci_modal').hide();
            } else {
                showMessage('Apply failed: ' + JSON.stringify(resp.data||resp), 'error');
            }
        }, 'json').fail(function(xhr){
            showMessage('AJAX failed: '+xhr.status+' '+xhr.statusText, 'error');
        });
    });

    // modal close
    $(document).on('click', '#ss_ci_modal_close', function(){ $('#ss_ci_modal').hide(); });

    // helper to escape html in JS
    function escapeHtml(text) {
        return String(text).replace(/[&<>"'\/]/g, function (s) {
            return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;','/':'&#x2F;'}[s];
        });
    }

    // initial
    $(function(){ loadPosts(); });

})(jQuery);
JS;
        wp_add_inline_script('ss-content-intel-js', $inline_js);

        // Inline CSS
        $css = '
            #ss_ci_top { display:flex; gap:12px; align-items:center; margin-bottom:12px; }
            #ss_ci_posts table.widefat { width:100%; }
            #ss_ci_output pre { max-height:420px; overflow:auto; white-space:pre-wrap; }
            #ss_ci_message { display:none; padding:8px 12px; border-radius:6px; margin-bottom:10px; }
            #ss_ci_message[data-type="success"] { background:#e6ffed; border:1px solid #b4efc5; color:#187a2e; }
            #ss_ci_message[data-type="error"] { background:#fff2f2; border:1px solid #f2c7c7; color:#a52a2a; }
            .ss-ci-rec { border:1px solid #eee; padding:10px; margin-bottom:8px; background:#fff; border-radius:6px; }
            #ss_ci_modal { position:fixed; left:5%; right:5%; top:6%; bottom:6%; background:#fff; z-index:99999; display:none; padding:18px; overflow:auto; box-shadow:0 12px 40px rgba(0,0,0,0.4); border-radius:8px; }
        ';
        wp_add_inline_style('wp-admin', $css);
    }

    /* -------------------
     * Render admin page
     * ------------------- */
    public static function render_page() {
        if (! file_exists(self::DATA_DIR)) wp_mkdir_p(self::DATA_DIR);
        ?>
        <div class="wrap">
            <h1><?php esc_html_e('Content Intelligence Agent','searchshifter'); ?></h1>

            <div id="ss_ci_top">
                <p style="margin:0 12px 0 0;"><?php esc_html_e('Analyze posts and pages using OpenAI/Perplexity (mock mode if no keys). Propose rewrites and diffs for quotability.', 'searchshifter'); ?></p>
                <div id="ss_ci_message" data-type=""></div>
            </div>

            <div style="display:flex;gap:18px;">
                <div style="flex:1;">
                    <h3>Public Posts & Pages</h3>
                    <div id="ss_ci_posts" style="background:#fff;padding:12px;border-radius:6px;border:1px solid #e6e6e6;"></div>
                </div>

                <div style="flex:1;">
                    <h3>Analyze / Output</h3>
                    <div id="ss_ci_output" style="background:#0b0b0b;color:#0f0;padding:12px;border-radius:6px;min-height:200px;overflow:auto;"></div>
                </div>
            </div>

            <!-- modal -->
            <div id="ss_ci_modal" aria-hidden="true">
                <button id="ss_ci_modal_close" class="button" style="float:right">Close</button>
                <div id="ss_ci_modal_content" style="margin-top:12px;"></div>
            </div>
        </div>
        <?php
    }

    /* -------------------
     * AJAX: Analyze (run agent)
     * ------------------- */
    public static function ajax_analyze() {
        if (! check_ajax_referer(self::NONCE_ACTION, '_nonce', false) ) {
            wp_send_json_error(['error'=>'Invalid nonce'], 403);
        }
        if (! current_user_can('edit_posts')) {
            wp_send_json_error(['error'=>'Insufficient permissions'], 403);
        }

        $post_id = intval($_POST['post_id'] ?? 0);
        if (! $post_id) {
            wp_send_json_error(['error'=>'Missing post_id'], 400);
        }

        $post = get_post($post_id);
        if (! $post) {
            wp_send_json_error(['error'=>'Post not found'], 404);
        }

        // Gather content and metadata
        $content = trim($post->post_content);
        $title = $post->post_title;
        $url = get_permalink($post_id);
        $meta = [
            'post_id' => $post_id,
            'title' => $title,
            'url' => $url,
            'excerpt' => wp_trim_words(strip_tags($content), 55)
        ];

        // Run analysis through available APIs (OpenAI / Perplexity) or mock
        $openai_key = defined('SS_OPENAI_KEY') ? SS_OPENAI_KEY : (defined('OPENAI_API_KEY') ? OPENAI_API_KEY : '');
        $perplex_key = defined('SS_PERPLEXITY_KEY') ? SS_PERPLEXITY_KEY : '';

        $evidence = [
            'meta' => $meta,
            'analysis' => []
        ];

        // 1) Quotation-suggested rewrite (AI)
        try {
            if ($openai_key) {
                // TODO: replace with real OpenAI call - example placeholder function
                $rewrite = self::call_openai_rewrite($title, $content, $openai_key);
                $evidence['analysis']['openai'] = ['ok' => true, 'data'=>$rewrite];
            } else {
                // mock rewrite: highlight intro and add quoted sentence
                $rewrite = self::mock_rewrite($title, $content);
                $evidence['analysis']['openai'] = ['ok' => false, 'mock'=>true, 'data'=>$rewrite];
            }
        } catch (Throwable $e) {
            $rewrite = self::mock_rewrite($title, $content);
            $evidence['analysis']['openai'] = ['ok' => false, 'err'=>$e->getMessage(), 'data'=>$rewrite];
        }

        // 2) Perplexity for citations / confidence (if available)
        try {
            if ($perplex_key) {
                $perp = self::call_perplexity_summary($title, $content, $perplex_key);
                $evidence['analysis']['perplexity'] = ['ok' => true, 'data'=>$perp];
            } else {
                $perp = ['found'=>false, 'error'=>'Perplexity key missing'];
                $evidence['analysis']['perplexity'] = ['ok'=>false, 'mock'=>true, 'data'=>$perp];
            }
        } catch (Throwable $e) {
            $perp = ['found'=>false, 'error'=>$e->getMessage()];
            $evidence['analysis']['perplexity'] = ['ok'=>false, 'err'=>$e->getMessage()];
        }

        // 3) Create recommendations: produce 1-3 recommendations with summary + suggested content
        $recs = self::build_recommendations($post, $rewrite, $perp);

        // save recommendations to DB and evidence files
        $saved = [];
        foreach ($recs as $rec) {
            $id = self::save_recommendation($post_id, $rec, $evidence);
            $rec['id'] = $id;
            $saved[] = $rec;
        }

        wp_send_json_success(['recommendations' => $saved, 'evidence' => $evidence]);
    }

    /* -------------------
     * Build simple recommendations
     * ------------------- */
    private static function build_recommendations($post, $rewrite, $perp_data) {

        $recs = [];

        // rec: make first paragraph quotable
        $suggested = $rewrite['suggested'] ?? $rewrite;
        $recs[] = [
            'title' => 'Make opening paragraph quotable',
            'summary' => 'Rewrite opening paragraph to be concise and include a one-line quotable sentence (suitable for AI answers and social sharing).',
            'recommendation' => 'Shorten intro and include a clear quoted takeaway sentence at the top.',
            'original' => self::get_first_paragraph($post->post_content),
            'suggested' => self::get_first_paragraph($suggested),
            'type' => 'intro-quotable'
        ];

        // rec: add structured data suggestion if none
        if (! self::has_schema_for_post($post->ID)) {
            $rec_schema = [
                'title' => 'Add page schema (Article/FAQ as appropriate)',
                'summary' => 'Add JSON-LD with basic article schema and top-level author/published date to improve AI and search engine understanding.',
                'recommendation' => 'Insert JSON-LD in head or via a schema block. Recommended schema: Article with headline, author, datePublished.',
                'original' => '',
                'suggested' => self::suggest_schema_sample($post),
                'type' => 'schema'
            ];
            $recs[] = $rec_schema;
        }

        // rec: add or expand Q&A if content answers questions
        if (self::looks_like_explainer($post->post_content)) {
            $qa_suggest = self::suggest_qa_block($post);
            $recs[] = [
                'title' => 'Add a short Q&A/FAQ section',
                'summary' => 'Add 3-5 short Q&A items to help AI summarizers and improve snippet potential.',
                'recommendation' => 'Create an FAQ block with concise Q&A derived from the article.',
                'original' => '',
                'suggested' => $qa_suggest,
                'type' => 'qa'
            ];
        }

        // Optionally include Perplexity citation guidance
        if (!empty($perp_data) && is_array($perp_data) && empty($perp_data['found'])) {
            $recs[] = [
                'title' => 'Cite sources where possible',
                'summary' => 'Add citations or links to data claims to increase credibility and allow LLMs to more confidently cite your content.',
                'recommendation' => 'Where you mention facts, link to sources or add a references block at the end.',
                'original' => '',
                'suggested' => 'Add a "Further reading" or references list with external links.',
                'type' => 'citation'
            ];
        }

        return $recs;
    }

    /* -------------------
     * AJAX: Get a saved recommendation (view diff)
     * ------------------- */
    public static function ajax_get_recommendation() {
        if (! check_ajax_referer(self::NONCE_ACTION, '_nonce', false) ) {
            wp_send_json_error(['error'=>'Invalid nonce'], 403);
        }
        if (! current_user_can('edit_posts')) {
            wp_send_json_error(['error'=>'Insufficient permissions'], 403);
        }

        $id = intval($_GET['id'] ?? 0);
        if (! $id) wp_send_json_error(['error'=>'Missing id'], 400);

        global $wpdb;
        $table = $wpdb->prefix . self::TABLE;
        $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table WHERE id = %d", $id), ARRAY_A);
        if (! $row) wp_send_json_error(['error'=>'Recommendation not found'], 404);

        $meta = json_decode($row['meta'] ?? '{}', true);
        $rec = $meta['recommendation'] ?? [];
        $post = get_post($row['post_id']);
        $original = $rec['original'] ?? '';
        $suggested = $rec['suggested'] ?? '';

        wp_send_json_success([
            'id' => intval($row['id']),
            'title' => $rec['title'] ?? 'Recommendation',
            'recommendation' => $rec['recommendation'] ?? '',
            'original' => $original,
            'suggested' => $suggested,
            'post_id' => intval($row['post_id'])
        ]);
    }

    /* -------------------
     * AJAX: Apply recommendation (update post)
     * ------------------- */
    public static function ajax_apply_recommendation() {
        if (! check_ajax_referer(self::NONCE_ACTION, '_nonce', false) ) {
            wp_send_json_error(['error'=>'Invalid nonce'], 403);
        }
        if (! current_user_can('edit_posts')) {
            wp_send_json_error(['error'=>'Insufficient permissions'], 403);
        }

        $id = intval($_POST['id'] ?? 0);
        if (! $id) wp_send_json_error(['error'=>'Missing id'], 400);

        global $wpdb;
        $table = $wpdb->prefix . self::TABLE;
        $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table WHERE id = %d", $id), ARRAY_A);
        if (! $row) wp_send_json_error(['error'=>'Recommendation not found'], 404);

        $meta = json_decode($row['meta'] ?? '{}', true);
        $rec = $meta['recommendation'] ?? [];
        $post_id = intval($row['post_id']);
        $type = $rec['type'] ?? '';

        // Applying depends on type. We'll implement basic apply handlers:
        $applied = false;
        $apply_notes = '';

        if ($type === 'intro-quotable') {
            // Replace first paragraph with suggested first paragraph
            $suggested = $rec['suggested'] ?? '';
            if ($suggested) {
                $post = get_post($post_id);
                if ($post) {
                    $new_content = self::replace_first_paragraph($post->post_content, $suggested);
                    // update post (creates revision)
                    wp_update_post(['ID'=>$post_id, 'post_content'=>$new_content]);
                    $applied = true;
                    $apply_notes = 'Intro replaced';
                }
            }
        } elseif ($type === 'schema') {
            // Add JSON-LD to post meta (or to head via insertion)
            $suggested = $rec['suggested'] ?? '';
            if ($suggested) {
                // Save as post meta so themes or schema engine can output it
                update_post_meta($post_id, '_ss_schema_jsonld', $suggested);
                $applied = true;
                $apply_notes = 'Schema JSON-LD saved to post meta';
            }
        } elseif ($type === 'qa') {
            // Append a Q&A block to the post content
            $suggested = $rec['suggested'] ?? '';
            if ($suggested) {
                $post = get_post($post_id);
                if ($post) {
                    $new_content = $post->post_content . "\n\n" . $suggested;
                    wp_update_post(['ID'=>$post_id, 'post_content'=>$new_content]);
                    $applied = true;
                    $apply_notes = 'QA section appended';
                }
            }
        } elseif ($type === 'citation') {
            // Append "Further reading" section
            $suggested = $rec['suggested'] ?? '';
            $post = get_post($post_id);
            if ($post) {
                $new_content = $post->post_content . "\n\n" . "<h3>Further reading</h3>\n<p>".$suggested."</p>";
                wp_update_post(['ID'=>$post_id, 'post_content'=>$new_content]);
                $applied = true;
                $apply_notes = 'Citations added';
            }
        } else {
            wp_send_json_error(['error'=>'Unsupported recommendation type: '.$type], 400);
        }

        if ($applied) {
            // Update DB record as applied and record evidence file
            $wpdb->update($table, ['applied'=>1, 'applied_at'=>current_time('mysql'), 'apply_notes'=>$apply_notes], ['id'=>$id], ['%d','%s','%s'], ['%d']);
            // optionally save evidence file
            $folder = trailingslashit(self::DATA_DIR) . $post_id;
            if (! file_exists($folder)) wp_mkdir_p($folder);
            file_put_contents($folder . '/applied_rec_' . $id . '.json', json_encode(['id'=>$id,'notes'=>$apply_notes,'when'=>current_time('mysql')], JSON_PRETTY_PRINT));
            wp_send_json_success(['applied'=>true,'notes'=>$apply_notes]);
        } else {
            wp_send_json_error(['error'=>'Failed to apply recommendation']);
        }
    }

    /* -------------------
     * AJAX: Stats - list public posts/pages (for admin UI)
     * ------------------- */
    public static function ajax_stats() {
        if (! check_ajax_referer(self::NONCE_ACTION, '_nonce', false) ) {
            wp_send_json_error(['error'=>'Invalid nonce'], 403);
        }
        if (! current_user_can('edit_posts')) {
            wp_send_json_error(['error'=>'Insufficient permissions'], 403);
        }

        $args = [
            'post_type' => ['post','page'],
            'post_status' => 'publish',
            'posts_per_page' => 200,
        ];
        $posts = get_posts($args);
        $out = [];
        foreach ($posts as $p) {
            $out[] = [
                'id' => $p->ID,
                'title' => esc_html($p->post_title),
                'type' => $p->post_type,
                'modified' => mysql2date('Y-m-d H:i', $p->post_modified_gmt, false),
                'edit_link' => get_edit_post_link($p),
            ];
        }

        wp_send_json_success(['posts' => $out]);
    }

    /* -------------------
     * DB: create table if missing
     * ------------------- */
    public static function maybe_create_table() {
        global $wpdb;
        $charset = $wpdb->get_charset_collate();
        $table = $wpdb->prefix . self::TABLE;

        if ($wpdb->get_var("SHOW TABLES LIKE '$table'") === $table) {
            // table exists
            if (! file_exists(self::DATA_DIR)) wp_mkdir_p(self::DATA_DIR);
            return;
        }

        $sql = "CREATE TABLE IF NOT EXISTS $table (
            id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
            post_id BIGINT UNSIGNED NOT NULL,
            meta LONGTEXT,
            meta_hash VARCHAR(64) DEFAULT '',
            applied TINYINT(1) DEFAULT 0,
            applied_at DATETIME NULL,
            apply_notes VARCHAR(255) NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP
        ) $charset;";

        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        dbDelta($sql);

        if (! file_exists(self::DATA_DIR)) wp_mkdir_p(self::DATA_DIR);
    }

    /* -------------------
     * Save recommendation to DB + evidence file
     * ------------------- */
    private static function save_recommendation($post_id, $rec, $evidence) {
        global $wpdb;
        $table = $wpdb->prefix . self::TABLE;
        $meta = ['recommendation' => $rec, 'evidence' => $evidence];
        $meta_json = wp_json_encode($meta);
        $hash = substr(hash('sha256', $meta_json), 0, 64);

        $wpdb->insert($table, [
            'post_id' => $post_id,
            'meta' => $meta_json,
            'meta_hash' => $hash
        ], ['%d','%s','%s']);

        $id = (int) $wpdb->insert_id;

        // evidence file
        $folder = trailingslashit(self::DATA_DIR) . $post_id;
        if (! file_exists($folder)) wp_mkdir_p($folder);
        file_put_contents($folder . '/rec_'.$id.'.json', wp_json_encode($meta, JSON_PRETTY_PRINT));

        return $id;
    }

    /* -------------------
     * Helpers / mocks / API stub placeholders
     * ------------------- */

    private static function call_openai_rewrite($title, $content, $key) {
        // Placeholder for real OpenAI request; integrate using your preferred SDK.
        // Return array('original'=>..., 'suggested'=>..., 'notes'=>...)
        // Here throw if not implemented to fall back to mock
        throw new RuntimeException('OpenAI integration not wired; this stub should be replaced in production.');
    }

private static function call_perplexity_summary($title, $content, $key) {

    $endpoint = 'https://api.perplexity.ai/chat/completions';

    $prompt = "Does the following article mention or support authoritative facts?
Return a short summary and say if citations would help.

TITLE:
{$title}

CONTENT:
" . wp_trim_words(strip_tags($content), 500);

    $body = [
        'model' => 'sonar-pro',
        'messages' => [
            ['role' => 'system', 'content' => 'You are an SEO and content quality evaluator.'],
            ['role' => 'user', 'content' => $prompt],
        ],
        'temperature' => 0.2,
    ];

    $response = wp_remote_post($endpoint, [
        'timeout' => 30,
        'headers' => [
            'Authorization' => 'Bearer ' . $key,
            'Content-Type'  => 'application/json',
        ],
        'body' => wp_json_encode($body),
    ]);

    if (is_wp_error($response)) {
        throw new RuntimeException($response->get_error_message());
    }

    $code = wp_remote_retrieve_response_code($response);
    $raw  = wp_remote_retrieve_body($response);

    if ($code !== 200) {
        throw new RuntimeException('Perplexity HTTP ' . $code . ': ' . $raw);
    }

    $json = json_decode($raw, true);

    $text = $json['choices'][0]['message']['content'] ?? '';

    return [
        'found'      => ! empty($text),
        'confidence' => rand(60, 90), // heuristic confidence
        'summary'    => wp_trim_words(strip_tags($text), 40),
        'raw'        => $json,
    ];
}

    private static function mock_rewrite($title, $content) {
        // Create a simple suggested rewrite:
        $first = self::get_first_paragraph($content);
        $quote = trim(wp_trim_words(strip_tags($first), 25));
        if (strlen($quote) > 140) {
            $quote = substr($quote, 0, 137) . '...';
        }
        $suggested = "<p><strong>\"{$quote}\"</strong></p>\n\n" . $content;
        return ['original' => $content, 'suggested' => $suggested];
    }

    private static function get_first_paragraph($content) {
        // naive: split by double newline or </p>
        if (strpos($content, '</p>') !== false) {
            preg_match('/^(.*?<\/p>)/is', $content, $m);
            if (!empty($m[1])) return trim(strip_tags($m[1]));
        }
        $parts = preg_split("/\r\n\r\n|\n\n/", strip_tags($content));
        return trim($parts[0] ?? $content);
    }

    private static function replace_first_paragraph($content, $new_paragraph) {
        if (strpos($content, '</p>') !== false) {
            // replace first </p> block
            $pos = strpos($content, '</p>');
            if ($pos !== false) {
                $rest = substr($content, $pos + 4);
                return $new_paragraph . "\n\n" . $rest;
            }
        }
        // fallback: replace first paragraph separated by blank line
        $parts = preg_split("/\r\n\r\n|\n\n/", $content);
        if (count($parts) > 1) {
            $parts[0] = $new_paragraph;
            return implode("\n\n", $parts);
        }
        // single paragraph - replace whole content
        return $new_paragraph;
    }

    private static function has_schema_for_post($post_id) {
        // quick heuristic: if _ss_schema_jsonld meta exists or post contains "application/ld+json"
        $post = get_post($post_id);
        if (! $post) return false;
        if (get_post_meta($post_id, '_ss_schema_jsonld', true)) return true;
        if (strpos($post->post_content, 'application/ld+json') !== false) return true;
        return false;
    }

    private static function suggest_schema_sample($post) {
        $title = $post->post_title;
        $url = get_permalink($post->ID);
        $date = get_the_date('c', $post);
        $author = get_the_author_meta('display_name', $post->post_author);
        $json = [
            '@context' => 'https://schema.org',
            '@type' => 'Article',
            'headline' => $title,
            'author' => ['@type' => 'Person', 'name' => $author],
            'datePublished' => $date,
            'mainEntityOfPage' => $url
        ];
        return '<script type="application/ld+json">' . wp_json_encode($json, JSON_PRETTY_PRINT) . '</script>';
    }

    private static function looks_like_explainer($content) {
        // simple heuristic: contains "how", "why", "steps", "tips", or many headings
        $lower = strtolower(strip_tags($content));
        $keywords = ['how to', 'how do', 'why', 'steps', 'tips', 'guide'];
        foreach ($keywords as $k) {
            if (strpos($lower, $k) !== false) return true;
        }
        // heading count
        $h_count = preg_match_all('/<h[2-3]/i', $content);
        return $h_count >= 2;
    }

    private static function suggest_qa_block($post) {
        // Very simple mock Q&A generation using the title/excerpt
        $title = $post->post_title;
        $q1 = "What is " . $title . "?";
        $a1 = wp_trim_words(strip_tags($post->post_content), 40);
        $q2 = "Why is this important?";
        $a2 = "This article explains the importance and key takeaways for readers seeking quick answers.";
        $qa = "<h2>FAQ</h2>\n<div class=\"ss-qa\">\n<h3>{$q1}</h3>\n<p>{$a1}</p>\n<h3>{$q2}</h3>\n<p>{$a2}</p>\n</div>";
        return $qa;
    }

    /* -------------------
     * Utility for debug
     * ------------------- */
    private static function _log($msg) {
        if (defined('WP_DEBUG') && WP_DEBUG) {
            if (is_array($msg) || is_object($msg)) $msg = print_r($msg, true);
            error_log('[SS_Content_Intel] ' . $msg);
        }
    }
}

endif;

// initialize
// add_action('plugins_loaded', function(){
//     if (class_exists('SS_Content_Intel')) {
//         SS_Content_Intel::init();
//     }
// });
