<?php
/**
 * Scanner tab — file-integrity overview, recent findings, settings.
 *
 * @package Brainwerk Security Suite
 */

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

// Local helper for the severity column. Defined once even if the view is
// re-included (defensive — WP admin sometimes does that during settings_errors).
if ( ! function_exists( 'shieldforge_scanner_severity_label' ) ) {
    function shieldforge_scanner_severity_label( $sev ) {
        switch ( (int) $sev ) {
            case Shieldforge_Logger::SEV_CRITICAL: return __( 'critical', 'brainwerk-security-suite' );
            case Shieldforge_Logger::SEV_HIGH:     return __( 'high', 'brainwerk-security-suite' );
            case Shieldforge_Logger::SEV_WARN:     return __( 'warn', 'brainwerk-security-suite' );
            default:                               return __( 'info', 'brainwerk-security-suite' );
        }
    }
}

// Manual actions: rebuild baseline / run-scan-now / acknowledge.
// Each is gated on its own nonce + the standard cap so the form posts can't
// be abused from outside the admin.
if ( ! empty( $_POST['shieldforge_scanner_action'] ) && check_admin_referer( 'shieldforge_scanner' ) && current_user_can( Shieldforge_Admin::CAP ) ) {
    $action = sanitize_key( wp_unslash( $_POST['shieldforge_scanner_action'] ) );
    switch ( $action ) {
        case 'reset_baseline':
            Shieldforge_Scanner::reset();
            add_settings_error( 'brainwerk-security-suite', 'sf_scanner_reset', __( 'Baseline cleared. The next scheduled scan will rebuild it.', 'brainwerk-security-suite' ), 'updated' );
            break;
        case 'rebuild_now':
            Shieldforge_Scanner::reset();
            $stats = Shieldforge_Scanner::build_baseline();
            add_settings_error( 'brainwerk-security-suite', 'sf_scanner_rebuild', sprintf(
                /* translators: 1: hashed files this run, 2: errors, 3: finished bool */
                esc_html__( 'Baseline run: %1$d files hashed, %2$d errors, finished: %3$s.', 'brainwerk-security-suite' ),
                (int) $stats['hashed'],
                (int) $stats['errors'],
                ! empty( $stats['finished'] ) ? esc_html__( 'yes', 'brainwerk-security-suite' ) : esc_html__( 'no (continues next cron tick)', 'brainwerk-security-suite' )
            ), 'updated' );
            break;
        case 'scan_now':
            $stats = Shieldforge_Scanner::scan_now();
            add_settings_error( 'brainwerk-security-suite', 'sf_scanner_scan', sprintf(
                /* translators: %1$d scanned, %2$d added, %3$d changed, %4$d missing, %5$d malware suspects */
                esc_html__( 'Scan run: %1$d files scanned, %2$d added, %3$d changed, %4$d missing, %5$d suspicious-pattern hits.', 'brainwerk-security-suite' ),
                (int) $stats['scanned'],
                (int) $stats['added'],
                (int) $stats['changed'],
                (int) $stats['missing'],
                (int) $stats['malware']
            ), 'updated' );
            break;
        case 'whitelist_path':
            $path = isset( $_POST['shieldforge_scanner_path'] ) ? sanitize_text_field( wp_unslash( $_POST['shieldforge_scanner_path'] ) ) : '';
            $abs  = Shieldforge_Scanner::resolve_path( $path );
            if ( $abs && Shieldforge_Scanner::whitelist_path( $abs ) ) {
                add_settings_error( 'brainwerk-security-suite', 'sf_scanner_wl', sprintf(
                    /* translators: %s: path */
                    esc_html__( 'Path whitelisted: %s', 'brainwerk-security-suite' ),
                    '<code>' . esc_html( $path ) . '</code>'
                ), 'updated' );
            }
            break;
        case 'rebaseline_path':
            $path = isset( $_POST['shieldforge_scanner_path'] ) ? sanitize_text_field( wp_unslash( $_POST['shieldforge_scanner_path'] ) ) : '';
            $abs  = Shieldforge_Scanner::resolve_path( $path );
            if ( $abs && Shieldforge_Scanner::rebaseline_path( $abs ) ) {
                add_settings_error( 'brainwerk-security-suite', 'sf_scanner_rb', sprintf(
                    /* translators: %s: path */
                    esc_html__( 'Re-baselined: %s', 'brainwerk-security-suite' ),
                    '<code>' . esc_html( $path ) . '</code>'
                ), 'updated' );
            }
            break;
    }
}

