<?php
/**
 * DBA Startup Hub Admin — Admin settings page
 *
 * Adds submenu page: Damalion Blog AI → 🚀 Startup Hub
 * Includes settings, generate controls, progress bar, status dashboard,
 * article settings (word count, CTA with live preview), plagiarism compliance,
 * internal linking & hub post status panel.
 *
 * Mirrors GeoBot admin panel features for consistency.
 *
 * @since 2.16.0
 */

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

class DBA_Startup_Hub_Admin {

    private static $instance = null;

    public static function get_instance() {
        if ( null === self::$instance ) self::$instance = new self();
        return self::$instance;
    }

    private function __construct() {
        add_action( 'admin_menu', array( $this, 'add_submenu' ), 40 );
        add_action( 'admin_init', array( $this, 'register_settings' ) );

        // AJAX
        add_action( 'wp_ajax_dba_startup_hub_import_cities', array( $this, 'ajax_import_cities' ) );
        add_action( 'wp_ajax_dba_startup_hub_create_hub_page', array( $this, 'ajax_create_hub_page' ) );
        add_action( 'wp_ajax_dba_startup_hub_orphan_audit', array( $this, 'ajax_orphan_audit' ) );
    }

    public function add_submenu() {
        $config = DBA_Startup_Hub_Registry::get_config();
        add_submenu_page(
            'dba-settings',
            $config['label'],
            $config['menu_label'],
            'manage_options',
            $config['admin_slug'],
            array( $this, 'render_page' )
        );
    }

    public function register_settings() {
        $config = DBA_Startup_Hub_Registry::get_config();
        register_setting(
            $config['settings_option'] . '_group',
            $config['settings_option'],
            array( $this, 'sanitize_settings' )
        );
    }

