<?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_CONTENT_DIR . '/uploads/searchshifter/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 =
            "(function($){
                var ajaxurl = '" . esc_js( $ajax ) . "';
                var nonce   = '" . esc_js( $nonce ) . "';

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

                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');
                }

                $(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) {
                            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>';
                            $('#ss_ci_output').html(html);
                            loadPosts();
                        } else {

                            var msg = 'Analysis failed.';

                            if (resp.data && resp.data.error) {
                                msg = resp.data.error;
                            }

                            $('#ss_ci_output').html(
                                '<div class=\"ss-ci-rec\">' +
                                '<p style=\"color:#a52a2a;\">⚠️ ' + msg + '</p>' +
                                '</div>'
                            );
                        }

                    }, 'json');
                });

                $(document).on('click', '.ss-ci-view', function(){

                    var id = $(this).data('id');

                    $('#ss_ci_output').html('<p>Loading recommendation...</p>');

                    $.get(ajaxurl, {
                        action: 'ss_content_intel_get_rec',
                        _nonce: nonce,
                        id: id
                    }, function(resp){

                        if (!resp || !resp.success) {
                            $('#ss_ci_output').html('<p>Failed to load recommendation.</p>');
                            return;
                        }

                        var r = resp.data;

                        var html = '';

                        html += '<div class=\"ss-ci-rec\">';
                        html += '<h4>' + r.title + '</h4>';

                        html += '<h5>Original</h5>';
                        html += '<div class=\"ss-ci-original\">' + r.original + '</div>';

                        html += '<h5>Suggested</h5>';
                        html += '<div class=\"ss-ci-suggested\">' + r.suggested + '</div>';


                        html += '</div>';

                        $('#ss_ci_output').html(html);

                    }, 'json');

                });

                $(document).on('click', '.ss-ci-apply', function(){

                    var id = $(this).data('id');

                    if (!confirm('Are you sure you want to apply this fix?')) {
                        return;
                    }

                    $.post(ajaxurl, {
                        action: 'ss_content_intel_apply',
                        _nonce: nonce,
                        id: id
                    }, function(resp){

                        if (!resp || !resp.success) {
                            alert('Failed to apply fix.');
                            return;
                        }

                        alert('Fix applied successfully.');
                        location.reload();

                    }, 'json');

                });


                function escapeHtml(text) {
                    return String(text).replace(/[&<>]/g, function (s) {
                        return {
                            '&':'&amp;',
                            '<':'&lt;',
                            '>':'&gt;'
                        }[s];
                    });
                }


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

            })(jQuery);";

        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 {
                background:#ffffff;
                padding:16px;
                border-radius:8px;
                border:1px solid #e5e5e5;
                min-height:250px;
            }

            .ss-ci-rec {
                border:1px solid #eaeaea;
                background:#fafafa;
                padding:16px;
                margin-bottom:14px;
                border-radius:8px;
            }

            .ss-ci-rec h4 {
                margin:0 0 6px 0;
                color:#1d2327;
            }

            .ss-ci-rec p {
                color:#555;
            }

            .ss-ci-original {
                background:#fff;
                border:1px solid #ddd;
                padding:10px;
                margin-bottom:10px;
            }

            .ss-ci-suggested {
                background:#f0fff4;
                border:1px solid #b4efc5;
                padding:10px;
            }

            #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_register_style('ss-content-intel-css', false, [], '1.0.0');
        wp_enqueue_style('ss-content-intel-css');
        wp_add_inline_style('ss-content-intel-css', $css);

    }

    private static function is_meaningful_content($content) {

        $clean = trim(wp_strip_all_tags($content));

        // If empty
        if ($clean === '') {
            return false;
        }

        // If only shortcode
        if (preg_match('/^\[[^\]]+\]$/', $clean)) {
            return false;
        }

        // If too short
        if (strlen($clean) < 60) {
            return false;
        }

        return true;
    }


    /* -------------------
     * 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" class="ss-ci-output"></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);
        }

                if ( self::is_system_page($post->post_content) ) {
            wp_send_json_error([
                'error' => 'This page appears to be a dynamic or system page and is not suitable for content analysis.'
            ]);
        }

        // Gather content and metadata
        $content = trim($post->post_content);
        if (!self::is_meaningful_content($content)) {
            wp_send_json_error([
                'error' => 'This page does not contain analyzable content.'
            ]);
        }
        $title = $post->post_title;
        $url = get_permalink($post_id);
        $meta = [
            'post_id' => $post_id,
            'title' => $title,
            'url' => $url,
            'excerpt' => wp_trim_words(wp_strip_all_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]);
    }

    private static function is_system_page($content) {

        $clean = trim(wp_strip_all_tags($content));

        // 1️⃣ Block if completely empty
        if (empty($clean)) {
            return true;
        }

        // 2️⃣ Block if content is ONLY a shortcode
        if (preg_match('/^\[[^\]]+\]$/', trim($content))) {
            return true;
        }

        // 3️⃣ Block known system shortcodes
        $blocked_shortcodes = ['lifterlms', 'llms_', 'woocommerce_', 'wp_login'];

        foreach ($blocked_shortcodes as $sc) {
            if (stripos($content, '[' . $sc) !== false) {
                return true;
            }
        }

        return false;
    }


    private static function has_ss_faq($content) {
        return strpos($content, 'class="ss-qa"') !== false;
    }

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

        $recs = [];

        // rec: make first paragraph quotable
       $first_original = self::get_first_paragraph($post->post_content);

        // extract ONLY first paragraph from rewritten content
        $first_suggested = self::get_first_paragraph($rewrite['suggested']);
        if (! self::is_intro_quotable($post->post_content)) {

            $first_original  = self::get_first_paragraph($post->post_content);
            $first_suggested = self::get_first_paragraph($rewrite['suggested']);

            $recs[] = [
                'title' => 'Make opening paragraph quotable',
                'summary' => 'Your opening paragraph is not structured in a way that is easily quotable by AI systems or search engines. Adding a clear one-line takeaway improves snippet potential and AI citation probability.',
                'recommendation' => 'Shorten intro and include a clear quoted takeaway sentence at the top.',
                'original' => $first_original,
                'suggested' => '<p><strong>"' . esc_html($first_suggested) . '"</strong></p>',
                '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)
            && ! self::has_ss_faq($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;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $row = $wpdb->get_row(
            $wpdb->prepare(
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                "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;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $row = $wpdb->get_row(
            $wpdb->prepare(
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                "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
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $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 (
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->get_var(
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                "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);

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
        $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) {

        $first = self::get_first_paragraph($content);

        $quote = wp_trim_words(wp_strip_all_tags($first), 22);

        return [
            'original' => $content,
            'suggested' => '<p><strong>"'.$quote.'"</strong></p>' . "\n\n" . $content
        ];
    }


    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(wp_strip_all_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(
                    esc_html( $response->get_error_message() )
                );
            }

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

            if ( 200 !== (int) $code ) {
                throw new RuntimeException(
                    esc_html(
                        sprintf(
                            'Perplexity HTTP %d: %s',
                            (int) $code,
                            wp_strip_all_tags( $raw )
                        )
                    )
                );
            }

            $json = json_decode($raw, true);

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

            return [
                'found'      => ! empty($text),
                'confidence' => wp_rand(60, 90), // heuristic confidence
                'summary'    => wp_trim_words(wp_strip_all_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(wp_strip_all_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(wp_strip_all_tags($m[1]));
        }
        $parts = preg_split("/\r\n\r\n|\n\n/", wp_strip_all_tags($content));
        return trim($parts[0] ?? $content);
    }

    private static function is_intro_quotable($content) {
        return (
            strpos($content, '<strong>"') !== false ||
            strpos($content, '<strong>&quot;') !== false
        );
    }

    private static function replace_first_paragraph($content, $new_paragraph) {

        // Ensure paragraph wrapper
        if (stripos($new_paragraph, '<p') === false) {
            $new_paragraph = '<p>' . wp_kses_post($new_paragraph) . '</p>';
        }

        // Gutenberg block paragraph
        if (preg_match('/<!-- wp:paragraph -->(.*?)<!-- \/wp:paragraph -->/is', $content)) {
            return preg_replace(
                '/<!-- wp:paragraph -->(.*?)<!-- \/wp:paragraph -->/is',
                '<!-- wp:paragraph -->' . $new_paragraph . '<!-- /wp:paragraph -->',
                $content,
                1
            );
        }

        // Elementor text editor
        if (preg_match('/<div class="elementor-widget-text-editor[^"]*">(.*?)<\/div>/is', $content)) {
            return preg_replace(
                '/(<div class="elementor-widget-text-editor[^"]*>)(.*?)(<\/div>)/is',
                '$1' . $new_paragraph . '$3',
                $content,
                1
            );
        }

        // Classic editor <p>
        if (preg_match('/<p[\s\S]*?<\/p>/i', $content)) {
            return preg_replace(
                '/<p[\s\S]*?<\/p>/i',
                $new_paragraph,
                $content,
                1
            );
        }

        // Fallback
        return $new_paragraph . "\n\n" . $content;
    }

    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(wp_strip_all_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(wp_strip_all_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 ) {
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
            if ( is_array( $msg ) || is_object( $msg ) ) {
                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
                $msg = print_r( $msg, true );
            }

            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log( '[SS_Content_Intel] ' . $msg );
        }
    }

}

endif;

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