$status     = Shieldforge_Scanner::status();
$summary24  = Shieldforge_Scanner::findings_summary( 24 );
$summary7d  = Shieldforge_Scanner::findings_summary( 168 );
$findings   = Shieldforge_Scanner::recent_findings( 168, 100 );

$enabled            = (bool) Shieldforge_Settings::get( 'scanner_enabled', true );
$pattern_enabled    = (bool) Shieldforge_Settings::get( 'scanner_pattern_enabled', true );
$max_kb             = (int) Shieldforge_Settings::get( 'scanner_max_file_kb', 4096 );
$skip_dirs          = (array) Shieldforge_Settings::get( 'scanner_skip_dirs', array() );
$extensions         = (array) Shieldforge_Settings::get( 'scanner_extensions', array( 'php', 'phtml', 'phar', 'inc' ) );

$threat_data    = Shieldforge_Threat_Intel::build_digest();
$threat_score   = (int) $threat_data['score']['score'];
$threat_label   = (string) $threat_data['score']['label'];

$next_run_human = $status['next_run'] ? human_time_diff( time(), (int) $status['next_run'] ) : esc_html__( 'not scheduled', 'brainwerk-security-suite' );
$last_scan      = $status['last_scan_at'] ? $status['last_scan_at'] . ' UTC' : __( 'never', 'brainwerk-security-suite' );
$last_baseline  = $status['last_baseline_at'] ? $status['last_baseline_at'] . ' UTC' : __( 'never', 'brainwerk-security-suite' );
?>
<div class="sf-threat-header is-<?php echo esc_attr( $threat_label ); ?>">
    <div class="sf-threat-score"><?php echo esc_html( $threat_score ); ?></div>
    <div style="flex:1; min-width:0">
        <div class="sf-threat-label"><?php echo esc_html( strtoupper( $threat_label ) ); ?></div>
        <div class="sf-threat-meta">
            <?php
            printf(
                /* translators: 1: changed, 2: added, 3: missing, 4: malware-suspect (24h) */
                esc_html__( 'Last 24h: %1$d changed, %2$d added, %3$d missing, %4$d suspicious patterns.', 'brainwerk-security-suite' ),
                (int) $summary24['changed'],
                (int) $summary24['added'],
                (int) $summary24['missing'],
                (int) $summary24['malware']
            );
            ?>
        </div>
    </div>
    <div class="sf-threat-bar"><span style="width: <?php echo (int) $threat_score; ?>%"></span></div>
</div>