    public function sanitize_settings( $input ) {
        $clean = array();
        $clean['enabled']       = ! empty( $input['enabled'] );
        $clean['posts_per_run'] = max( 1, min( 5, intval( $input['posts_per_run'] ?? 1 ) ) );
        $clean['post_status']   = in_array( $input['post_status'] ?? '', array( 'publish', 'draft' ), true )
                                    ? $input['post_status'] : 'publish';
        $clean['author_id']     = max( 1, intval( $input['author_id'] ?? 1 ) );

        $valid_days = array( 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday' );
        $days = array();
        if ( ! empty( $input['posting_days'] ) && is_array( $input['posting_days'] ) ) {
            foreach ( $input['posting_days'] as $d ) {
                $d = strtolower( sanitize_text_field( $d ) );
                if ( in_array( $d, $valid_days, true ) ) $days[] = $d;
            }
        }
        $clean['posting_days'] = ! empty( $days ) ? $days : array( 'monday', 'tuesday', 'wednesday', 'thursday', 'friday' );

        // Article Settings
        $clean['word_count_min']       = max( 500, min( 3000, intval( $input['word_count_min'] ?? 1000 ) ) );
        $clean['word_count_max']       = max( $clean['word_count_min'], min( 5000, intval( $input['word_count_max'] ?? 1800 ) ) );
        $clean['require_subtitle']     = ! empty( $input['require_subtitle'] );
        $clean['require_company_link'] = ! empty( $input['require_company_link'] );
        $clean['require_gov_link']     = ! empty( $input['require_gov_link'] );

        // CTA fields
        $clean['cta_enabled']   = ! empty( $input['cta_enabled'] );
        $clean['cta_text']      = sanitize_textarea_field( $input['cta_text'] ?? '' );
        $clean['cta_link_text'] = sanitize_text_field( $input['cta_link_text'] ?? '' );
        $clean['cta_link_url']  = esc_url_raw( $input['cta_link_url'] ?? 'https://www.damalion.com/lets-connect/' );
        $clean['cta_html_override'] = wp_kses_post( $input['cta_html_override'] ?? '' );

        if ( $clean['enabled'] ) {
            DBA_Startup_Hub_Scheduler::activate();
        }

        return $clean;
    }

    /* =================================================================
     *  RENDER PAGE
     * ================================================================= */

    public function render_page() {
        $config     = DBA_Startup_Hub_Registry::get_config();
        $settings   = get_option( $config['settings_option'], array() );
        $cities     = DBA_Startup_Hub_Registry::get_cities();
        $categories = DBA_Startup_Hub_Registry::get_categories();
        $last_run   = get_option( $config['last_run_option'], array() );
        $hub_id     = get_option( $config['hub_page_option'], 0 );
        $nonce      = wp_create_nonce( 'dba_admin_nonce' );
        $opt        = $config['settings_option'];

        // --- Auto-detect hub page if option is empty but page exists ---
        if ( ! $hub_id || ! get_post_status( $hub_id ) || get_post_status( $hub_id ) === 'trash' ) {
            $found_hub = null;

            // Method 1: Search by known slugs
            $hub_slugs = array(
                'smb-growth-hub-u-s-market-entry-business-expansion-services',
                'us-startup-ecosystem-analysis',
                'smb-growth-hub',
            );
            foreach ( $hub_slugs as $slug ) {
                $found = get_page_by_path( $slug, OBJECT, 'post' );
                if ( $found && $found->post_status !== 'trash' ) {
                    $found_hub = $found->ID;
                    break;
                }
            }

            // Method 2: Search by hub meta key
            if ( ! $found_hub ) {
                $meta_search = get_posts( array(
                    'post_type'      => 'post',
                    'post_status'    => array( 'publish', 'draft', 'private' ),
                    'meta_key'       => '_dba_startup_hub_hub_post',
                    'meta_value'     => '1',
                    'posts_per_page' => 1,
                    'fields'         => 'ids',
                ) );
                if ( ! empty( $meta_search ) ) {
                    $found_hub = $meta_search[0];
                }
            }

            // Method 3: Search by title keywords
            if ( ! $found_hub ) {
                $title_search = get_posts( array(
                    'post_type'      => 'post',
                    'post_status'    => array( 'publish', 'draft', 'private' ),
                    's'              => 'SMB Growth Hub',
                    'posts_per_page' => 1,
                    'fields'         => 'ids',
                ) );
                if ( ! empty( $title_search ) ) {
                    $found_hub = $title_search[0];
                }
            }

            if ( $found_hub ) {
                $hub_id = $found_hub;
                update_option( $config['hub_page_option'], $hub_id, false );
                update_post_meta( $hub_id, '_dba_startup_hub_hub_post', '1' );
                error_log( 'DBA StartupHub: Auto-detected hub page #' . $hub_id . ' — "' . get_the_title( $hub_id ) . '"' );
            }
        }

        // --- Stats ---
        $all_post_ids = get_posts( array(
            'post_type' => 'post', 'post_status' => array( 'publish', 'draft' ),
            'meta_key' => $config['meta_auto_created'], 'meta_compare' => 'EXISTS',
            'posts_per_page' => -1, 'fields' => 'ids',
        ) );
        $total_posts = count( $all_post_ids );

        $recent_posts = count( get_posts( array(
            'post_type' => 'post', 'post_status' => 'publish',
            'meta_key' => $config['meta_auto_created'], 'meta_compare' => 'EXISTS',
            'posts_per_page' => -1, 'fields' => 'ids',
            'date_query' => array( array( 'after' => '30 days ago' ) ),
        ) ) );

        $cities_covered = array();
        foreach ( $all_post_ids as $pid ) {
            $c = get_post_meta( $pid, '_dba_startup_hub_city', true );
            if ( $c ) $cities_covered[ $c ] = true;
        }
        $cities_written = count( $cities_covered );
        $total_cities   = count( $cities );
        $coverage_pct   = $total_cities > 0 ? round( ( $cities_written / $total_cities ) * 100, 1 ) : 0;

        // Orphan count
        $orphan_count = 0;
        $hub_ok = ( $hub_id && get_post_status( $hub_id ) && get_post_status( $hub_id ) !== 'trash' );
        if ( $hub_ok ) {
            $hub_content = get_post_field( 'post_content', $hub_id );
            foreach ( $all_post_ids as $pid ) {
                if ( $pid == $hub_id ) continue;
                $permalink = get_permalink( $pid );
                if ( $permalink && strpos( $hub_content, $permalink ) === false ) $orphan_count++;
            }
        }

        // Cross-city links
        $cross_linked = 0;
        foreach ( array_slice( $all_post_ids, 0, 200 ) as $pid ) {
            $pc = get_post_field( 'post_content', $pid );
            if ( stripos( $pc, 'startup-hub-related' ) !== false || stripos( $pc, 'Related Cities' ) !== false || stripos( $pc, 'Related Ecosystems' ) !== false ) {
                $cross_linked++;
            }
        }

        // Copyscape
        $dba_settings  = get_option( 'dba_settings', array() );
        $has_copyscape = ! empty( $dba_settings['copyscape_api_key'] );

        // CTA defaults
        $cta_enabled   = $settings['cta_enabled'] ?? true;
        $cta_text      = $settings['cta_text'] ?? 'Damalion supports international investors, entrepreneurs, and family offices navigating the U.S. startup ecosystem with structuring, compliance, and strategic advisory.';
        $cta_link_text = $settings['cta_link_text'] ?? 'Contact your Damalion experts now.';
        $cta_link_url  = $settings['cta_link_url'] ?? 'https://www.damalion.com/lets-connect/';

        ?>
        <div class="wrap">
        <h1>🚀 Startup Hub <small style="font-size:13px;color:#666;">U.S. Startup Ecosystem — v2.16.0</small></h1>

        <!-- ══ COVERAGE STATS BAR ══ -->
        <div style="background:#f0fef0;border:1px solid #c3e6cb;border-radius:6px;padding:10px 18px;margin-bottom:20px;font-size:14px;">
            <strong>Coverage:</strong> <?php echo $cities_written; ?>/<?php echo $total_cities; ?> cities written (<?php echo $coverage_pct; ?>%)
            &nbsp;|&nbsp; <strong>Last 30 days:</strong> <?php echo $recent_posts; ?> posts
            &nbsp;|&nbsp; <strong>Total published:</strong> <?php echo $total_posts; ?>
            &nbsp;|&nbsp;
            <button class="button button-small" id="dba-shub-reset-rotation">🔄 Reset Rotation</button>
        </div>

        <!-- ══ PLAGIARISM DETECTION & GOOGLE PENALTY COMPLIANCE ══ -->
        <div class="postbox" style="padding:15px;margin-bottom:20px;background:#f9fff9;border-color:#c3e6cb;">
            <h2 style="margin-top:0;">🛡 Plagiarism Detection &amp; Google Penalty Compliance — <span style="color:<?php echo class_exists('DBA_Plagiarism') ? '#46b450' : '#dc3232'; ?>;"><?php echo class_exists('DBA_Plagiarism') ? 'ACTIVE' : 'NOT LOADED'; ?></span></h2>
            <table style="width:100%;border-collapse:collapse;">
                <tr>
                    <td style="padding:6px 12px;width:30px;">✅</td>
                    <td style="padding:6px 12px;width:280px;"><strong>Gate A — Internal Duplicate Detection</strong></td>
                    <td style="padding:6px 12px;">Jaccard 3-gram shingling against ALL existing Damalion posts. Threshold: 35% overlap = REJECT. <strong>ENABLED</strong></td>
                </tr>
                <tr>
                    <td style="padding:6px 12px;">✅</td>
                    <td style="padding:6px 12px;"><strong>Gate B — Sentence-Level Uniqueness</strong></td>
                    <td style="padding:6px 12px;">Compares every sentence (&gt;30 chars) against last 30 Startup Hub posts. 90% similarity = flagged. Max 15% duplicate sentences allowed. <strong>ENABLED</strong></td>
                </tr>
                <tr>
                    <td style="padding:6px 12px;"><?php echo $has_copyscape ? '✅' : '⚠️'; ?></td>
                    <td style="padding:6px 12px;"><strong>Gate C — Copyscape API</strong></td>
                    <td style="padding:6px 12px;">
                        <?php if ( $has_copyscape ) : ?>
                            Premium API plagiarism scan. <strong>ENABLED</strong>
                        <?php else : ?>
                            <span style="color:#dc3232;">Not configured.</span> Add Copyscape credentials in <a href="<?php echo admin_url( 'admin.php?page=dba-settings' ); ?>">Settings</a> for web-wide plagiarism detection. Fallback: web sentence sampling.
                        <?php endif; ?>
                    </td>
                </tr>
                <tr>
                    <td style="padding:6px 12px;">✅</td>
                    <td style="padding:6px 12px;"><strong>Gate D — Web Sentence Sampling</strong></td>
                    <td style="padding:6px 12px;">5 random sentences searched via Google to detect web-wide matches. Active when Copyscape is not configured. <strong><?php echo $has_copyscape ? 'STANDBY' : 'ENABLED (fallback)'; ?></strong></td>
                </tr>
                <tr>
                    <td style="padding:6px 12px;">✅</td>
                    <td style="padding:6px 12px;"><strong>Gate E — AI Prompt Anti-Template</strong></td>
                    <td style="padding:6px 12px;">System prompt instructs AI to vary sentence structure, vocabulary, and narrative angle per city. Retry on validation failure. <strong>ENABLED</strong></td>
                </tr>
            </table>
            <p style="color:#666;margin:12px 0 0;">
                <strong>Pipeline:</strong> Every article passes through Gates A → B → (C or D) → E before publishing. Any gate failure = article REJECTED and regenerated (up to 2 retries). Failed articles are logged with full error trace.
            </p>
        </div>

        <!-- ══ INTERNAL LINKING & HUB POST ══ -->
        <div class="postbox" style="padding:15px;margin-bottom:20px;background:#f9fff9;border-color:#c3e6cb;">
            <?php $all_linked = ( $orphan_count === 0 && $hub_ok ); ?>
            <h2 style="margin-top:0;">🔗 Internal Linking &amp; Hub Post — <span style="color:<?php echo $all_linked ? '#46b450' : '#dc3232'; ?>;"><?php echo $all_linked ? 'ALL POSTS LINKED' : $orphan_count . ' ORPHAN(S)'; ?></span></h2>
            <table style="width:100%;border-collapse:collapse;">
                <tr>
                    <td style="padding:6px 12px;width:30px;"><?php echo $hub_ok ? '✅' : '❌'; ?></td>
                    <td style="padding:6px 12px;width:200px;"><strong>Hub/Pillar Post</strong></td>
                    <td style="padding:6px 12px;">
                        <?php if ( $hub_ok ) : ?>
                            <a href="<?php echo get_permalink( $hub_id ); ?>" target="_blank"><?php echo esc_html( get_the_title( $hub_id ) ); ?></a>
                            &nbsp;<a href="<?php echo get_edit_post_link( $hub_id ); ?>" style="color:#666;">(edit)</a>
                        <?php else : ?>
                            <span style="color:#dc3232;">Not created yet.</span> Click "Generate Hub Post" below.
                        <?php endif; ?>
                    </td>
                </tr>
                <tr>
                    <td style="padding:6px 12px;"><?php echo ( $cross_linked >= $total_posts * 0.5 ) ? '✅' : '⚠️'; ?></td>
                    <td style="padding:6px 12px;"><strong>Cross-City Links</strong></td>
                    <td style="padding:6px 12px;"><?php echo $cross_linked; ?>/<?php echo $total_posts; ?> posts have "Related Cities" block</td>
                </tr>
                <tr>
                    <td style="padding:6px 12px;">✅</td>
                    <td style="padding:6px 12px;"><strong>Auto Back-Links</strong></td>
                    <td style="padding:6px 12px;">When a new city post is published, related existing posts are automatically updated with back-links to the new post.</td>
                </tr>
                <tr>
                    <td style="padding:6px 12px;">✅</td>
                    <td style="padding:6px 12px;"><strong>GPT Link Sanitizer</strong></td>
                    <td style="padding:6px 12px;">Strips hallucinated damalion.com URLs (non-English slugs, invented paths, /blog/ links). Only verified allowlist survives.</td>
                </tr>
            </table>
            <p style="margin-top:12px;">
                <button class="button button-primary" id="dba-shub-create-hub" <?php echo $hub_ok ? 'disabled style="opacity:0.5;"' : ''; ?>>✨ Generate Hub Post</button>
                &nbsp;
                <button class="button" id="dba-shub-orphan-audit">🔗 Fix All Orphan Posts (<?php echo $orphan_count; ?>)</button>
            </p>
        </div>

        <!-- ══ INBOUND LINK SCANNER — PageRank from rest of blog ══ -->
        <?php
        $inbound_stats = array( 'posts_with_inbound_links' => 0, 'total_inbound_links' => 0, 'link_targets' => 0 );
        if ( class_exists( 'DBA_Startup_Hub_Inbound' ) ) {
            $inbound_stats = DBA_Startup_Hub_Inbound::get_instance()->get_scan_stats();
        }
        $url_pats = class_exists( 'DBA_Startup_Hub_Inbound' ) ? DBA_Startup_Hub_Inbound::get_url_patterns() : array();
        ?>
        <div class="postbox" style="padding:15px;margin-bottom:20px;background:#e8f4fd;border-color:#b8daff;">
            <h2 style="margin-top:0;">📍 Inbound Link Scanner — PageRank from rest of blog</h2>
            <p>Scans the <strong>entire site</strong> — all posts, all pages, all WPML languages — and auto-links U.S. city name mentions and startup keywords to Startup Hub articles.</p>
            <p style="color:#444;font-size:13px;">
                <strong>Tier 1</strong> — WPML EN language posts/pages &nbsp;→&nbsp;
                <strong>Tier 2</strong> — URLs containing
                "<?php echo implode( '", "', array_slice( $url_pats, 0, 8 ) ); ?>"…
                &nbsp;→&nbsp;
                <strong>Tier 3</strong> — Everything else on the site.
                Max 3 links per post. City names &lt; 4 chars skipped. Hub post keywords also matched.
            </p>
            <?php if ( $inbound_stats['total_inbound_links'] > 0 ) : ?>
            <p style="background:#d4edda;padding:6px 12px;border-radius:4px;display:inline-block;">
                ✅ <strong><?php echo $inbound_stats['posts_with_inbound_links']; ?></strong> posts linked
                (<strong><?php echo $inbound_stats['total_inbound_links']; ?></strong> total inbound links,
                <strong><?php echo $inbound_stats['link_targets']; ?></strong> targets available)
            </p>
            <?php endif; ?>
            <p>
                <button class="button button-primary" id="dba-shub-inbound-scan" style="background:#0073aa;border-color:#006799;">🔗 Scan &amp; Link</button>
                &nbsp;
                <button class="button" id="dba-shub-inbound-force">🔄 Force Re-scan</button>
                &nbsp;
                <button class="button" id="dba-shub-inbound-strip" style="color:#dc3232;border-color:#dc3232;">🗑 Strip All Inbound Links</button>
            </p>
            <div id="dba-shub-inbound-progress" style="display:none;margin-top:12px;">
                <div style="background:#f0f0f1;border:1px solid #c3c4c7;border-radius:4px;overflow:hidden;height:28px;position:relative;">
                    <div id="dba-shub-inbound-bar" style="background:linear-gradient(90deg,#0073aa,#00a0d2);height:100%;width:0%;transition:width 0.4s ease;"></div>
                    <span id="dba-shub-inbound-pct" style="position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font-weight:bold;font-size:13px;color:#1d2327;">0%</span>
                </div>
                <p id="dba-shub-inbound-detail" style="color:#555;margin-top:5px;font-size:13px;"></p>
            </div>
            <div id="dba-shub-inbound-result" style="display:none;margin-top:10px;padding:10px;background:#fff;border:1px solid #ccc;border-radius:4px;"></div>
        </div>

        <!-- ══ GENERATE CONTROLS ══ -->
        <div class="postbox" style="padding:15px;margin-bottom:20px;">
            <h2 style="margin-top:0;">⚡ Generate</h2>
            <p>
                <button class="button button-primary button-hero" id="dba-shub-gen-single">▶ Generate 1 Post Now</button>
                &nbsp;
                <button class="button" id="dba-shub-gen-batch">🔄 Run Full Batch (<?php echo intval( $settings['posts_per_run'] ?? 1 ); ?> posts)</button>
            </p>
            <div id="dba-shub-progress-wrap" style="display:none;margin-top:15px;">
                <div style="background:#f0f0f1;border:1px solid #c3c4c7;border-radius:4px;overflow:hidden;height:28px;position:relative;">
                    <div id="dba-shub-progress-bar" style="background:#2271b1;height:100%;width:0%;transition:width 0.5s;"></div>
                    <span id="dba-shub-progress-text" style="position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font-weight:bold;font-size:13px;color:#1d2327;">0%</span>
                </div>
                <p id="dba-shub-progress-detail" style="color:#666;margin-top:5px;"></p>
            </div>
        </div>

        <!-- ══ SETTINGS FORM ══ -->
        <form method="post" action="options.php">
            <?php settings_fields( $opt . '_group' ); ?>

            <!-- Core Settings -->
            <div class="postbox" style="padding:15px;margin-bottom:20px;">
                <h2 style="margin-top:0;">⚙️ Settings</h2>
                <table class="form-table">
                    <tr><th>Enable</th>
                        <td><label><input type="checkbox" name="<?php echo $opt; ?>[enabled]" value="1" <?php checked( $settings['enabled'] ?? false ); ?>> Enable automatic daily generation</label></td>
                    </tr>
                    <tr><th>Posts per run</th>
                        <td><input type="number" name="<?php echo $opt; ?>[posts_per_run]" value="<?php echo intval( $settings['posts_per_run'] ?? 1 ); ?>" min="1" max="5" style="width:60px;"></td>
                    </tr>
                    <tr><th>Post status</th>
                        <td><select name="<?php echo $opt; ?>[post_status]">
                            <option value="publish" <?php selected( $settings['post_status'] ?? 'publish', 'publish' ); ?>>Publish</option>
                            <option value="draft" <?php selected( $settings['post_status'] ?? '', 'draft' ); ?>>Draft (review first)</option>
                        </select></td>
                    </tr>
                    <tr><th>Author ID</th>
                        <td><input type="number" name="<?php echo $opt; ?>[author_id]" value="<?php echo intval( $settings['author_id'] ?? 1 ); ?>" min="1" style="width:80px;"></td>
                    </tr>
                    <tr><th>Posting days</th>
                        <td><?php
                            $all_days = array( 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday' );
                            $active_days = $settings['posting_days'] ?? $config['default_posting_days'];
                            foreach ( $all_days as $day ) : ?>
                                <label style="margin-right:10px;">
                                    <input type="checkbox" name="<?php echo $opt; ?>[posting_days][]" value="<?php echo $day; ?>" <?php checked( in_array( $day, $active_days ) ); ?>>
                                    <?php echo ucfirst( substr( $day, 0, 3 ) ); ?>
                                </label>
                            <?php endforeach; ?>
                        </td>
                    </tr>
                </table>
                <?php submit_button( 'Save Settings' ); ?>
            </div>

            <!-- ══ ARTICLE SETTINGS (GeoBot-style) ══ -->
            <div class="postbox" style="padding:15px;margin-bottom:20px;">
                <h2 style="margin-top:0;">📝 Article Settings</h2>
                <table class="form-table">
                    <tr>
                        <th style="color:#0073aa;font-weight:bold;">Word Count Range</th>
                        <td>
                            <input type="number" name="<?php echo $opt; ?>[word_count_min]" value="<?php echo intval( $settings['word_count_min'] ?? 1000 ); ?>" min="500" max="3000" style="width:80px;">
                            <span style="margin:0 6px;">to</span>
                            <input type="number" name="<?php echo $opt; ?>[word_count_max]" value="<?php echo intval( $settings['word_count_max'] ?? 1800 ); ?>" min="500" max="5000" style="width:80px;">
                            <span style="margin-left:8px;">words</span>
                            <p class="description" style="background:#e8f0fe;padding:4px 8px;border-radius:3px;display:inline-block;margin-top:4px;">Default: 1000–1800 (target ~1400). The AI aims for this range; the validator enforces minimum. Max is a soft warning.</p>
                        </td>
                    </tr>
                    <tr>
                        <th style="color:#0073aa;font-weight:bold;">Require Subtitle</th>
                        <td>
                            <label style="background:#e8f0fe;padding:4px 10px;border-radius:3px;">
                                <input type="checkbox" name="<?php echo $opt; ?>[require_subtitle]" value="1" <?php checked( $settings['require_subtitle'] ?? true ); ?>>
                                Every article must include a subtitle (H2 or &lt;p class="subtitle"&gt;) below the H1 for readability &amp; SEO
                            </label>
                            <p class="description" style="background:#e8f0fe;padding:4px 8px;border-radius:3px;display:inline-block;margin-top:4px;">Improves readability scores and provides a secondary hook for readers. Enabled by default.</p>
                        </td>
                    </tr>
                    <tr>
                        <th style="color:#0073aa;font-weight:bold;">Company Link Rule</th>
                        <td>
                            <label style="background:#e8f0fe;padding:4px 10px;border-radius:3px;">
                                <input type="checkbox" name="<?php echo $opt; ?>[require_company_link]" value="1" <?php checked( $settings['require_company_link'] ?? true ); ?>>
                                Startup name must link to its official website
                            </label>
                            <p class="description" style="background:#e8f0fe;padding:4px 8px;border-radius:3px;display:inline-block;margin-top:4px;">Already enforced — the &lt;a&gt; tag wraps the startup name pointing to the company's official URL.</p>
                        </td>
                    </tr>
                    <tr>
                        <th>State/City .gov Link</th>
                        <td>
                            <label><input type="checkbox" name="<?php echo $opt; ?>[require_gov_link]" value="1" <?php checked( $settings['require_gov_link'] ?? false ); ?>>
                                First mention of the state or city must link to its official .gov website
                            </label>
                            <p class="description">Example: "New York" → <code>&lt;a href="https://www.ny.gov"&gt;New York&lt;/a&gt;</code></p>
                        </td>
                    </tr>
                    <tr>
                        <th>Call to Action (CTA)</th>
                        <td>
                            <label style="margin-bottom:12px;display:block;">
                                <input type="checkbox" name="<?php echo $opt; ?>[cta_enabled]" value="1" <?php checked( $cta_enabled ); ?> id="dba-shub-cta-enabled">
                                Append CTA block at the end of every article
                            </label>

                            <div id="dba-shub-cta-fields" style="margin-top:10px;">
                                <label style="display:block;margin-bottom:4px;font-weight:600;">CTA text:</label>
                                <textarea name="<?php echo $opt; ?>[cta_text]" rows="3" style="width:100%;max-width:600px;" id="dba-shub-cta-text"><?php echo esc_textarea( $cta_text ); ?></textarea>

                                <label style="display:block;margin:10px 0 4px;font-weight:600;">CTA link text:</label>
                                <input type="text" name="<?php echo $opt; ?>[cta_link_text]" value="<?php echo esc_attr( $cta_link_text ); ?>" id="dba-shub-cta-link-text" style="width:100%;max-width:400px;">

                                <label style="display:block;margin:10px 0 4px;font-weight:600;">CTA link URL:</label>
                                <input type="url" name="<?php echo $opt; ?>[cta_link_url]" value="<?php echo esc_attr( $cta_link_url ); ?>" id="dba-shub-cta-link-url" style="width:100%;max-width:400px;">

                                <div style="background:#f8f8f8;border:1px solid #ddd;border-radius:4px;padding:12px 16px;margin-top:12px;max-width:600px;">
                                    <strong style="display:block;margin-bottom:6px;">Preview:</strong>
                                    <div id="dba-shub-cta-preview">
                                        <em><?php echo esc_html( $cta_text ); ?></em><br>
                                        <a href="<?php echo esc_url( $cta_link_url ); ?>" target="_blank"><?php echo esc_html( $cta_link_text ); ?></a>
                                    </div>
                                </div>
                            </div>

                            <details style="margin-top:12px;">
                                <summary style="cursor:pointer;color:#666;font-size:12px;">⚙️ Advanced: Raw HTML CTA override</summary>
                                <textarea name="<?php echo $opt; ?>[cta_html_override]" rows="4" style="width:100%;max-width:600px;margin-top:8px;" placeholder="Leave empty to use fields above"><?php echo esc_textarea( $settings['cta_html_override'] ?? '' ); ?></textarea>
                                <p class="description">Paste raw HTML to completely override the CTA. Leave empty to use the structured fields above.</p>
                            </details>
                        </td>
                    </tr>
                </table>
                <?php submit_button( 'Save Article Settings' ); ?>
            </div>
        </form>

        <!-- ══ STATUS DASHBOARD ══ -->
        <div class="postbox" style="padding:15px;margin-bottom:20px;">
            <h2 style="margin-top:0;">📊 Status</h2>
            <table class="widefat" style="max-width:600px;">
                <tr><td><strong>Module</strong></td><td><?php echo ( $settings['enabled'] ?? false ) ? '✅ Enabled' : '⏸ Disabled'; ?></td></tr>
                <tr><td><strong>Total posts</strong></td><td><?php echo $total_posts; ?></td></tr>
                <tr><td><strong>Hub page</strong></td><td>
                    <?php if ( $hub_ok ) : ?>
                        <a href="<?php echo get_permalink( $hub_id ); ?>" target="_blank">#<?php echo $hub_id; ?> — <?php echo esc_html( get_the_title( $hub_id ) ); ?></a>
                    <?php else : ?>
                        <em>Not created</em>
                    <?php endif; ?>
                </td></tr>
                <tr><td><strong>Posting days</strong></td><td><?php echo DBA_Startup_Hub_Scheduler::get_posting_days_string(); ?></td></tr>
                <tr><td><strong>Next run</strong></td><td><?php echo DBA_Startup_Hub_Scheduler::get_next_run_info(); ?></td></tr>
                <tr><td><strong>Last run</strong></td>
                    <td><?php if ( ! empty( $last_run ) ) : ?>
                            <?php echo esc_html( $last_run['timestamp'] ?? '—' ); ?> — "<?php echo esc_html( $last_run['title'] ?? '—' ); ?>"
                            (<?php echo esc_html( $last_run['category'] ?? '' ); ?> / <?php echo esc_html( $last_run['city'] ?? '' ); ?>)
                        <?php else : ?>Never<?php endif; ?>
                    </td>
                </tr>
                <tr><td><strong>Categories</strong></td><td><?php echo count( $categories ); ?> verticals (FinTech weighted 3×)</td></tr>
                <tr><td><strong>Cities</strong></td><td><?php echo $total_cities; ?> cities in <?php echo count( array_unique( array_column( $cities, 'state' ) ) ); ?> states</td></tr>
            </table>
        </div>

        <!-- ══ CITIES LIST ══ -->
        <div class="postbox" style="padding:15px;margin-bottom:20px;">
            <h2 style="margin-top:0;">🗺️ Cities (<?php echo $total_cities; ?>)</h2>
            <table class="widefat striped" style="max-width:900px;">
                <thead><tr><th>City</th><th>State</th><th>Ecosystem Focus</th><th>Weight</th><th style="text-align:center;">Written</th></tr></thead>
                <tbody>
                <?php foreach ( $cities as $c ) : ?>
                    <tr>
                        <td><strong><?php echo esc_html( $c['city'] ); ?></strong></td>
                        <td><?php echo esc_html( $c['state'] ); ?></td>
                        <td><?php echo esc_html( $c['ecosystem'] ?? '' ); ?></td>
                        <td><?php echo intval( $c['weight'] ?? 1 ); ?></td>
                        <td style="text-align:center;"><?php echo isset( $cities_covered[ $c['city'] ] ) ? '✅' : '—'; ?></td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
            <p style="margin-top:10px;">
                <button class="button" onclick="document.getElementById('dba-shub-import-area').style.display='block';this.style.display='none';">➕ Import Cities</button>
                <button class="button" id="dba-shub-reset-cities">🔄 Reset to Defaults</button>
            </p>
            <div id="dba-shub-import-area" style="display:none;margin-top:10px;">
                <p>Paste cities (one per line): <code>City, State, Ecosystem, Weight</code></p>
                <textarea id="dba-shub-cities-text" rows="6" cols="80" placeholder="Boulder, Colorado, CleanTech SaaS, 1&#10;Pittsburgh, Pennsylvania, AI Robotics, 1"></textarea><br>
                <button class="button button-primary" id="dba-shub-import-btn">Import (Append)</button>
                <button class="button" id="dba-shub-import-replace-btn">Import (Replace All)</button>
            </div>
        </div>

        <!-- ══ CATEGORIES ══ -->
        <div class="postbox" style="padding:15px;margin-bottom:20px;">
            <h2 style="margin-top:0;">📁 Categories (<?php echo count( $categories ); ?> verticals)</h2>
            <table class="widefat striped" style="max-width:800px;">
                <thead><tr><th>Category</th><th>Weight</th></tr></thead>
                <tbody>
                <?php foreach ( $categories as $slug => $cat ) : ?>
                    <tr>
                        <td><strong><?php echo esc_html( $cat['name'] ); ?></strong></td>
                        <td><?php echo intval( $cat['weight'] ); ?>× <?php echo $cat['weight'] >= 2 ? '⭐' : ''; ?></td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
        </div>

        </div><!-- .wrap -->

        <script>
        jQuery(function($){
            var nonce = '<?php echo $nonce; ?>';
            var pollTimer = null;

            function startPolling() {
                $('#dba-shub-progress-wrap').show();
                pollTimer = setInterval(function(){
                    $.post(ajaxurl, { action: 'dba_startup_hub_get_progress', nonce: nonce }, function(r){
                        if (!r.success) return;
                        var d = r.data;
                        var pct = d.overall_percent || d.step_percent || 0;
                        $('#dba-shub-progress-bar').css('width', pct + '%');
                        $('#dba-shub-progress-text').text(pct + '%');
                        $('#dba-shub-progress-detail').text('Step ' + (d.current_step||0) + '/14: ' + (d.current_step_name||'') + ' — ' + (d.current_detail||''));
                    });
                }, 2000);
            }
            function stopPolling() { if (pollTimer) clearInterval(pollTimer); pollTimer = null; }

            // Generate single
            $('#dba-shub-gen-single').on('click', function(){
                if (!confirm('Generate 1 Startup Hub post now?')) return;
                var btn = $(this); btn.prop('disabled', true).text('⏳ Generating…');
                startPolling();
                $.post(ajaxurl, { action: 'dba_startup_hub_generate_single', nonce: nonce }, function(r){
                    stopPolling(); btn.prop('disabled', false).text('▶ Generate 1 Post Now');
                    if (r.success) { alert('✅ ' + r.data.message); location.reload(); }
                    else { alert('❌ Error: ' + (r.data?.message || 'Unknown error')); }
                }).fail(function(){ stopPolling(); btn.prop('disabled', false).text('▶ Generate 1 Post Now'); alert('Request failed'); });
            });

            // Generate batch
            $('#dba-shub-gen-batch').on('click', function(){
                if (!confirm('Run a full Startup Hub batch?')) return;
                var btn = $(this); btn.prop('disabled', true).text('⏳ Running batch…');
                startPolling();
                $.post(ajaxurl, { action: 'dba_startup_hub_generate_batch', nonce: nonce }, function(r){
                    stopPolling(); btn.prop('disabled', false).text('🔄 Run Full Batch');
                    if (r.success) { alert('✅ ' + r.data.message); location.reload(); }
                    else { alert('❌ Error: ' + (r.data?.message || 'Unknown error')); }
                }).fail(function(){ stopPolling(); btn.prop('disabled', false); alert('Request failed'); });
            });

            // Create hub page
            $(document).on('click', '#dba-shub-create-hub:not(:disabled)', function(){
                var btn = $(this); btn.prop('disabled', true).text('⏳ Creating…');
                $.post(ajaxurl, { action: 'dba_startup_hub_create_hub_page', nonce: nonce }, function(r){
                    if (r.success) { alert('✅ Hub page created!'); location.reload(); }
                    else { alert('❌ ' + (r.data?.message || r.data || 'Error')); btn.prop('disabled', false).text('✨ Generate Hub Post'); }
                });
            });

            // Orphan audit
            $('#dba-shub-orphan-audit').on('click', function(){
                var btn = $(this); btn.prop('disabled', true).text('⏳ Running audit…');
                $.post(ajaxurl, { action: 'dba_startup_hub_orphan_audit', nonce: nonce }, function(r){
                    btn.prop('disabled', false).text('🔗 Fix All Orphan Posts');
                    if (r.success) { alert('✅ ' + r.data.message); location.reload(); }
                    else { alert('❌ ' + (r.data || 'Error')); }
                });
            });

            // Reset rotation
            $('#dba-shub-reset-rotation').on('click', function(){
                if (!confirm('Reset all city/category rotation history?')) return;
                var btn = $(this); btn.prop('disabled', true).text('⏳ Resetting…');
                $.post(ajaxurl, { action: 'dba_startup_hub_import_cities', nonce: nonce, cities_text: '__RESET_ROTATION__', mode: 'reset_rotation' }, function(r){
                    btn.prop('disabled', false).text('🔄 Reset Rotation');
                    if (r.success) { alert('✅ Rotation reset!'); location.reload(); }
                    else { alert('❌ ' + (r.data?.message || r.data || 'Error')); }
                });
            });

            // Import cities
            function importCities(mode) {
                var text = $('#dba-shub-cities-text').val();
                if (!text.trim()) { alert('Paste city data first'); return; }
                $.post(ajaxurl, { action: 'dba_startup_hub_import_cities', nonce: nonce, cities_text: text, mode: mode }, function(r){
                    if (r.success) { alert('✅ Imported ' + r.data.imported + ' cities (' + r.data.mode + ')'); location.reload(); }
                    else { alert('❌ ' + (r.data?.message || r.data || 'Error')); }
                });
            }
            $('#dba-shub-import-btn').on('click', function(){ importCities('append'); });
            $('#dba-shub-import-replace-btn').on('click', function(){
                if (confirm('Replace ALL cities? This removes existing ones.')) importCities('replace');
            });
            $('#dba-shub-reset-cities').on('click', function(){
                if (confirm('Reset to default 15 U.S. cities?')) {
                    $.post(ajaxurl, { action: 'dba_startup_hub_import_cities', nonce: nonce, cities_text: '__RESET__', mode: 'reset' }, function(r){
                        if (r.success) { alert('✅ Reset to defaults'); location.reload(); }
                    });
                }
            });

            // CTA live preview
            function updateCtaPreview() {
                var text = $('#dba-shub-cta-text').val() || '';
                var linkText = $('#dba-shub-cta-link-text').val() || '';
                var linkUrl  = $('#dba-shub-cta-link-url').val() || '#';
                var safe = function(s){ return $('<span>').text(s).html(); };
                $('#dba-shub-cta-preview').html('<em>' + safe(text) + '</em><br><a href="' + safe(linkUrl) + '" target="_blank">' + safe(linkText) + '</a>');
            }
            $('#dba-shub-cta-text, #dba-shub-cta-link-text, #dba-shub-cta-link-url').on('input', updateCtaPreview);

            // Toggle CTA fields
            function toggleCtaFields() {
                var on = $('#dba-shub-cta-enabled').is(':checked');
                $('#dba-shub-cta-fields').css('opacity', on ? 1 : 0.4);
            }
            $('#dba-shub-cta-enabled').on('change', toggleCtaFields);
            toggleCtaFields();

            // ── Inbound Link Scanner with Progress Bar ──
            var inboundPollTimer = null;
            function showInboundResult(html) {
                $('#dba-shub-inbound-result').html(html).show();
            }
            function startInboundPolling() {
                $('#dba-shub-inbound-progress').show();
                $('#dba-shub-inbound-result').hide();
                inboundPollTimer = setInterval(function(){
                    $.post(ajaxurl, { action: 'dba_shub_inbound_progress', nonce: nonce }, function(r){
                        if (!r.success) return;
                        var d = r.data;
                        var pct = d.percent || 0;
                        $('#dba-shub-inbound-bar').css('width', pct + '%');
                        $('#dba-shub-inbound-pct').text(pct + '%');
                        $('#dba-shub-inbound-detail').text(d.detail || '');
                        if (d.phase === 'done') stopInboundPolling();
                    });
                }, 1500);
            }
            function stopInboundPolling() {
                if (inboundPollTimer) clearInterval(inboundPollTimer);
                inboundPollTimer = null;
            }
            function resetInboundBar() {
                $('#dba-shub-inbound-bar').css('width', '0%');
                $('#dba-shub-inbound-pct').text('0%');
                $('#dba-shub-inbound-detail').text('');
            }
            function disableInboundBtns(on) {
                $('#dba-shub-inbound-scan, #dba-shub-inbound-force, #dba-shub-inbound-strip').prop('disabled', on);
            }

            $('#dba-shub-inbound-scan').on('click', function(){
                resetInboundBar(); disableInboundBtns(true);
                var btn = $(this); btn.text('⏳ Scanning…');
                startInboundPolling();
                $.post(ajaxurl, { action: 'dba_shub_inbound_scan', nonce: nonce, force_rescan: 0 }, function(r){
                    stopInboundPolling(); disableInboundBtns(false); btn.text('🔗 Scan & Link');
                    if (r.success) {
                        var d = r.data;
                        $('#dba-shub-inbound-bar').css('width', '100%');
                        $('#dba-shub-inbound-pct').text('100%');
                        showInboundResult(
                            '✅ Scanned <strong>' + d.scanned + '</strong> posts '
                            + '(T1:' + d.tier1_scanned + ' T2:' + d.tier2_scanned + ' T3:' + d.tier3_scanned + '). '
                            + 'Linked <strong>' + d.linked + '</strong> posts, injected <strong>' + d.links_injected + '</strong> links '
                            + '(' + d.targets_count + ' targets available).'
                        );
                    } else { showInboundResult('❌ ' + (r.data?.error || r.data || 'Error')); }
                }).fail(function(){ stopInboundPolling(); disableInboundBtns(false); btn.text('🔗 Scan & Link'); showInboundResult('❌ Request failed / timed out'); });
            });

            $('#dba-shub-inbound-force').on('click', function(){
                if (!confirm('Force re-scan? This strips existing inbound links and re-scans all posts.')) return;
                resetInboundBar(); disableInboundBtns(true);
                var btn = $(this); btn.text('⏳ Re-scanning…');
                startInboundPolling();
                $.post(ajaxurl, { action: 'dba_shub_inbound_scan', nonce: nonce, force_rescan: 1 }, function(r){
                    stopInboundPolling(); disableInboundBtns(false); btn.text('🔄 Force Re-scan');
                    if (r.success) {
                        var d = r.data;
                        $('#dba-shub-inbound-bar').css('width', '100%');
                        $('#dba-shub-inbound-pct').text('100%');
                        showInboundResult(
                            '✅ Force re-scan complete. Scanned <strong>' + d.scanned + '</strong> posts. '
                            + 'Linked <strong>' + d.linked + '</strong>, injected <strong>' + d.links_injected + '</strong> links.'
                        );
                    } else { showInboundResult('❌ ' + (r.data?.error || r.data || 'Error')); }
                }).fail(function(){ stopInboundPolling(); disableInboundBtns(false); btn.text('🔄 Force Re-scan'); showInboundResult('❌ Request failed / timed out'); });
            });

            $('#dba-shub-inbound-strip').on('click', function(){
                if (!confirm('⚠️ Strip ALL Startup Hub inbound links from the entire site? This is reversible by re-scanning.')) return;
                disableInboundBtns(true);
                var btn = $(this); btn.text('⏳ Stripping…');
                $('#dba-shub-inbound-progress').show();
                $('#dba-shub-inbound-bar').css('width', '50%');
                $('#dba-shub-inbound-pct').text('…');
                $('#dba-shub-inbound-detail').text('Removing inbound links from all posts…');
                $.post(ajaxurl, { action: 'dba_shub_inbound_strip', nonce: nonce }, function(r){
                    disableInboundBtns(false); btn.text('🗑 Strip All Inbound Links');
                    $('#dba-shub-inbound-bar').css('width', '100%');
                    $('#dba-shub-inbound-pct').text('100%');
                    if (r.success) {
                        showInboundResult('✅ Stripped links from <strong>' + r.data.posts_cleaned + '</strong> posts. Cleared <strong>' + r.data.meta_removed + '</strong> meta entries.');
                    } else { showInboundResult('❌ ' + (r.data || 'Error')); }
                }).fail(function(){ disableInboundBtns(false); btn.text('🗑 Strip All Inbound Links'); showInboundResult('❌ Request failed'); });
            });
        });
        </script>
        <?php
    }

    /* =================================================================
     *  AJAX HANDLERS
     * ================================================================= */

    public function ajax_import_cities() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Permission denied' );

        $raw  = wp_unslash( $_POST['cities_text'] ?? '' );
        $mode = sanitize_key( $_POST['mode'] ?? 'append' );

        if ( trim( $raw ) === '__RESET__' ) {
            delete_option( 'dba_startup_hub_cities' );
            wp_send_json_success( array( 'imported' => count( DBA_Startup_Hub_Registry::get_default_cities() ), 'mode' => 'reset' ) );
        }

        if ( trim( $raw ) === '__RESET_ROTATION__' || $mode === 'reset_rotation' ) {
            if ( class_exists( 'DBA_Startup_Hub_Dedupe' ) && method_exists( 'DBA_Startup_Hub_Dedupe', 'reset_rotation' ) ) {
                DBA_Startup_Hub_Dedupe::reset_rotation();
            } else {
                // Manual fallback: clear the transients
                delete_transient( 'dba_startup_hub_today_categories' );
                delete_transient( 'dba_startup_hub_today_cities' );
            }
            wp_send_json_success( array( 'imported' => 0, 'mode' => 'reset_rotation' ) );
        }

        if ( empty( trim( $raw ) ) ) wp_send_json_error( 'No cities provided.' );

        $lines  = preg_split( '/[\r\n]+/', $raw, -1, PREG_SPLIT_NO_EMPTY );
        $parsed = array();

        foreach ( $lines as $line ) {
            $line = trim( $line );
            if ( $line === '' ) continue;
            if ( strpos( $line, "\t" ) !== false ) { $parts = explode( "\t", $line ); }
            elseif ( strpos( $line, '|' ) !== false ) { $parts = explode( '|', $line ); }
            else { $parts = explode( ',', $line ); }
            $parts = array_map( 'trim', $parts );
            $parsed[] = array(
                'city'      => $parts[0] ?? '',
                'state'     => $parts[1] ?? '',
                'ecosystem' => $parts[2] ?? '',
                'weight'    => max( 1, intval( $parts[3] ?? 1 ) ),
            );
        }

        $parsed = array_filter( $parsed, function( $c ) { return ! empty( $c['city'] ); } );
        if ( empty( $parsed ) ) wp_send_json_error( 'No valid cities found.' );

        if ( $mode === 'append' ) {
            $existing = get_option( 'dba_startup_hub_cities', array() );
            $existing_names = array_map( function( $c ) { return strtolower( $c['city'] ); }, $existing );
            $added = 0;
            foreach ( $parsed as $city ) {
                if ( ! in_array( strtolower( $city['city'] ), $existing_names, true ) ) {
                    $existing[] = $city;
                    $existing_names[] = strtolower( $city['city'] );
                    $added++;
                }
            }
            update_option( 'dba_startup_hub_cities', $existing, false );
            wp_send_json_success( array( 'imported' => $added, 'mode' => 'append' ) );
        } else {
            update_option( 'dba_startup_hub_cities', $parsed, false );
            wp_send_json_success( array( 'imported' => count( $parsed ), 'mode' => 'replace' ) );
        }
    }

    public function ajax_create_hub_page() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Permission denied' );

        $config = DBA_Startup_Hub_Registry::get_config();
        $existing = get_option( $config['hub_page_option'], 0 );
        if ( $existing && get_post_status( $existing ) && get_post_status( $existing ) !== 'trash' ) {
            wp_send_json_error( array( 'message' => 'Hub page already exists: #' . $existing ) );
        }

        $cta = DBA_Startup_Hub_Registry::get_partnership_cta();

        $content = '<p>This section gathers our in-depth analyses of startup ecosystems across major U.S. cities. '
            . 'We cover 15 technology verticals — from FinTech and AI to CleanTech and Web3 — in the most dynamic '
            . 'innovation hubs across California, New York, Texas, Massachusetts, Florida, and beyond.</p>'
            . "\n\n<h2>Our Startup Analyses</h2>\n\n"
            . DBA_Startup_Hub_Anti_Orphan::HUB_LIST_MARKER
            . "\n\n<p>New analyses are published regularly throughout the week.</p>"
            . "\n\n<h2>Why the U.S. Startup Ecosystem</h2>\n\n"
            . '<p>The United States remains the world\'s largest venture capital market. Damalion helps international entrepreneurs '
            . 'and investors access corporate structuring, regulatory compliance, and operational guidance tailored to '
            . 'the U.S. market.</p>'
            . "\n\n" . $cta;

        $post_id = wp_insert_post( array(
            'post_title'   => 'U.S. Startup Ecosystem: Industry Analysis by City and Sector',
            'post_name'    => 'us-startup-ecosystem-analysis',
            'post_content' => wp_kses_post( $content ),
            'post_excerpt' => 'Comprehensive guide to U.S. startup investment opportunities across 15 tech verticals and 10+ innovation hubs.',
            'post_status'  => 'publish',
            'post_type'    => 'post',
            'post_author'  => get_current_user_id() ?: 1,
        ) );

        if ( is_wp_error( $post_id ) ) wp_send_json_error( $post_id->get_error_message() );

        $cat_term = get_term_by( 'slug', 'smb-growth-hub', 'category' );
        if ( ! $cat_term ) {
            $r = wp_insert_term( 'SMB Growth Hub', 'category', array( 'slug' => 'smb-growth-hub' ) );
            $cat_id = is_wp_error( $r ) ? 1 : $r['term_id'];
        } else {
            $cat_id = $cat_term->term_id;
        }
        wp_set_post_categories( $post_id, array( $cat_id ), false );

        update_post_meta( $post_id, '_dba_startup_hub_auto_created', current_time( 'mysql' ) );
        update_post_meta( $post_id, '_dba_startup_hub_hub_post', '1' );
        update_post_meta( $post_id, '_dba_auto_created', current_time( 'mysql' ) );
        update_post_meta( $post_id, '_et_pb_use_builder', 'off' );
        update_post_meta( $post_id, '_yoast_wpseo_focuskw', 'US startup ecosystem' );
        update_post_meta( $post_id, '_yoast_wpseo_title', 'U.S. Startup Ecosystem Analysis | Damalion' );
        update_post_meta( $post_id, '_yoast_wpseo_metadesc', 'Explore U.S. startup ecosystems across 15 tech verticals and 10+ innovation hubs. FinTech, AI, SaaS, and more.' );

        update_option( $config['hub_page_option'], $post_id, false );

        wp_send_json_success( array( 'post_id' => $post_id, 'title' => get_the_title( $post_id ), 'message' => 'Hub page created!' ) );
    }

    public function ajax_orphan_audit() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Permission denied' );

        $anti_orphan = DBA_Startup_Hub_Anti_Orphan::get_instance();
        $result = $anti_orphan->weekly_audit();

        $fixed = is_array( $result ) ? ( $result['fixed'] ?? 0 ) : 0;
        wp_send_json_success( array( 'message' => "Orphan audit complete. Fixed {$fixed} posts. Check error_log for details." ) );
    }
}
