<?php
/**
 * DBA_Anti_Orphan_Admin v2.19.2 — Multi-language selection
 *
 * Layout:
 *   1. Command Center (scan/stop/reset/undo/fix-everything)
 *   2. Stats cards
 *   3. Language table WITH CHECKBOXES for selection
 *   4. Per-language orphan/weak lists
 *   5. Injection log + Settings
 */
if ( ! defined( 'ABSPATH' ) ) exit;

class DBA_Anti_Orphan_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, 'menu' ), 99 );
        add_action( 'wp_ajax_dba_ao_run_scan',    array( $this, 'ajax_run_scan' ) );
        add_action( 'wp_ajax_dba_ao_progress',     array( $this, 'ajax_progress' ) );
        add_action( 'wp_ajax_dba_ao_fix_orphan',   array( $this, 'ajax_fix_orphan' ) );
        add_action( 'wp_ajax_dba_ao_fix_all',      array( $this, 'ajax_fix_all' ) );
        add_action( 'wp_ajax_dba_ao_rollback',     array( $this, 'ajax_rollback' ) );
        add_action( 'wp_ajax_dba_ao_rollback_all', array( $this, 'ajax_rollback_all' ) );
        add_action( 'wp_ajax_dba_ao_rollback_date', array( $this, 'ajax_rollback_date' ) );
        add_action( 'wp_ajax_dba_ao_stop_scan',    array( $this, 'ajax_stop_scan' ) );
        add_action( 'wp_ajax_dba_ao_reset',        array( $this, 'ajax_reset' ) );
        add_action( 'wp_ajax_dba_ao_save_settings',array( $this, 'ajax_save_settings' ) );
        add_action( 'wp_ajax_dba_ao_get_results',  array( $this, 'ajax_get_results' ) );
        add_action( 'dba_anti_orphan_weekly_scan',  array( $this, 'cron_weekly_scan' ) );
        add_action( 'dba_anti_orphan_auto_fix',     array( $this, 'cron_auto_fix' ) );
        if ( ! wp_next_scheduled( 'dba_anti_orphan_weekly_scan' ) )
            wp_schedule_event( time() + DAY_IN_SECONDS, 'weekly', 'dba_anti_orphan_weekly_scan' );
    }

    public function menu() {
        add_submenu_page( 'dba-settings', 'Anti-Orphan Center', '🔗 Anti-Orphan Center', 'manage_options', 'dba-anti-orphan', array( $this, 'page' ) );
    }

    /* ═══════════ AJAX ═══════════ */

    public function ajax_run_scan() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Forbidden' );
        @set_time_limit( 600 ); @ini_set( 'max_execution_time', '600' ); wp_raise_memory_limit( 'admin' );
        $language = sanitize_text_field( $_POST['language'] ?? '' );
        try {
            $result = DBA_Anti_Orphan_Scanner::run_scan( $language );
            if ( is_wp_error( $result ) ) wp_send_json_error( $result->get_error_message() );
            if ( ! is_array( $result ) ) wp_send_json_error( 'Unexpected: ' . gettype( $result ) );
            wp_send_json_success( $result );
        } catch ( \Throwable $e ) {
            wp_send_json_error( get_class($e) . ': ' . $e->getMessage() . ' in ' . basename($e->getFile()) . ':' . $e->getLine() );
        }
    }
    public function ajax_progress() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        wp_send_json_success( DBA_Anti_Orphan_Scanner::get_progress() );
    }
    public function ajax_stop_scan() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Forbidden' );
        DBA_Anti_Orphan_Scanner::request_stop();
        wp_send_json_success( 'Stop requested.' );
    }
    public function ajax_reset() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Forbidden' );
        DBA_Anti_Orphan_Scanner::reset_all();
        delete_option( DBA_Anti_Orphan_Injector::LOG_KEY );
        wp_send_json_success( 'Reset done.' );
    }
    public function ajax_fix_orphan() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Forbidden' );
        $post_id = intval( $_POST['post_id'] ?? 0 );
        $lang = sanitize_text_field( $_POST['language'] ?? 'en' );
        if ( ! $post_id ) wp_send_json_error( 'Invalid post ID.' );
        try {
            $settings = DBA_Anti_Orphan_Scanner::get_settings();
            wp_send_json_success( DBA_Anti_Orphan_Injector::fix_orphan( $post_id, $lang, $settings['max_links'] ) );
        } catch ( \Throwable $e ) {
            wp_send_json_error( $e->getMessage() . ' in ' . basename($e->getFile()) . ':' . $e->getLine() );
        }
    }
    public function ajax_fix_all() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Forbidden' );
        @set_time_limit( 600 );
        $lang = sanitize_text_field( $_POST['language'] ?? 'en' );
        try {
            $settings = DBA_Anti_Orphan_Scanner::get_settings();
            wp_send_json_success( DBA_Anti_Orphan_Injector::fix_all_orphans( $lang, $settings['max_links'], 30 ) );
        } catch ( \Throwable $e ) {
            wp_send_json_error( $e->getMessage() . ' in ' . basename($e->getFile()) . ':' . $e->getLine() );
        }
    }
    public function ajax_rollback() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Forbidden' );
        $post_id = intval( $_POST['post_id'] ?? 0 );
        if ( ! $post_id ) wp_send_json_error( 'Invalid post ID.' );
        try { wp_send_json_success( DBA_Anti_Orphan_Injector::rollback_orphan( $post_id ) ); }
        catch ( \Throwable $e ) { wp_send_json_error( $e->getMessage() ); }
    }
    public function ajax_rollback_all() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Forbidden' );
        @set_time_limit( 90 );

        global $wpdb;

        // Find ALL posts with injection meta
        $orphan_ids = $wpdb->get_col(
            "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_dba_anti_orphan_injected' LIMIT 50"
        );

        $total_remaining = (int) $wpdb->get_var(
            "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_dba_anti_orphan_injected'"
        );

        $rolled = 0; $failed = 0;
        foreach ( $orphan_ids as $oid ) {
            try {
                $r = DBA_Anti_Orphan_Injector::rollback_orphan( intval( $oid ) );
                if ( $r['success'] ) $rolled += $r['rolled_back_count']; else $failed++;
            } catch ( \Throwable $e ) { $failed++; }
        }

        $still_remaining = (int) $wpdb->get_var(
            "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_dba_anti_orphan_injected'"
        );

        // Only clear log when fully done
        if ( $still_remaining === 0 ) {
            delete_option( DBA_Anti_Orphan_Injector::LOG_KEY );
            // Clean orphaned donor meta
            $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE meta_key = '_dba_anti_orphan_donor'" );
        }

        wp_send_json_success( array(
            'rolled_back' => $rolled,
            'failed'      => $failed,
            'remaining'   => $still_remaining,
            'total_found' => $total_remaining,
            'done'        => ( $still_remaining === 0 ),
        ) );
    }
    public function ajax_rollback_date() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Forbidden' );
        @set_time_limit( 90 );
        $hours = max( 1, intval( $_POST['hours'] ?? 24 ) );
        try {
            wp_send_json_success( DBA_Anti_Orphan_Injector::rollback_by_date( $hours, 50 ) );
        } catch ( \Throwable $e ) {
            wp_send_json_error( $e->getMessage() );
        }
    }
    public function ajax_save_settings() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( 'Forbidden' );
        DBA_Anti_Orphan_Scanner::save_settings( array(
            'enabled'         => ! empty( $_POST['enabled'] ),
            'auto_fix'        => ! empty( $_POST['auto_fix'] ),
            'max_links'       => max( 1, min( 5, intval( $_POST['max_links'] ?? 2 ) ) ),
            'min_content_len' => max( 200, intval( $_POST['min_content_len'] ?? 500 ) ),
            'cron_schedule'   => sanitize_text_field( $_POST['cron_schedule'] ?? 'weekly' ),
            'email_report'    => ! empty( $_POST['email_report'] ),
            'email_address'   => sanitize_email( $_POST['email_address'] ?? '' ),
        ) );
        wp_send_json_success( 'Saved.' );
    }
    public function ajax_get_results() {
        check_ajax_referer( 'dba_admin_nonce', 'nonce' );
        wp_send_json_success( DBA_Anti_Orphan_Scanner::get_results() );
    }

    /* ═══════════ CRON ═══════════ */
    public function cron_weekly_scan() {
        $s = DBA_Anti_Orphan_Scanner::get_settings();
        if ( ! $s['enabled'] ) return;
        DBA_Anti_Orphan_Scanner::run_scan();
        if ( $s['auto_fix'] ) {
            foreach ( DBA_Anti_Orphan_Scanner::get_active_languages() as $lang )
                DBA_Anti_Orphan_Injector::fix_all_orphans( $lang, $s['max_links'], 30 );
        }
    }
    public function cron_auto_fix() {
        $s = DBA_Anti_Orphan_Scanner::get_settings();
        if ( ! $s['enabled'] || ! $s['auto_fix'] ) return;
        foreach ( DBA_Anti_Orphan_Scanner::get_active_languages() as $lang )
            DBA_Anti_Orphan_Injector::fix_all_orphans( $lang, $s['max_links'], 20 );
    }

    /* ═══════════════════════════════════════════════════════════════
     *  PAGE RENDER
     * ═══════════════════════════════════════════════════════════════ */
    public function page() {
        $results   = DBA_Anti_Orphan_Scanner::get_results();
        $settings  = DBA_Anti_Orphan_Scanner::get_settings();
        $log       = DBA_Anti_Orphan_Injector::get_log();
        $languages = DBA_Anti_Orphan_Scanner::get_active_languages();
        $stats     = isset( $results['stats'] ) ? $results['stats'] : null;
        $details   = isset( $results['details'] ) ? $results['details'] : array();
        $nonce     = wp_create_nonce( 'dba_admin_nonce' );

        // Count actual injected posts in DB (not just log)
        global $wpdb;
        $injected_count = (int) $wpdb->get_var(
            "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_dba_anti_orphan_injected'"
        );
        ?>
        <style>
        @keyframes ao-flip{0%{transform:rotate(0)}50%{transform:rotate(180deg)}100%{transform:rotate(360deg)}}
        @keyframes ao-stripe{0%{background-position:0 0}100%{background-position:40px 0}}
        .ao-panel{background:#fff;border:1px solid #e5e7eb;border-radius:10px;padding:24px;margin-bottom:18px}
        .ao-progress-track{background:#e5e7eb;border-radius:6px;height:22px;overflow:hidden;position:relative}
        .ao-progress-fill{height:100%;border-radius:6px;transition:width .4s;background:repeating-linear-gradient(135deg,#1a56db,#1a56db 10px,#3b82f6 10px,#3b82f6 20px);background-size:40px 40px;animation:ao-stripe 1s linear infinite}
        .ao-progress-fill.done{background:#059669;animation:none}
        .ao-progress-fill.stopped{background:#f59e0b;animation:none}
        .ao-progress-fill.errored{background:#dc2626;animation:none}
        .ao-pct{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.3)}
        .ao-step{font-size:13px;color:#666;margin-top:6px;min-height:20px}
        .ao-btn{border-radius:8px;padding:8px 18px;font-size:13px;font-weight:600;cursor:pointer;border:2px solid;transition:all .15s}
        .ao-btn:disabled{opacity:.4;cursor:not-allowed}
        .ao-btn-blue{background:#1a56db;color:#fff;border-color:#1a56db}.ao-btn-blue:hover:not(:disabled){background:#1e40af}
        .ao-btn-red{background:#dc2626;color:#fff;border-color:#dc2626}.ao-btn-red:hover:not(:disabled){background:#b91c1c}
        .ao-btn-grey{background:#fff;color:#6b7280;border-color:#d1d5db}.ao-btn-grey:hover:not(:disabled){background:#f3f4f6}
        .ao-btn-amber{background:#fff;color:#f59e0b;border-color:#f59e0b}.ao-btn-amber:hover:not(:disabled){background:#fffbeb}
        .ao-btn-green{background:#059669;color:#fff;border-color:#059669}.ao-btn-green:hover:not(:disabled){background:#047857}
        .ao-banner{padding:14px 20px;border-radius:8px;font-size:14px;font-weight:600;display:none;align-items:center;gap:10px;margin-top:14px}
        .ao-banner.ok{background:#ecfdf5;color:#059669;border:2px solid #059669}
        .ao-banner.warn{background:#fffbeb;color:#d97706;border:2px solid #f59e0b}
        .ao-banner.err{background:#fef2f2;color:#dc2626;border:2px solid #dc2626}
        .lang-row-selected{background:#eff6ff !important}
        .lang-cb-cell{width:30px;text-align:center}
        </style>

        <div class="wrap" style="max-width:1200px;">

        <h1 style="display:flex;align-items:center;gap:10px">
            <span style="font-size:28px">🔗</span> Anti-Orphan Center
            <span style="font-size:12px;color:#999;font-weight:normal">v2.19.2</span>
        </h1>

        <!-- ════════════ 1. COMMAND CENTER ════════════ -->
        <div class="ao-panel" id="ao-cc">
            <div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:16px">
                <button id="btn-scan" class="ao-btn ao-btn-blue">🔍 Scan All</button>
                <button id="btn-stop" class="ao-btn ao-btn-red" style="display:none">⏹ Stop</button>
                <button id="btn-fixsel" class="ao-btn ao-btn-green" <?php echo empty($stats)||$stats['total_orphans']<1?'disabled':''; ?>>🚀 Fix Selected (<?php echo $stats ? number_format($stats['total_orphans']) : '0'; ?>)</button>
                <button id="btn-fixstop" class="ao-btn ao-btn-red" style="display:none">⏹ Stop Fixing</button>
                <span style="color:#d1d5db">|</span>
                <button id="btn-reset" class="ao-btn ao-btn-grey">🗑️ Reset</button>
                <div style="display:inline-block;position:relative" id="undo-wrap">
                    <button id="btn-undo-toggle" class="ao-btn ao-btn-amber" <?php echo $injected_count<1?'disabled':''; ?>>↩️ Undo (<?php echo $injected_count; ?>) ▾</button>
                    <div id="undo-menu" style="display:none;position:absolute;top:100%;left:0;z-index:999;background:#fff;border:1px solid #d1d5db;border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,.15);padding:6px;min-width:200px;margin-top:4px">
                        <button class="undo-opt" data-hours="3" style="display:block;width:100%;text-align:left;padding:6px 10px;border:none;background:none;cursor:pointer;font-size:13px;border-radius:4px">↩️ Undo last <strong>3 hours</strong></button>
                        <button class="undo-opt" data-hours="6" style="display:block;width:100%;text-align:left;padding:6px 10px;border:none;background:none;cursor:pointer;font-size:13px;border-radius:4px">↩️ Undo last <strong>6 hours</strong></button>
                        <button class="undo-opt" data-hours="24" style="display:block;width:100%;text-align:left;padding:6px 10px;border:none;background:none;cursor:pointer;font-size:13px;border-radius:4px">↩️ Undo last <strong>24 hours</strong></button>
                        <button class="undo-opt" data-hours="48" style="display:block;width:100%;text-align:left;padding:6px 10px;border:none;background:none;cursor:pointer;font-size:13px;border-radius:4px">↩️ Undo last <strong>2 days</strong></button>
                        <button class="undo-opt" data-hours="72" style="display:block;width:100%;text-align:left;padding:6px 10px;border:none;background:none;cursor:pointer;font-size:13px;border-radius:4px">↩️ Undo last <strong>3 days</strong></button>
                        <hr style="margin:4px 0;border-color:#e5e7eb">
                        <button id="btn-undo-all" style="display:block;width:100%;text-align:left;padding:6px 10px;border:none;background:none;cursor:pointer;font-size:13px;border-radius:4px;color:#dc2626;font-weight:600">🗑️ Undo EVERYTHING</button>
                    </div>
                </div>
            </div>

            <!-- Progress panel -->
            <div style="background:#f8fafc;border:1px solid #e5e7eb;border-radius:10px;padding:20px">
                <div style="display:flex;align-items:center;gap:20px;margin-bottom:14px">
                    <div id="hg" style="font-size:42px;line-height:1;opacity:.3"><?php echo $stats ? '✅' : '⏳'; ?></div>
                    <div>
                        <div id="timer" style="font-size:28px;font-weight:700;color:#1a56db;font-variant-numeric:tabular-nums">—</div>
                        <div id="timer-label" style="font-size:11px;color:#999"><?php echo $stats ? 'total' : 'waiting'; ?></div>
                    </div>
                    <div id="badge" style="margin-left:auto;padding:4px 14px;border-radius:20px;font-size:12px;font-weight:700;<?php echo $stats ? 'background:#059669;color:#fff' : 'background:#e5e7eb;color:#6b7280'; ?>"><?php echo $stats ? 'DONE' : 'IDLE'; ?></div>
                </div>
                <div class="ao-progress-track">
                    <div class="ao-progress-fill<?php echo $stats ? ' done' : ''; ?>" id="bar" style="width:<?php echo $stats ? '100' : '0'; ?>%"></div>
                    <div class="ao-pct" id="pct"><?php echo $stats ? '100%' : '0%'; ?></div>
                </div>
                <div class="ao-step" id="step"><?php
                    if ( $stats ) {
                        echo 'Last scan: ' . number_format($stats['total_pages']) . ' pages — '
                            . number_format($stats['total_orphans']) . ' orphans, '
                            . number_format($stats['total_weak']) . ' weak. Select languages and click Fix.';
                    } else {
                        echo 'Select languages in table below, then click a button.';
                    }
                ?></div>
            </div>

            <div class="ao-banner ok" id="b-done"><span style="font-size:22px">✅</span><span id="b-done-t"></span><button class="ao-btn ao-btn-green" style="margin-left:auto;padding:6px 14px" onclick="location.reload()">🔄 Refresh</button></div>
            <div class="ao-banner warn" id="b-stop"><span style="font-size:22px">⏹</span><span id="b-stop-t"></span><button class="ao-btn ao-btn-blue" style="margin-left:auto;padding:6px 14px" onclick="location.reload()">Refresh</button></div>
            <div class="ao-banner err" id="b-err"><span style="font-size:22px">❌</span><span id="b-err-t"></span></div>

            <!-- Fix live log -->
            <div id="fix-log-panel" style="display:none;margin-top:14px;background:#f0fdf4;border:2px solid #059669;border-radius:10px;padding:16px">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px">
                    <h3 style="margin:0;font-size:15px;color:#059669">🚀 Fix Log</h3>
                    <span id="fix-log-status" style="font-size:13px;font-weight:600"></span>
                </div>
                <div id="fix-log" style="background:#fff;border:1px solid #d1d5db;border-radius:8px;padding:12px;max-height:350px;overflow-y:auto;font-size:12px;font-family:monospace;line-height:1.8"></div>
                <div id="fix-log-summary" style="margin-top:10px;font-size:14px;font-weight:700;display:none"></div>
            </div>
        </div>

        <!-- ════════════ 2. STATS CARDS ════════════ -->
        <?php if ( $stats ) : ?>
        <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;margin-bottom:18px">
            <div style="background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:14px;text-align:center">
                <div style="font-size:26px;font-weight:700;color:#1a56db"><?php echo number_format($stats['total_pages']); ?></div>
                <div style="font-size:11px;color:#666">Total Pages</div>
            </div>
            <div style="background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:14px;text-align:center">
                <div style="font-size:26px;font-weight:700;color:#dc2626"><?php echo number_format($stats['total_orphans']); ?></div>
                <div style="font-size:11px;color:#666">Orphans</div>
            </div>
            <div style="background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:14px;text-align:center">
                <div style="font-size:26px;font-weight:700;color:#f59e0b"><?php echo number_format($stats['total_weak']); ?></div>
                <div style="font-size:11px;color:#666">Weak</div>
            </div>
            <div style="background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:14px;text-align:center">
                <div style="font-size:26px;font-weight:700;color:#059669"><?php echo number_format(max(0,$stats['total_pages']-$stats['total_orphans']-$stats['total_weak'])); ?></div>
                <div style="font-size:11px;color:#666">Well-Linked</div>
            </div>
            <div style="background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:14px;text-align:center">
                <?php $hp=$stats['total_pages']>0?round((1-$stats['total_orphans']/$stats['total_pages'])*100):100; ?>
                <div style="font-size:26px;font-weight:700;color:<?php echo $hp>=50?'#059669':'#dc2626'; ?>"><?php echo $hp; ?>%</div>
                <div style="font-size:11px;color:#666">Health</div>
            </div>
            <?php if(!empty($stats['structural_links'])): ?>
            <div style="background:#fff;border:1px solid #c4b5fd;border-radius:8px;padding:14px;text-align:center">
                <div style="font-size:26px;font-weight:700;color:#7c3aed"><?php echo number_format($stats['structural_links']); ?></div>
                <div style="font-size:11px;color:#666">🧭 Nav/Widget</div>
            </div>
            <?php endif; ?>
        </div>

        <!-- ════════════ 3. LANGUAGE TABLE WITH CHECKBOXES ════════════ -->
        <div class="ao-panel" style="padding:14px;overflow-x:auto">
            <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px">
                <h3 style="margin:0;font-size:15px">📊 Language Breakdown — <span id="sel-count" style="color:#1a56db">select languages to fix</span></h3>
                <div style="display:flex;gap:8px">
                    <button type="button" id="sel-all-btn" class="button button-small">☑️ Select All</button>
                    <button type="button" id="sel-none-btn" class="button button-small">☐ Select None</button>
                </div>
            </div>
            <table class="widefat striped" style="font-size:13px" id="lang-table">
                <thead><tr style="background:#f8fafc">
                    <th class="lang-cb-cell"><input type="checkbox" id="cb-all" checked></th>
                    <th style="width:40px">Code</th>
                    <th style="width:80px">Language</th>
                    <th style="text-align:center;width:60px">Total</th>
                    <th style="text-align:center;width:70px">🚨 Orphans</th>
                    <th style="text-align:center;width:60px">⚠️ Weak</th>
                    <th style="text-align:center;width:60px">✅ OK</th>
                    <th style="width:140px">Health</th>
                    <th style="width:60px">Status</th>
                    <th style="width:90px;text-align:center">Action</th>
                </tr></thead>
                <tbody>
                <?php
                $sl = $stats['by_language'];
                uasort($sl, function($a,$b){ return ($b['orphans']??0)-($a['orphans']??0); });
                foreach ( $sl as $lc => $ls ) :
                    $err = !empty($ls['error']);
                    $linked = max(0,$ls['total']-$ls['orphans']-$ls['weak']);
                    $lhp = $ls['total']>0 ? round($linked/$ls['total']*100) : 0;
                    $hc = $lhp>=90?'#059669':($lhp>=70?'#f59e0b':'#dc2626');
                ?>
                <tr class="lang-row lang-row-selected" data-lang="<?php echo esc_attr($lc); ?>" data-orphans="<?php echo intval($ls['orphans']); ?>" data-name="<?php echo esc_attr($ls['language_name']); ?>">
                    <td class="lang-cb-cell"><input type="checkbox" class="lang-cb" value="<?php echo esc_attr($lc); ?>" checked></td>
                    <td><strong><?php echo strtoupper(esc_html($lc)); ?></strong></td>
                    <td><?php echo esc_html($ls['language_name']); ?></td>
                    <?php if($err): ?>
                    <td colspan="5" style="color:#999">Error: <?php echo esc_html(substr($ls['error'],0,60)); ?></td>
                    <td><span style="background:#dc2626;color:#fff;border-radius:10px;padding:2px 8px;font-size:11px">ERR</span></td>
                    <td>—</td>
                    <?php else: ?>
                    <td style="text-align:center;font-weight:500"><?php echo number_format($ls['total']); ?></td>
                    <td style="text-align:center"><?php if($ls['orphans']>0): ?><span style="background:#fef2f2;color:#dc2626;padding:2px 8px;border-radius:10px;font-size:12px;font-weight:600"><?php echo $ls['orphans']; ?></span><?php else: ?><span style="color:#059669;font-weight:600">0 ✓</span><?php endif; ?></td>
                    <td style="text-align:center"><?php if($ls['weak']>0): ?><span style="background:#fffbeb;color:#d97706;padding:2px 6px;border-radius:10px;font-size:12px"><?php echo $ls['weak']; ?></span><?php else: ?>0<?php endif; ?></td>
                    <td style="text-align:center;color:#059669;font-weight:500"><?php echo number_format($linked); ?></td>
                    <td><div style="display:flex;align-items:center;gap:4px"><div style="flex:1;background:#e5e7eb;border-radius:4px;height:8px;overflow:hidden"><div style="background:<?php echo $hc; ?>;height:100%;width:<?php echo $lhp; ?>%"></div></div><span style="font-size:11px;color:<?php echo $hc; ?>;font-weight:600;min-width:28px"><?php echo $lhp; ?>%</span></div></td>
                    <td><?php echo $ls['orphans']>0?'<span style="color:#dc2626;font-size:11px">🔧 Fix</span>':($ls['weak']>0?'<span style="color:#f59e0b;font-size:11px">⚠️</span>':'<span style="color:#059669;font-size:11px">✅</span>'); ?></td>
                    <td style="text-align:center"><?php if($ls['orphans']>0): ?><button class="ao-btn-fix-all" data-lang="<?php echo esc_attr($lc); ?>" style="background:#dc2626;color:#fff;border:1px solid #dc2626;border-radius:6px;padding:3px 10px;font-size:11px;font-weight:600;cursor:pointer;white-space:nowrap">⚡ Fix <?php echo $ls['orphans']; ?></button><?php else: ?>—<?php endif; ?></td>
                    <?php endif; ?>
                </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
            <div style="font-size:11px;color:#999;margin-top:6px">
                Last scan: <?php echo esc_html($stats['scan_date']); ?> (<?php echo $stats['scan_time']; ?>s)
                <?php if(!empty($stats['structural_links'])): ?> — <?php echo $stats['structural_links']; ?> structural links<?php endif; ?>
            </div>
        </div>

        <?php else: ?>
        <div style="background:#fefce8;border:1px solid #fde68a;border-radius:8px;padding:16px;margin-bottom:18px">
            <strong>No scan results yet.</strong> Click "Scan All" above.
        </div>
        <?php endif; ?>

        <!-- ════════════ 4. ORPHAN + WEAK LISTS PER LANGUAGE ════════════ -->
        <?php foreach ( $details as $lc => $ld ) :
            if ( empty($ld['orphans']) && empty($ld['weak']) ) continue;
        ?>
        <div style="background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:18px;margin-bottom:14px">
            <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px">
                <h2 style="margin:0;font-size:15px">
                    <?php echo strtoupper(esc_html($lc)); ?> — <?php echo esc_html($ld['language_name']); ?>
                    <span style="color:#dc2626;font-size:13px">(<?php echo count($ld['orphans']); ?> orphans, <?php echo count($ld['weak']); ?> weak)</span>
                </h2>
                <?php if(!empty($ld['orphans'])): ?>
                <button class="button ao-btn-fix-all" data-lang="<?php echo esc_attr($lc); ?>" style="background:#dc2626;color:#fff;border-color:#dc2626">⚡ Fix All (<?php echo esc_html($lc); ?>)</button>
                <?php endif; ?>
            </div>
            <?php if(!empty($ld['orphans'])): ?>
            <h3 style="color:#dc2626;font-size:13px;margin:10px 0 6px">🚨 Orphans (0 inbound)</h3>
            <table class="widefat striped" style="font-size:12px"><thead><tr><th style="width:45%">Page</th><th style="width:8%">Type</th><th style="width:12%">Date</th><th style="width:8%">In</th><th style="width:27%">Actions</th></tr></thead><tbody>
            <?php foreach(array_slice($ld['orphans'],0,100) as $o): ?>
            <tr id="ao-row-<?php echo $o['id']; ?>">
                <td><a href="<?php echo esc_url($o['url']); ?>" target="_blank" style="font-weight:500"><?php echo esc_html(wp_trim_words($o['title'],12)); ?></a><div style="font-size:10px;color:#999;word-break:break-all"><?php echo esc_html(str_replace(home_url(),'',$o['url'])); ?></div></td>
                <td><code style="font-size:11px"><?php echo esc_html($o['type']); ?></code></td>
                <td style="font-size:11px"><?php echo date('Y-m-d',strtotime($o['date'])); ?></td>
                <td><span style="background:#fef2f2;color:#dc2626;padding:1px 6px;border-radius:10px;font-size:11px;font-weight:600">0</span></td>
                <td>
                    <button class="button button-small ao-btn-fix" data-id="<?php echo $o['id']; ?>" data-lang="<?php echo esc_attr($lc); ?>" style="color:#1a56db">🔧 Fix</button>
                    <a href="<?php echo admin_url('post.php?post='.$o['id'].'&action=edit'); ?>" class="button button-small" target="_blank">✏️</a>
                    <button class="button button-small ao-btn-rollback" data-id="<?php echo $o['id']; ?>" style="color:#666;display:none">↩️</button>
                </td>
            </tr>
            <?php endforeach; ?>
            </tbody></table>
            <?php if(count($ld['orphans'])>100): ?><p style="color:#888;font-size:11px;margin-top:4px">Showing 100 of <?php echo count($ld['orphans']); ?>.</p><?php endif; ?>
            <?php endif; ?>
            <?php if(!empty($ld['weak'])): ?>
            <details style="margin-top:12px"><summary style="font-size:13px;color:#d97706;cursor:pointer;font-weight:600">⚠️ <?php echo count($ld['weak']); ?> Weak Pages (1 inbound)</summary>
            <table class="widefat striped" style="font-size:12px;margin-top:6px"><thead><tr><th style="width:45%">Page</th><th style="width:10%">Type</th><th style="width:25%">Linked From</th><th style="width:20%">Actions</th></tr></thead><tbody>
            <?php foreach(array_slice($ld['weak'],0,50) as $w): ?>
            <tr>
                <td><a href="<?php echo esc_url($w['url']); ?>" target="_blank"><?php echo esc_html(wp_trim_words($w['title'],12)); ?></a></td>
                <td><code style="font-size:11px"><?php echo esc_html($w['type']); ?></code></td>
                <td style="font-size:11px"><?php if(!empty($w['inbound'][0])): ?><a href="<?php echo esc_url($w['inbound'][0]['from_url']); ?>" target="_blank"><?php echo esc_html(wp_trim_words($w['inbound'][0]['from_title'],6)); ?></a><?php endif; ?></td>
                <td><button class="button button-small ao-btn-fix" data-id="<?php echo $w['id']; ?>" data-lang="<?php echo esc_attr($lc); ?>" style="color:#f59e0b">🔧 Strengthen</button></td>
            </tr>
            <?php endforeach; ?>
            </tbody></table></details>
            <?php endif; ?>
        </div>
        <?php endforeach; ?>

        <!-- ════════════ 5. LOG ════════════ -->
        <?php if(!empty($log)): ?>
        <div class="ao-panel" style="padding:18px">
            <h2 style="margin:0 0 10px;font-size:15px">📋 Injection Log (last <?php echo min(count($log),20); ?>)</h2>
            <table class="widefat striped" style="font-size:12px"><thead><tr><th>Date</th><th>Orphan</th><th>Lang</th><th>Donors</th></tr></thead><tbody>
            <?php foreach(array_slice($log,0,20) as $e): ?>
            <tr>
                <td style="white-space:nowrap"><?php echo esc_html($e['date']); ?></td>
                <td><a href="<?php echo esc_url($e['orphan_url']); ?>" target="_blank">#<?php echo intval($e['orphan_id']); ?></a></td>
                <td><code><?php echo esc_html($e['language']); ?></code></td>
                <td><?php foreach($e['donors'] as $d): ?><div>← #<?php echo intval($d['donor_id']); ?> <em style="color:#888">"<?php echo esc_html($d['anchor']); ?>"</em></div><?php endforeach; ?></td>
            </tr>
            <?php endforeach; ?>
            </tbody></table>
        </div>
        <?php endif; ?>

        <!-- ════════════ 6. SETTINGS ════════════ -->
        <div class="ao-panel" style="padding:18px">
            <h2 style="margin:0 0 10px;font-size:15px">⚙️ Settings</h2>
            <div style="display:grid;grid-template-columns:1fr 1fr;gap:14px;max-width:550px">
                <label style="display:flex;align-items:center;gap:6px"><input type="checkbox" id="s-enabled" <?php checked($settings['enabled']); ?>> Enable scanner</label>
                <label style="display:flex;align-items:center;gap:6px"><input type="checkbox" id="s-autofix" <?php checked($settings['auto_fix']); ?>> Auto-fix on scan</label>
                <label style="display:flex;flex-direction:column;gap:3px"><span style="font-size:11px;color:#666">Max links/orphan</span><input type="number" id="s-maxlinks" value="<?php echo intval($settings['max_links']); ?>" min="1" max="5" style="width:70px"></label>
                <label style="display:flex;flex-direction:column;gap:3px"><span style="font-size:11px;color:#666">Min content length</span><input type="number" id="s-mincontent" value="<?php echo intval($settings['min_content_len']); ?>" min="200" max="2000" style="width:90px"></label>
                <label style="display:flex;align-items:center;gap:6px"><input type="checkbox" id="s-email" <?php checked($settings['email_report']); ?>> Email report</label>
                <label style="display:flex;flex-direction:column;gap:3px"><span style="font-size:11px;color:#666">Email</span><input type="email" id="s-emailaddr" value="<?php echo esc_attr($settings['email_address']); ?>" style="width:180px"></label>
            </div>
            <button id="btn-save" class="button" style="margin-top:10px">💾 Save</button>
            <span id="save-ok" style="font-size:12px;color:#059669;margin-left:8px"></span>
        </div>

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

        <script>
        jQuery(function($){
            // Show persistent message from undo/action redirect
            var urlP=new URLSearchParams(window.location.search);
            var aoMsg=urlP.get('ao_msg');
            if(aoMsg){
                var $banner=$('<div style="background:#ecfdf5;border:2px solid #059669;border-radius:8px;padding:12px 18px;margin-bottom:16px;font-size:15px;font-weight:600;color:#065f46;display:flex;align-items:center;gap:10px"><span style="flex:1">'+decodeURIComponent(aoMsg)+'</span><button style="background:none;border:none;font-size:18px;cursor:pointer;color:#065f46" onclick="$(this).parent().fadeOut()">✕</button></div>');
                $('#ao-command-center').before($banner);
                // Clean URL without reload
                var clean=window.location.pathname+window.location.search.replace(/[&?]ao_msg=[^&]*/,'');
                window.history.replaceState(null,'',clean);
            }
            var N='<?php echo esc_js($nonce); ?>', A='<?php echo admin_url("admin-ajax.php"); ?>';
            var scanXHR,poll,tick,t0,fixStop=false;

            // ── Timer ──
            function startT(){t0=Date.now();tick=setInterval(function(){var s=Math.floor((Date.now()-t0)/1000),m=Math.floor(s/60);s%=60;$('#timer').text((m<10?'0':'')+m+':'+(s<10?'0':'')+s);},250);}
            function stopT(){clearInterval(tick);}

            // ── Checkbox selection ──
            function getSelectedLangs(){
                var langs=[];
                $('.lang-cb:checked').each(function(){
                    var row=$(this).closest('tr');
                    var o=parseInt(row.data('orphans'))||0;
                    if(o>0) langs.push({code:$(this).val(), name:row.data('name'), orphans:o});
                });
                // Sort by orphan count desc
                langs.sort(function(a,b){return b.orphans-a.orphans;});
                return langs;
            }
            function updateSelCount(){
                var checked=$('.lang-cb:checked').length, total=$('.lang-cb').length;
                var langs=getSelectedLangs();
                var totalOrph=0; langs.forEach(function(l){totalOrph+=l.orphans;});
                if(checked===total) $('#sel-count').text('All '+total+' languages selected ('+totalOrph+' orphans)');
                else if(checked===0) $('#sel-count').text('No languages selected').css('color','#dc2626');
                else {
                    var codes=langs.map(function(l){return l.code.toUpperCase();});
                    $('#sel-count').text(codes.join(', ')+' — '+totalOrph+' orphans').css('color','#1a56db');
                }
                $('#cb-all').prop('checked',checked===total);
                // Update Fix button
                $('#btn-fixsel').text('🚀 Fix Selected'+(totalOrph>0?' ('+totalOrph+')':'')).prop('disabled',totalOrph<1);
                // Highlight rows
                $('.lang-row').each(function(){
                    $(this).toggleClass('lang-row-selected',$(this).find('.lang-cb').is(':checked'));
                });
            }
            $('#cb-all').on('change',function(){$('.lang-cb').prop('checked',this.checked);updateSelCount();});
            $(document).on('change','.lang-cb',function(){updateSelCount();});
            $('#sel-all-btn').on('click',function(){$('.lang-cb').prop('checked',true);$('#cb-all').prop('checked',true);updateSelCount();});
            $('#sel-none-btn').on('click',function(){$('.lang-cb').prop('checked',false);$('#cb-all').prop('checked',false);updateSelCount();});
            updateSelCount(); // init

            // ── UI helpers ──
            function banner(id,t){$('#b-'+id).find('span:eq(1)').text(t);$('#b-'+id).css('display','flex');}
            function errBox(title,msg){
                $('#ao-errbox').remove();
                $('<div id="ao-errbox" style="background:#fef2f2;border:2px solid #dc2626;border-radius:8px;padding:14px;margin:10px 0;font-family:monospace"><div style="display:flex;justify-content:space-between"><strong style="color:#dc2626">🚨 '+title+'</strong><button onclick="$(this).closest(\'#ao-errbox\').remove()" style="background:none;border:none;cursor:pointer;color:#dc2626;font-size:16px">✕</button></div><pre style="background:#1e1e1e;color:#f0f0f0;padding:10px;border-radius:4px;margin:6px 0 0;font-size:11px;white-space:pre-wrap;word-break:break-all;max-height:250px;overflow:auto">'+$('<span>').text(msg).html()+'</pre></div>').insertAfter('#ao-cc');
            }
            function disableAll(on){$('#btn-scan,#btn-reset,#btn-undo-toggle,#btn-fixsel,.lang-cb,#cb-all,#sel-all-btn,#sel-none-btn').prop('disabled',on);}

            // ── SCAN ──
            function scanning(on){
                if(on){
                    $('#hg').css({opacity:1,display:'inline-block',animation:'ao-flip 2s ease-in-out infinite',transformOrigin:'center center'}).text('⏳');
                    $('#badge').text('SCANNING').css({background:'#1a56db',color:'#fff'});
                    $('#btn-scan').hide();$('#btn-stop').show();disableAll(true);$('#btn-stop').prop('disabled',false);
                    $('.ao-banner').hide();$('#bar').removeClass('done stopped errored').css('width','0%');
                    $('#pct').text('0%');$('#step').text('Starting...');$('#timer-label').text('elapsed');startT();
                } else {
                    $('#hg').css('animation','none');$('#btn-scan').show();$('#btn-stop').hide();disableAll(false);stopT();updateSelCount();
                }
            }
            $('#btn-scan').on('click',function(){
                scanning(true);
                poll=setInterval(function(){$.post(A,{action:'dba_ao_progress',nonce:N},function(r){if(r.success&&r.data){$('#bar').css('width',(r.data.percent||0)+'%');$('#pct').text((r.data.percent||0)+'%');$('#step').text(r.data.message||'');}});},1500);
                scanXHR=$.ajax({url:A,method:'POST',data:{action:'dba_ao_run_scan',nonce:N,language:''},timeout:600000,dataType:'json',
                    success:function(r){clearInterval(poll);scanning(false);
                        if(r.success){var d=r.data;if(d.stopped){$('#hg').text('⏹');$('#badge').text('STOPPED').css({background:'#f59e0b'});$('#bar').addClass('stopped');banner('stop','Stopped. '+d.total_pages+' pages.');}
                        else{$('#hg').text('✅');$('#badge').text('DONE').css({background:'#059669'});$('#bar').addClass('done').css('width','100%');$('#pct').text('100%');$('#timer-label').text('total');banner('done','Done! '+d.total_pages+' pages — '+d.total_orphans+' orphans, '+d.total_weak+' weak ('+(d.structural_links||0)+' structural) in '+d.scan_time+'s');}}
                        else{$('#hg').text('❌');$('#badge').text('ERROR').css({background:'#dc2626'});$('#bar').addClass('errored').css('width','100%');banner('err','Failed: '+(typeof r.data==='string'?r.data:JSON.stringify(r.data)));errBox('Scan Error',typeof r.data==='string'?r.data:JSON.stringify(r.data));}
                    },
                    error:function(x,s,e){clearInterval(poll);scanning(false);if(s==='abort')return;var d=s==='timeout'?'Timed out.':'HTTP '+(x.status||'?')+' '+s+': '+e;$('#hg').text('❌');$('#badge').text('ERROR').css({background:'#dc2626'});$('#bar').addClass('errored');banner('err','Request error');errBox('Error',d);}
                });
            });
            $('#btn-stop').on('click',function(){$(this).prop('disabled',true).text('⏹ Stopping...');$.post(A,{action:'dba_ao_stop_scan',nonce:N});});

            // ── RESET ──
            $('#btn-reset').on('click',function(){
                if(!confirm('🗑️ DELETE all scan data & logs?'))return;
                $(this).prop('disabled',true).text('🗑️ ...');
                $.post(A,{action:'dba_ao_reset',nonce:N},function(r){if(r.success)location.reload();else alert('Failed');});
            });

            // ── UNDO DROPDOWN ──
            $('#btn-undo-toggle').on('click',function(e){e.stopPropagation();$('#undo-menu').toggle();});
            $(document).on('click',function(e){if(!$(e.target).closest('#undo-wrap').length)$('#undo-menu').hide();});
            $('.undo-opt').hover(function(){$(this).css('background','#f3f4f6')},function(){$(this).css('background','')});
            $('#btn-undo-all').hover(function(){$(this).css('background','#fef2f2')},function(){$(this).css('background','')});

            // Undo by date range — batched
            var dateUndoRolled=0,dateUndoFailed=0,dateUndoTotal=0;
            $(document).on('click','.undo-opt',function(){
                var h=$(this).data('hours');
                if(!confirm('↩️ Undo all injections from the last '+h+' hours?\n\nRuns in batches. Older injections kept.'))return;
                $('#undo-menu').hide();
                var btn=$('#btn-undo-toggle');
                dateUndoRolled=0;dateUndoFailed=0;dateUndoTotal=0;
                function dateUndoBatch(n){
                    btn.prop('disabled',true).text('↩️ Undoing batch #'+n+'... ('+dateUndoRolled+' done)');
                    $.ajax({url:A,method:'POST',data:{action:'dba_ao_rollback_date',nonce:N,hours:h},timeout:120000,
                        success:function(r){
                            if(r.success){
                                if(n===1) dateUndoTotal=r.data.total_found;
                                dateUndoRolled+=r.data.rolled_back;dateUndoFailed+=r.data.failed;
                                if(!r.data.done && r.data.remaining>0){
                                    btn.text('↩️ Batch #'+n+': '+dateUndoRolled+'/'+dateUndoTotal+' ('+r.data.remaining+' left)');
                                    dateUndoBatch(n+1);
                                }else{
                                    var msg='✅ Undo last '+h+'h complete: '+dateUndoRolled+' links removed, '+(r.data.skipped||0)+' kept (older), '+dateUndoFailed+' failed';
                                    window.location=window.location.pathname+window.location.search+(window.location.search?'&':'?')+'ao_msg='+encodeURIComponent(msg);
                                }
                            }else{btn.text('❌ Failed');}
                        },
                        error:function(){
                            if(dateUndoRolled>0){btn.text('↩️ Retrying...');setTimeout(function(){dateUndoBatch(n)},2000);}
                            else btn.text('❌ Request failed');
                        }
                    });
                }
                dateUndoBatch(1);
            });

            // Undo ALL — batched with auto-chain
            var undoTotal=0,undoRolled=0,undoFailed=0;
            $('#btn-undo-all').on('click',function(){
                if(!confirm('🗑️ Undo EVERYTHING — rollback ALL injected links?\n\nThis runs in batches of 50. Fully automatic.'))return;
                $('#undo-menu').hide();
                var btn=$('#btn-undo-toggle');
                undoTotal=0;undoRolled=0;undoFailed=0;
                function undoBatch(n){
                    btn.prop('disabled',true).text('↩️ Rolling back batch #'+n+'... ('+undoRolled+' done)');
                    $.ajax({url:A,method:'POST',data:{action:'dba_ao_rollback_all',nonce:N},timeout:120000,
                        success:function(r){
                            if(r.success){
                                if(n===1) undoTotal=r.data.total_found;
                                undoRolled+=r.data.rolled_back;undoFailed+=r.data.failed;
                                if(!r.data.done && r.data.remaining>0){
                                    btn.text('↩️ Batch #'+n+': '+undoRolled+'/'+undoTotal+' rolled back ('+r.data.remaining+' left)');
                                    undoBatch(n+1);
                                }else{
                                    var msg='✅ Undo EVERYTHING complete: '+undoRolled+' links removed from '+undoTotal+' posts ('+undoFailed+' failed)';
                                    window.location=window.location.pathname+window.location.search+(window.location.search?'&':'?')+'ao_msg='+encodeURIComponent(msg);
                                }
                            }else{btn.text('❌ Failed: '+(r.data||''));}
                        },
                        error:function(x){
                            if(undoRolled>0){btn.text('↩️ Retrying after error...');setTimeout(function(){undoBatch(n)},2000);}
                            else btn.text('❌ Request failed');
                        }
                    });
                }
                undoBatch(1);
            });

            // ── FIX SELECTED LANGUAGES — auto-chain ──
            var fixTotalFixed=0,fixTotalFailed=0,fixTotalSkipped=0;
            function fixLog(msg,color){$('#fix-log').append('<div style="color:'+(color||'#333')+'">'+msg+'</div>');$('#fix-log').scrollTop($('#fix-log')[0].scrollHeight);}

            $('#btn-fixsel').on('click',function(){
                var langs=getSelectedLangs();
                if(langs.length===0){alert('No languages with orphans selected!');return;}
                var codes=langs.map(function(l){return l.code.toUpperCase();}).join(', ');
                var totalOrph=0;langs.forEach(function(l){totalOrph+=l.orphans;});
                var estSeconds=totalOrph*1.5; // ~1.5s per orphan avg with pre-filter
                var estMinutes=Math.ceil(estSeconds/60);
                var estH=Math.floor(estMinutes/60),estM=estMinutes%60;
                var estStr=estH>0?estH+'h '+estM+'min':estM+' min';
                if(!confirm('🚀 FIX: '+codes+'\n\n'+langs.length+' language(s), ~'+totalOrph+' orphans.\nBatches of 30, fully automatic.\nEstimated time: ~'+estStr+'\nCrash-safe: click again to resume.\n\nContinue?'))return;

                fixStop=false;fixTotalFixed=0;fixTotalFailed=0;fixTotalSkipped=0;
                $(this).hide();$('#btn-fixstop').show();disableAll(true);$('#btn-fixstop').prop('disabled',false);
                $('#fix-log-panel').show();$('#fix-log').empty();$('#fix-log-summary').hide();
                $('#fix-log-status').text('Running...').css('color','#1a56db');
                $('#hg').css({opacity:1,animation:'ao-flip 2s ease-in-out infinite',transformOrigin:'center center'}).text('⏳');
                $('#badge').text('FIXING').css({background:'#7c3aed',color:'#fff'});
                $('#bar').removeClass('done stopped errored').css('width','0%');$('#pct').text('0%');
                startT();

                var langIdx=0;
                if(totalOrph<1)totalOrph=1;
                fixLog('🚀 Fix: '+codes+' — '+langs.length+' language(s), ~'+totalOrph+' orphans','#7c3aed');
                fixLog('─'.repeat(50),'#ccc');

                nextLang();

                var MAX_BATCHES=100;
                function nextLang(){
                    if(fixStop||langIdx>=langs.length){finish();return;}
                    var l=langs[langIdx];
                    fixLog('');fixLog('📌 '+l.code.toUpperCase()+' — '+l.name+' ('+l.orphans+' orphans)','#1a56db');
                    doBatch(l.code,1);
                }
                function doBatch(code,bNum){
                    if(fixStop){finish();return;}
                    if(bNum>MAX_BATCHES){fixLog('   ⚠️ Max batches ('+MAX_BATCHES+') hit, moving on','#d97706');langIdx++;nextLang();return;}
                    var pct=Math.min(99,Math.round((fixTotalFixed+fixTotalFailed+fixTotalSkipped)/totalOrph*100));
                    $('#bar').css('width',pct+'%');$('#pct').text(pct+'%');$('#step').text('Fixing '+code.toUpperCase()+' batch #'+bNum+'...');
                    $.ajax({url:A,method:'POST',timeout:600000,data:{action:'dba_ao_fix_all',nonce:N,language:code},
                        success:function(r){
                            if(r.success&&r.data){
                                var d=r.data,fx=d.fixed||0,fl=d.failed||0,sk=d.skipped||0,rem=d.remaining||0;
                                fixTotalFixed+=fx;fixTotalFailed+=fl;fixTotalSkipped+=sk;
                                var parts=[];if(fx>0)parts.push(fx+' fixed');if(fl>0)parts.push(fl+' failed');if(sk>0)parts.push(sk+' skipped');
                                fixLog('   '+(fx>0?'✅':sk>0?'⏭️':'⚠️')+' Batch #'+bNum+': '+parts.join(', ')+' — '+rem+' remaining',fx>0?'#059669':sk>0?'#666':'#d97706');
                                // Show samples with clickable links
                                if(d.samples&&d.samples.length>0){
                                    var methodLabels={'inline_wrap':'✏️ inline','sentence_append':'📝 sentence','see_also':'📎 see-also','injected':'✅ injected'};
                                    d.samples.forEach(function(s){
                                        var ml=methodLabels[s.method]||s.method;
                                        fixLog('      🔗 <a href="'+s.orphan_url+'" target="_blank" style="color:#1a56db;text-decoration:underline">'+s.orphan_title+'</a> <span style="color:#999">['+ml+']</span>');
                                    });
                                }
                                if(!fixStop&&rem>0&&(fx>0||sk>0)){doBatch(code,bNum+1);}
                                else{if(rem===0)fixLog('   ✅ '+code.toUpperCase()+' complete!','#059669');langIdx++;nextLang();}
                            }else{fixLog('   ❌ Error: '+(typeof r.data==='string'?r.data:JSON.stringify(r.data)),'#dc2626');langIdx++;nextLang();}
                        },
                        error:function(x,s){fixLog('   ❌ HTTP '+(x.status||'?')+' '+s+' — skipping','#dc2626');langIdx++;nextLang();}
                    });
                }
                function finish(){
                    stopT();$('#hg').text('✅').css({opacity:1,animation:'none'});
                    $('#badge').text('DONE').css({background:'#059669',color:'#fff'});
                    $('#bar').addClass('done').css('width','100%');$('#pct').text('100%');
                    $('#step').text('Fix complete.');$('#timer-label').text('total');
                    $('#btn-fixstop').hide();$('#btn-fixsel').show();disableAll(false);updateSelCount();
                    fixLog('');fixLog('─'.repeat(50),'#ccc');
                    fixLog('🏁 DONE — '+fixTotalFixed+' fixed, '+fixTotalFailed+' failed, '+fixTotalSkipped+' skipped across '+langs.length+' language(s).',fixTotalFixed>0?'#059669':'#d97706');
                    $('#fix-log-status').text(fixStop?'Stopped':'Complete!').css('color',fixStop?'#d97706':'#059669');
                    $('#fix-log-summary').css('display','block').html('<span style="color:#059669">✅ '+fixTotalFixed+' fixed</span> | <span style="color:#dc2626">❌ '+fixTotalFailed+' failed</span> | <span style="color:#666">⏭️ '+fixTotalSkipped+' skipped</span> | <a href="" onclick="location.reload();return false" style="color:#1a56db">🔄 Refresh</a>');
                }
            });
            $('#btn-fixstop').on('click',function(){fixStop=true;$(this).prop('disabled',true).text('⏹ Stopping...');fixLog('⏹ Stop requested...','#f59e0b');});

            // ── FIX SINGLE ──
            $(document).on('click','.ao-btn-fix',function(){
                var b=$(this),id=b.data('id'),lang=b.data('lang');b.prop('disabled',true).text('⏳...');
                $.post(A,{action:'dba_ao_fix_orphan',nonce:N,post_id:id,language:lang},function(r){
                    if(r.success&&r.data&&r.data.success){b.text('✅ '+r.data.links_injected).css({color:'#059669',background:'#ecfdf5',borderColor:'#059669'});$('#ao-row-'+id).find('.ao-btn-rollback').show();}
                    else{var m=r.data&&r.data.error?r.data.error:'No donors';b.text('❌ '+m).css('color','#dc2626');setTimeout(function(){b.prop('disabled',false).text('🔧 Fix').css({color:'',background:'',borderColor:''});},4000);}
                }).fail(function(x){b.text('❌ HTTP '+(x.status||'?'));setTimeout(function(){b.prop('disabled',false).text('🔧 Fix').css({color:'',background:'',borderColor:''});},4000);});
            });

            // ── FIX ALL (per-language button) ──
            $(document).on('click','.ao-btn-fix-all',function(){
                var b=$(this),lang=b.data('lang');
                if(!confirm('⚡ Fix all orphans for '+lang.toUpperCase()+'?'))return;
                b.prop('disabled',true).text('⏳ Fixing...');
                $.ajax({url:A,method:'POST',data:{action:'dba_ao_fix_all',nonce:N,language:lang},timeout:600000,
                    success:function(r){if(r.success&&r.data){b.text('✅ '+r.data.fixed+' fixed, '+r.data.failed+' failed').css({background:'#059669',borderColor:'#059669',color:'#fff'});}else{b.text('❌').css({background:'#dc2626'});}},
                    error:function(x){b.text('❌ HTTP '+(x.status||'?')).css({background:'#dc2626'});}
                });
            });

            // ── ROLLBACK SINGLE ──
            $(document).on('click','.ao-btn-rollback',function(){
                var b=$(this),id=b.data('id');if(!confirm('↩️ Undo #'+id+'?'))return;b.prop('disabled',true).text('⏳...');
                $.post(A,{action:'dba_ao_rollback',nonce:N,post_id:id},function(r){if(r.success&&r.data&&r.data.success)b.text('✅').css('color','#059669');else b.text('❌').css('color','#dc2626');});
            });

            // ── SAVE SETTINGS ──
            $('#btn-save').on('click',function(){
                $.post(A,{action:'dba_ao_save_settings',nonce:N,enabled:$('#s-enabled').is(':checked')?1:0,auto_fix:$('#s-autofix').is(':checked')?1:0,max_links:$('#s-maxlinks').val(),min_content_len:$('#s-mincontent').val(),email_report:$('#s-email').is(':checked')?1:0,email_address:$('#s-emailaddr').val()},function(r){$('#save-ok').text(r.success?'✅ Saved':'❌ Error').fadeIn().delay(2000).fadeOut();});
            });
        });
        </script>
        <?php
    }
}