<div class="shieldforge-card">
    <h2><?php esc_html_e( 'File-Integrity Monitor', 'brainwerk-security-suite' ); ?></h2>
    <p class="muted">
        <?php esc_html_e( 'Hashes every PHP file under WordPress core, plugins, mu-plugins and themes, then re-checks them daily. Detects added, modified or deleted files and runs a suspicious-pattern scan against new and modified files.', 'brainwerk-security-suite' ); ?>
        <strong><?php esc_html_e( 'All scanning is local — no file contents leave your server.', 'brainwerk-security-suite' ); ?></strong>
    </p>

    <table class="widefat striped" style="max-width:680px">
        <tbody>
            <tr><th scope="row" style="width:40%"><?php esc_html_e( 'Tracked files', 'brainwerk-security-suite' ); ?></th><td><strong><?php echo esc_html( number_format_i18n( $status['tracked_files'] ) ); ?></strong></td></tr>
            <tr><th scope="row"><?php esc_html_e( 'Phase', 'brainwerk-security-suite' ); ?></th><td><code><?php echo esc_html( $status['phase'] ); ?></code><?php if ( $status['cursor'] > 0 ) echo ' — ' . esc_html( sprintf( __( 'cursor at file #%d', 'brainwerk-security-suite' ), $status['cursor'] ) ); ?></td></tr>
            <tr><th scope="row"><?php esc_html_e( 'Last scan', 'brainwerk-security-suite' ); ?></th><td><?php echo esc_html( $last_scan ); ?></td></tr>
            <tr><th scope="row"><?php esc_html_e( 'Last baseline build', 'brainwerk-security-suite' ); ?></th><td><?php echo esc_html( $last_baseline ); ?></td></tr>
            <tr><th scope="row"><?php esc_html_e( 'Next scheduled run', 'brainwerk-security-suite' ); ?></th><td><?php echo esc_html( $next_run_human ); ?></td></tr>
        </tbody>
    </table>

    <form method="post" action="" style="margin-top:14px; display:flex; gap:8px; flex-wrap:wrap">
        <?php wp_nonce_field( 'shieldforge_scanner' ); ?>
        <button type="submit" name="shieldforge_scanner_action" value="scan_now" class="button button-primary"><?php esc_html_e( 'Run scan now', 'brainwerk-security-suite' ); ?></button>
        <button type="submit" name="shieldforge_scanner_action" value="rebuild_now" class="button"><?php esc_html_e( 'Rebuild baseline', 'brainwerk-security-suite' ); ?></button>
        <button type="submit" name="shieldforge_scanner_action" value="reset_baseline" class="button" onclick="return confirm('<?php echo esc_js( __( 'Clear the entire baseline?', 'brainwerk-security-suite' ) ); ?>');"><?php esc_html_e( 'Clear baseline', 'brainwerk-security-suite' ); ?></button>
    </form>
    <p class="description" style="margin-top:6px">
        <?php esc_html_e( 'Manual runs are time-budgeted to ~45s. Long sites resume on the next cron tick.', 'brainwerk-security-suite' ); ?>
    </p>
</div>

<div class="shieldforge-card">
    <h2><?php esc_html_e( 'Findings (last 7 days)', 'brainwerk-security-suite' ); ?></h2>
    <p>
        <?php
        printf(
            /* translators: 1: changed, 2: added, 3: missing, 4: malware-suspect */
            esc_html__( '%1$d changed · %2$d added · %3$d missing · %4$d suspicious patterns.', 'brainwerk-security-suite' ),
            (int) $summary7d['changed'],
            (int) $summary7d['added'],
            (int) $summary7d['missing'],
            (int) $summary7d['malware']
        );
        ?>
    </p>

    <?php if ( empty( $findings ) ) : ?>
        <div class="sf-empty-state">
            <div class="sf-empty-icon dashicons dashicons-search"></div>
            <h3><?php esc_html_e( 'No file-integrity findings yet — that\'s good news.', 'brainwerk-security-suite' ); ?></h3>
            <?php if ( 0 === (int) $status['tracked_files'] ) : ?>
                <p><?php esc_html_e( 'No baseline has been built yet. The scanner needs to fingerprint every PHP file once before it can detect changes. The first scheduled scan runs at 03:30, or you can build it on demand.', 'brainwerk-security-suite' ); ?></p>
                <form method="post" action="" style="display:inline">
                    <?php wp_nonce_field( 'shieldforge_scanner' ); ?>
                    <button type="submit" name="shieldforge_scanner_action" value="rebuild_now" class="button button-primary"><?php esc_html_e( 'Rebuild baseline now', 'brainwerk-security-suite' ); ?></button>
                </form>
            <?php else : ?>
                <p><?php
                    /* translators: %s: tracked files count */
                    printf( esc_html__( 'The baseline is in place (%s files tracked) and the daily scan has nothing unusual to report.', 'brainwerk-security-suite' ), '<strong>' . esc_html( number_format_i18n( $status['tracked_files'] ) ) . '</strong>' );
                ?></p>
                <form method="post" action="" style="display:inline">
                    <?php wp_nonce_field( 'shieldforge_scanner' ); ?>
                    <button type="submit" name="shieldforge_scanner_action" value="scan_now" class="button"><?php esc_html_e( 'Re-scan now anyway', 'brainwerk-security-suite' ); ?></button>
                </form>
            <?php endif; ?>
        </div>
    <?php else : ?>
        <table class="widefat striped">
            <thead>
                <tr>
                    <th><?php esc_html_e( 'When', 'brainwerk-security-suite' ); ?></th>
                    <th><?php esc_html_e( 'Type', 'brainwerk-security-suite' ); ?></th>
                    <th><?php esc_html_e( 'Path / Detail', 'brainwerk-security-suite' ); ?></th>
                    <th><?php esc_html_e( 'Severity', 'brainwerk-security-suite' ); ?></th>
                    <th><?php esc_html_e( 'Actions', 'brainwerk-security-suite' ); ?></th>
                </tr>
            </thead>
            <tbody>
                <?php foreach ( $findings as $f ) :
                    $ctx        = is_array( $f->ctx ) ? $f->ctx : array();
                    $path_disp  = isset( $ctx['path'] ) ? (string) $ctx['path'] : '';
                    $type_label = str_replace( '_', ' ', (string) $f->event_type );
                    $sev_class  = 'sf-sev sf-sev-' . (int) $f->severity;
                ?>
                    <tr>
                        <td><code><?php echo esc_html( $f->created_at ); ?></code></td>
                        <td><span class="sf-event-type"><?php echo esc_html( $type_label ); ?></span></td>
                        <td>
                            <code><?php echo esc_html( $path_disp ); ?></code>
                            <?php if ( Shieldforge_Logger::EVT_MALWARE_SUSPECT === $f->event_type && ! empty( $ctx['rule'] ) ) : ?>
                                <div class="muted" style="font-size:11px; margin-top:4px">
                                    <?php
                                    printf(
                                        /* translators: 1: rule id, 2: line number */
                                        esc_html__( 'rule: %1$s · line %2$d', 'brainwerk-security-suite' ),
                                        '<strong>' . esc_html( $ctx['rule'] ) . '</strong>',
                                        (int) ( $ctx['line'] ?? 0 )
                                    );
                                    ?>
                                </div>
                                <?php if ( ! empty( $ctx['snippet'] ) ) : ?>
                                    <pre style="margin:4px 0 0; padding:4px; background:#fafafa; border:1px solid #eee; font-size:11px; overflow-x:auto; max-width:520px"><?php echo esc_html( $ctx['snippet'] ); ?></pre>
                                <?php endif; ?>
                            <?php elseif ( Shieldforge_Logger::EVT_FILE_CHANGED === $f->event_type ) : ?>
                                <div class="muted" style="font-size:11px; margin-top:4px">
                                    <?php printf( esc_html__( 'size: %1$d → %2$d bytes', 'brainwerk-security-suite' ), (int) ( $ctx['size_old'] ?? 0 ), (int) ( $ctx['size_new'] ?? 0 ) ); ?>
                                </div>
                            <?php endif; ?>
                        </td>
                        <td><span class="<?php echo esc_attr( $sev_class ); ?>"><?php echo esc_html( shieldforge_scanner_severity_label( (int) $f->severity ) ); ?></span></td>
                        <td>
                            <?php if ( '' !== $path_disp ) : ?>
                                <form method="post" action="" style="display:inline">
                                    <?php wp_nonce_field( 'shieldforge_scanner' ); ?>
                                    <input type="hidden" name="shieldforge_scanner_path" value="<?php echo esc_attr( $path_disp ); ?>">
                                    <button type="submit" name="shieldforge_scanner_action" value="rebaseline_path" class="button-link" title="<?php esc_attr_e( 'Accept current state as the new baseline', 'brainwerk-security-suite' ); ?>"><?php esc_html_e( 'Re-baseline', 'brainwerk-security-suite' ); ?></button>
                                </form>
                                ·
                                <form method="post" action="" style="display:inline">
                                    <?php wp_nonce_field( 'shieldforge_scanner' ); ?>
                                    <input type="hidden" name="shieldforge_scanner_path" value="<?php echo esc_attr( $path_disp ); ?>">
                                    <button type="submit" name="shieldforge_scanner_action" value="whitelist_path" class="button-link" title="<?php esc_attr_e( 'Stop alerting for this path', 'brainwerk-security-suite' ); ?>"><?php esc_html_e( 'Whitelist', 'brainwerk-security-suite' ); ?></button>
                                </form>
                            <?php endif; ?>
                        </td>
                    </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    <?php endif; ?>
</div>

<div class="shieldforge-card">
    <h2><?php esc_html_e( 'Scanner settings', 'brainwerk-security-suite' ); ?></h2>
    <form method="post" action="">
        <?php wp_nonce_field( Shieldforge_Admin::NONCE ); ?>
        <input type="hidden" name="shieldforge_action" value="save_settings">
        <input type="hidden" name="shieldforge_tab_keys[]" value="scanner_enabled">
        <input type="hidden" name="shieldforge_tab_keys[]" value="scanner_pattern_enabled">

        <table class="form-table" role="presentation">
            <tr>
                <th scope="row"><?php esc_html_e( 'Enable scanner', 'brainwerk-security-suite' ); ?></th>
                <td>
                    <label class="sf-toggle">
                        <input type="checkbox" name="shieldforge[scanner_enabled]" value="1" <?php checked( $enabled ); ?>>
                        <?php esc_html_e( 'Run the daily integrity scan via wp-cron.', 'brainwerk-security-suite' ); ?>
                    </label>
                </td>
            </tr>
            <tr>
                <th scope="row"><?php esc_html_e( 'Pattern scanner', 'brainwerk-security-suite' ); ?></th>
                <td>
                    <label class="sf-toggle">
                        <input type="checkbox" name="shieldforge[scanner_pattern_enabled]" value="1" <?php checked( $pattern_enabled ); ?>>
                        <?php esc_html_e( 'Also run suspicious-code pattern checks against new and modified files.', 'brainwerk-security-suite' ); ?>
                    </label>
                </td>
            </tr>
            <tr>
                <th scope="row"><?php esc_html_e( 'Max file size (KB)', 'brainwerk-security-suite' ); ?></th>
                <td>
                    <input type="number" name="shieldforge[scanner_max_file_kb]" value="<?php echo esc_attr( $max_kb ); ?>" min="1" max="65536" class="small-text">
                    <p class="description"><?php esc_html_e( 'Files larger than this are skipped (cheap defense against accidental scanning of huge data dumps).', 'brainwerk-security-suite' ); ?></p>
                </td>
            </tr>
            <tr>
                <th scope="row"><?php esc_html_e( 'Extra skip directories', 'brainwerk-security-suite' ); ?></th>
                <td>
                    <textarea name="shieldforge[scanner_skip_dirs]" rows="4" class="large-text code" placeholder="wp-content/cache-custom"><?php echo esc_textarea( implode( "\n", $skip_dirs ) ); ?></textarea>
                    <p class="description"><?php esc_html_e( 'One path segment per line, relative to the WordPress root. Sensible defaults already cover uploads/, cache/, .git, node_modules and the like.', 'brainwerk-security-suite' ); ?></p>
                </td>
            </tr>
            <tr>
                <th scope="row"><?php esc_html_e( 'Tracked extensions', 'brainwerk-security-suite' ); ?></th>
                <td>
                    <textarea name="shieldforge[scanner_extensions]" rows="3" class="large-text code"><?php echo esc_textarea( implode( "\n", $extensions ) ); ?></textarea>
                    <p class="description"><?php esc_html_e( 'One extension per line. Default: php, phtml, phar, inc. .htaccess and wp-config.php are always tracked.', 'brainwerk-security-suite' ); ?></p>
                </td>
            </tr>
        </table>

        <p>
            <button type="submit" class="button button-primary"><?php esc_html_e( 'Save', 'brainwerk-security-suite' ); ?></button>
        </p>
    </form>
</div>

<?php
// ---------------------------------------------------------------------------
// Repo-Integrität (v0.15): Plugins/Themes gegen wp.org-Original (Detection-only)
// ---------------------------------------------------------------------------
$sf_repo_report  = Shieldforge_Repo_Integrity::get_report();
$sf_repo_enabled = (bool) Shieldforge_Settings::get( 'repo_integrity_enabled', false );
?>
<div class="shieldforge-card">
    <h2><?php esc_html_e( 'Repo integrity — plugins & themes vs. wordpress.org', 'brainwerk-security-suite' ); ?></h2>
    <p class="description">
        <?php esc_html_e( 'Compares every installed plugin (official checksums API) and theme (original release ZIP) against the wordpress.org distribution. Modified, missing or extra files are reported so you can react. Packages that are not hosted on wordpress.org are listed as "unverifiable" and never touched.', 'brainwerk-security-suite' ); ?>
    </p>
    <p class="description">
        <?php esc_html_e( 'To restore a tampered package, reinstall it the standard WordPress way — deactivate & delete it, then install the clean copy from wordpress.org (your settings are kept in the database).', 'brainwerk-security-suite' ); ?>
        <a href="<?php echo esc_url( admin_url( 'plugin-install.php' ) ); ?>"><?php esc_html_e( 'Add / reinstall plugins', 'brainwerk-security-suite' ); ?></a>
    </p>

    <p>
        <button type="button" class="button button-primary" id="sf-run-repo-integrity"><?php esc_html_e( 'Scan now', 'brainwerk-security-suite' ); ?></button>
        <span id="sf-repo-integrity-status" style="margin-left:8px;"></span>
    </p>

    <form method="post" action="">
        <?php wp_nonce_field( Shieldforge_Admin::NONCE ); ?>
        <input type="hidden" name="shieldforge_action" value="save_settings">
        <input type="hidden" name="shieldforge_tab_keys[]" value="repo_integrity_enabled">
        <p>
            <label>
                <input type="checkbox" name="shieldforge[repo_integrity_enabled]" value="1" <?php checked( $sf_repo_enabled ); ?>>
                <?php esc_html_e( 'Run automatically every night (daily cron, 03:40)', 'brainwerk-security-suite' ); ?>
            </label>
            <button type="submit" class="button" style="margin-left:8px;"><?php esc_html_e( 'Save', 'brainwerk-security-suite' ); ?></button>
        </p>
    </form>

    <?php if ( $sf_repo_report ) :
        $sum = $sf_repo_report['summary']; ?>
        <p>
            <strong><?php esc_html_e( 'Last scan:', 'brainwerk-security-suite' ); ?></strong>
            <?php echo esc_html( $sf_repo_report['checked_at'] ); ?> —
            <?php
            printf(
                /* translators: 1: ok count, 2: mismatch count, 3: unverifiable count, 4: flagged file count */
                esc_html__( '%1$d packages clean, %2$d with deviations (%4$d files), %3$d unverifiable.', 'brainwerk-security-suite' ),
                (int) $sum['ok'],
                (int) $sum['mismatch'],
                (int) $sum['unverifiable'],
                (int) $sum['files_flagged']
            );
            ?>
        </p>

        <?php
        $flagged = array_filter( $sf_repo_report['items'], function ( $i ) { return 'mismatch' === $i['status']; } );
        if ( empty( $flagged ) ) : ?>
            <p style="color:#2e8b3e;"><strong>✓ <?php esc_html_e( 'All verifiable packages match the official wordpress.org distribution.', 'brainwerk-security-suite' ); ?></strong></p>
        <?php else : ?>
            <table class="widefat striped">
                <thead>
                    <tr>
                        <th><?php esc_html_e( 'Package', 'brainwerk-security-suite' ); ?></th>
                        <th><?php esc_html_e( 'File', 'brainwerk-security-suite' ); ?></th>
                        <th><?php esc_html_e( 'Finding', 'brainwerk-security-suite' ); ?></th>
                        <th><?php esc_html_e( 'Action', 'brainwerk-security-suite' ); ?></th>
                    </tr>
                </thead>
                <tbody>
                <?php foreach ( $flagged as $item ) :
                    $rows = array();
                    foreach ( $item['modified'] as $f ) { $rows[] = array( $f, __( 'modified', 'brainwerk-security-suite' ), true ); }
                    foreach ( $item['missing'] as $f )  { $rows[] = array( $f, __( 'missing', 'brainwerk-security-suite' ), true ); }
                    foreach ( $item['extra'] as $f )    { $rows[] = array( $f, __( 'extra file (not in official package — inspect!)', 'brainwerk-security-suite' ), false ); }
                    foreach ( $rows as $row ) : ?>
                    <tr>
                        <td><?php echo esc_html( $item['name'] ); ?> <small>(<?php echo esc_html( $item['type'] . ' ' . $item['version'] ); ?>)</small></td>
                        <td><code><?php echo esc_html( $row[0] ); ?></code></td>
                        <td><?php echo esc_html( $row[1] ); ?></td>
                        <td>
                            <?php if ( $row[2] ) : ?>
                                <em><?php esc_html_e( 'reinstall package', 'brainwerk-security-suite' ); ?></em>
                            <?php else : ?>
                                <em><?php esc_html_e( 'manual review', 'brainwerk-security-suite' ); ?></em>
                            <?php endif; ?>
                        </td>
                    </tr>
                    <?php endforeach; ?>
                <?php endforeach; ?>
                </tbody>
            </table>
        <?php endif; ?>

        <?php
        $unverifiable = array_filter( $sf_repo_report['items'], function ( $i ) { return 'mismatch' !== $i['status'] && 'ok' !== $i['status']; } );
        if ( ! empty( $unverifiable ) ) : ?>
            <details style="margin-top:10px;">
                <summary style="cursor:pointer;"><?php
                /* translators: %d: package count */
                echo esc_html( sprintf( __( '%d packages not verifiable (not on wordpress.org)', 'brainwerk-security-suite' ), count( $unverifiable ) ) ); ?></summary>
                <ul style="margin:8px 0 0 18px;">
                    <?php foreach ( $unverifiable as $item ) : ?>
                        <li><code><?php echo esc_html( $item['slug'] ); ?></code> (<?php echo esc_html( $item['type'] ); ?>)<?php echo isset( $item['note'] ) ? ' — ' . esc_html( $item['note'] ) : ''; ?></li>
                    <?php endforeach; ?>
                </ul>
            </details>
        <?php endif; ?>
    <?php else : ?>
        <p><em><?php esc_html_e( 'No scan yet — click "Scan now" for the first run.', 'brainwerk-security-suite' ); ?></em></p>
    <?php endif; ?>
</div>

<?php
// Repo-integrity AJAX runner — delivered via wp_add_inline_script() (helper)
// rather than a raw <script> tag. Nonce + strings ride in a JSON config.
$ri_cfg = array(
    'nonce' => wp_create_nonce( 'shieldforge_admin' ),
    'i18n'  => array(
        'scanning' => __( 'Scanning… themes are downloaded once for comparison, this can take a minute.', 'brainwerk-security-suite' ),
        'failed'   => __( 'Scan failed.', 'brainwerk-security-suite' ),
    ),
);
$ri_js = 'var SF_RI = ' . wp_json_encode( $ri_cfg ) . ";\n" . <<<'JS'
(function () {
    var btn = document.getElementById('sf-run-repo-integrity');
    if (!btn) return;
    btn.addEventListener('click', function () {
        var out = document.getElementById('sf-repo-integrity-status');
        btn.disabled = true;
        out.textContent = SF_RI.i18n.scanning;
        var fd = new FormData();
        fd.append('action', 'shieldforge_repo_integrity');
        fd.append('nonce', SF_RI.nonce);
        fetch(ajaxurl, { method: 'POST', body: fd, credentials: 'same-origin' })
            .then(function (r) { return r.json(); })
            .then(function (r) {
                if (r && r.ok) { window.location.reload(); return; }
                btn.disabled = false;
                out.textContent = SF_RI.i18n.failed;
            })
            .catch(function () {
                btn.disabled = false;
                out.textContent = SF_RI.i18n.failed;
            });
    });
})();
JS;
Shieldforge_Utils::enqueue_inline_script( 'shieldforge-scanner-repo', $ri_js );
?>

