<?php
/**
 * Extra Modules — settings + viewers for the optional protection modules.
 * Strukturiert in Cards, je Modul ein Toggle + Konfiguration.
 *
 * @package Brainwerk Security Suite
 */
if ( ! defined( 'ABSPATH' ) ) exit;
if ( ! current_user_can( 'manage_options' ) ) return;

// Notice-Banner für Status-Messages
if ( isset( $_GET['shieldforge_modules_saved'] ) ) {
    echo '<div class="notice notice-success is-dismissible"><p>✓ ' . esc_html__( 'Einstellungen gespeichert.', 'brainwerk-security-suite' ) . '</p></div>';
}
if ( isset( $_GET['shieldforge_privacy_msg'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only GET (status message selector); no state change; page is capability-gated.
    $msg = sanitize_key( wp_unslash( $_GET['shieldforge_privacy_msg'] ) );
    $txt = ( 'export_sent' === $msg ) ? __( 'Export-Anfrage versendet — User bekommt Bestätigungsmail mit Download-Link.', 'brainwerk-security-suite' ) : __( 'Lösch-Anfrage versendet — User bekommt Bestätigungsmail.', 'brainwerk-security-suite' );
    echo '<div class="notice notice-info is-dismissible"><p>✓ ' . esc_html( $txt ) . '</p></div>';
}

$s = function ( $k, $d = false ) { return Shieldforge_Settings::get( $k, $d ); };
// The .sf-v12-* card styles live in assets/css/admin.css (enqueued on every
// plugin page) — no inline <style> block here.
?>

<form method="post" action="">
    <?php wp_nonce_field( 'shieldforge_modules_save' ); ?>
    <input type="hidden" name="action" value="shieldforge_modules_save">

    <h2 style="margin-top: 14px;">🛡 <?php esc_html_e( 'Extra Modules', 'brainwerk-security-suite' ); ?></h2>
    <p style="font-size: 13px; color: #50575e;"><?php esc_html_e( '9 zusätzliche Module für Defense-in-Depth. Alle standardmäßig OFF. Per Toggle einzeln scharf schalten.', 'brainwerk-security-suite' ); ?></p>

    <div class="sf-v12-grid">

        <!-- HEADERS -->
        <div class="sf-v12-card">
            <h2>🛡 <?php esc_html_e( 'HTTP-Security-Headers', 'brainwerk-security-suite' ); ?> <span class="status <?php echo $s('headers_enabled') ? 'on' : 'off'; ?>"><?php echo $s('headers_enabled') ? esc_html__( 'AN', 'brainwerk-security-suite' ) : esc_html__( 'AUS', 'brainwerk-security-suite' ); ?></span></h2>
            <p class="hint"><?php esc_html_e( 'Sendet OWASP-empfohlene Response-Header: X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, HSTS, COOP, CORP. Empfohlen: alle an.', 'brainwerk-security-suite' ); ?></p>
            <label class="row"><input type="checkbox" name="sf[headers_enabled]" value="1" <?php checked( $s('headers_enabled') ); ?>> <strong><?php esc_html_e( 'Modul aktiv', 'brainwerk-security-suite' ); ?></strong></label>
            <label class="row"><input type="checkbox" name="sf[headers_x_frame]" value="1" <?php checked( $s('headers_x_frame', true) ); ?>> <?php esc_html_e( 'X-Frame-Options: SAMEORIGIN (Clickjacking-Schutz)', 'brainwerk-security-suite' ); ?></label>
            <label class="row"><input type="checkbox" name="sf[headers_x_content_type]" value="1" <?php checked( $s('headers_x_content_type', true) ); ?>> <?php esc_html_e( 'X-Content-Type-Options: nosniff (MIME-Sniffing)', 'brainwerk-security-suite' ); ?></label>
            <label class="row"><input type="checkbox" name="sf[headers_referrer_policy]" value="1" <?php checked( $s('headers_referrer_policy', true) ); ?>> <?php esc_html_e( 'Referrer-Policy: strict-origin-when-cross-origin', 'brainwerk-security-suite' ); ?></label>
            <label class="row"><input type="checkbox" name="sf[headers_permissions_policy]" value="1" <?php checked( $s('headers_permissions_policy', true) ); ?>> <?php esc_html_e( 'Permissions-Policy (Kamera/Mikro/GPS deny)', 'brainwerk-security-suite' ); ?></label>
            <label class="row"><input type="checkbox" name="sf[headers_hsts]" value="1" <?php checked( $s('headers_hsts', true) ); ?>> <?php esc_html_e( 'Strict-Transport-Security (nur HTTPS)', 'brainwerk-security-suite' ); ?></label>
            <label class="row"><input type="checkbox" name="sf[headers_coop]" value="1" <?php checked( $s('headers_coop', true) ); ?>> <?php esc_html_e( 'Cross-Origin-Opener-Policy: same-origin', 'brainwerk-security-suite' ); ?></label>
            <label class="row"><input type="checkbox" name="sf[headers_corp]" value="1" <?php checked( $s('headers_corp', true) ); ?>> <?php esc_html_e( 'Cross-Origin-Resource-Policy: same-site', 'brainwerk-security-suite' ); ?></label>
        </div>

        <!-- PWNED CHECK -->
        <div class="sf-v12-card">
            <h2>🔑 <?php esc_html_e( 'HaveIBeenPwned-Passwort-Check', 'brainwerk-security-suite' ); ?> <span class="status <?php echo $s('pwned_check_enabled') ? 'on' : 'off'; ?>"><?php echo $s('pwned_check_enabled') ? esc_html__( 'AN', 'brainwerk-security-suite' ) : esc_html__( 'AUS', 'brainwerk-security-suite' ); ?></span></h2>
            <p class="hint"><?php echo wp_kses( __( 'Prüft neue Passwörter gegen ~12 Mrd. geleakte Passwörter. <strong>Privacy via k-Anonymity</strong>: nur SHA1-Präfix wird gesendet — HIBP sieht NIE das echte Passwort.', 'brainwerk-security-suite' ), array( 'strong' => array(), 'code' => array(), 'em' => array() ) ); ?></p>
            <label class="row"><input type="checkbox" name="sf[pwned_check_enabled]" value="1" <?php checked( $s('pwned_check_enabled') ); ?>> <?php echo wp_kses( __( '<strong>Modul aktiv</strong> — User mit kompromittiertem Passwort werden zur Änderung gezwungen', 'brainwerk-security-suite' ), array( 'strong' => array(), 'code' => array(), 'em' => array() ) ); ?></label>
        </div>

        <!-- TRUSTED DEVICES -->
        <div class="sf-v12-card">
            <h2>📱 <?php esc_html_e( 'Trusted Devices', 'brainwerk-security-suite' ); ?> <span class="status <?php echo $s('trusted_devices_enabled') ? 'on' : 'off'; ?>"><?php echo $s('trusted_devices_enabled') ? esc_html__( 'AN', 'brainwerk-security-suite' ) : esc_html__( 'AUS', 'brainwerk-security-suite' ); ?></span></h2>
            <p class="hint"><?php echo wp_kses( __( 'Fingerprint = SHA256(UA + IP-Subnet + Accept-Language). Bei Login von <strong>neuem Gerät</strong>: Mail-Benachrichtigung an User (Account-Takeover-Frühwarnung). Max 20 Devices/User.', 'brainwerk-security-suite' ), array( 'strong' => array(), 'code' => array(), 'em' => array() ) ); ?></p>
            <label class="row"><input type="checkbox" name="sf[trusted_devices_enabled]" value="1" <?php checked( $s('trusted_devices_enabled') ); ?>> <strong><?php esc_html_e( 'Modul aktiv', 'brainwerk-security-suite' ); ?></strong></label>
        </div>

        <!-- LIVE TRAFFIC -->
        <div class="sf-v12-card">
            <h2>📡 <?php esc_html_e( 'Live Traffic Monitor', 'brainwerk-security-suite' ); ?> <span class="status <?php echo $s('live_traffic_enabled') ? 'on' : 'off'; ?>"><?php echo $s('live_traffic_enabled') ? esc_html__( 'AN', 'brainwerk-security-suite' ) : esc_html__( 'AUS', 'brainwerk-security-suite' ); ?></span></h2>
            <p class="hint"><?php esc_html_e( 'Speichert letzte 1000 „interessante" Requests (Login, POST, Admin, AJAX, XML-RPC) für Forensik. Ring-Buffer — auto-cleanup.', 'brainwerk-security-suite' ); ?></p>
            <label class="row"><input type="checkbox" name="sf[live_traffic_enabled]" value="1" <?php checked( $s('live_traffic_enabled') ); ?>> <strong><?php esc_html_e( 'Modul aktiv', 'brainwerk-security-suite' ); ?></strong></label>
            <?php if ( $s('live_traffic_enabled') && class_exists( 'Shieldforge_Live_Traffic' ) ) :
                $recent = Shieldforge_Live_Traffic::recent( 10 );
                if ( $recent ) : ?>
                <details style="margin-top: 10px;"><summary style="cursor: pointer; font-size: 13px; font-weight: 600;"><?php esc_html_e( 'Letzte 10 Requests anzeigen', 'brainwerk-security-suite' ); ?></summary>
                    <table class="sf-v12-table">
                        <thead><tr><th><?php esc_html_e( 'Zeit', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'Method', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'Pfad', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'IP', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'Status', 'brainwerk-security-suite' ); ?></th></tr></thead>
                        <tbody>
                            <?php foreach ( $recent as $r ) : ?>
                                <tr>
                                    <td><?php echo esc_html( substr( $r['created_at'], 11, 8 ) ); ?></td>
                                    <td><code><?php echo esc_html( $r['method'] ); ?></code></td>
                                    <td><?php echo esc_html( mb_strimwidth( $r['url_path'], 0, 50, '…' ) ); ?></td>
                                    <td><code><?php echo esc_html( $r['ip_anon'] ); ?></code></td>
                                    <td><?php echo (int) $r['status_code']; ?></td>
                                </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </details>
            <?php endif; endif; ?>
        </div>

        <!-- CORE COMPARE -->
        <div class="sf-v12-card">
            <h2>🔍 <?php esc_html_e( 'Core-File-Compare', 'brainwerk-security-suite' ); ?> <span class="status on"><?php esc_html_e( 'aktiv (manual)', 'brainwerk-security-suite' ); ?></span></h2>
            <p class="hint"><?php echo wp_kses( __( 'Vergleicht alle WordPress-Core-Files (wp-admin/, wp-includes/) gegen das offizielle MD5-Manifest von wordpress.org. Findet modifizierte / fehlende / extra Files. <strong>Datenschutz</strong>: kein Upload, alles lokal.', 'brainwerk-security-suite' ), array( 'strong' => array(), 'code' => array(), 'em' => array() ) ); ?></p>
            <div class="sf-v12-runner">
                <button type="button" class="button button-primary" id="sf-run-core-compare">🔍 <?php esc_html_e( 'Jetzt Core-Files prüfen', 'brainwerk-security-suite' ); ?></button>
                <div id="sf-core-compare-result" style="margin-top: 10px; font-size: 12px;"></div>
            </div>
        </div>

        <!-- CAPTCHA -->
        <div class="sf-v12-card">
            <h2>🤖 <?php esc_html_e( 'CAPTCHA (hCaptcha / Turnstile)', 'brainwerk-security-suite' ); ?> <span class="status <?php echo $s('captcha_enabled') ? 'on' : 'off'; ?>"><?php echo $s('captcha_enabled') ? esc_html__( 'AN', 'brainwerk-security-suite' ) : esc_html__( 'AUS', 'brainwerk-security-suite' ); ?></span></h2>
            <p class="hint"><?php echo wp_kses( __( '<strong>Privacy-First:</strong> hCaptcha (EU-friendly) ODER Cloudflare Turnstile (kein Cookie) statt Google reCAPTCHA. Auf Login/Register/Lost-Password.', 'brainwerk-security-suite' ), array( 'strong' => array(), 'code' => array(), 'em' => array() ) ); ?></p>
            <label class="row"><input type="checkbox" name="sf[captcha_enabled]" value="1" <?php checked( $s('captcha_enabled') ); ?>> <strong><?php esc_html_e( 'Modul aktiv', 'brainwerk-security-suite' ); ?></strong></label>
            <label class="row"><?php esc_html_e( 'Provider:', 'brainwerk-security-suite' ); ?>
                <select name="sf[captcha_provider]" style="margin-left: 6px;">
                    <option value="hcaptcha"  <?php selected( $s('captcha_provider', 'hcaptcha'), 'hcaptcha' ); ?>><?php esc_html_e( 'hCaptcha (Empfehlung — EU)', 'brainwerk-security-suite' ); ?></option>
                    <option value="turnstile" <?php selected( $s('captcha_provider', 'hcaptcha'), 'turnstile' ); ?>><?php esc_html_e( 'Cloudflare Turnstile', 'brainwerk-security-suite' ); ?></option>
                </select>
            </label>
            <label class="row"><?php esc_html_e( 'Site-Key:', 'brainwerk-security-suite' ); ?> <input type="text" name="sf[captcha_site_key]" value="<?php echo esc_attr( $s('captcha_site_key', '') ); ?>" class="regular-text"></label>
            <label class="row"><?php esc_html_e( 'Secret-Key:', 'brainwerk-security-suite' ); ?> <input type="password" name="sf[captcha_secret_key]" value="<?php echo esc_attr( $s('captcha_secret_key', '') ); ?>" class="regular-text" autocomplete="off"></label>
            <p class="hint"><?php echo wp_kses( __( 'Site-Key + Secret-Key holen: <a href="https://www.hcaptcha.com/" target="_blank" rel="noopener">hCaptcha.com</a> (gratis) oder <a href="https://www.cloudflare.com/products/turnstile/" target="_blank" rel="noopener">Cloudflare Turnstile</a>.', 'brainwerk-security-suite' ), array( 'a' => array( 'href' => array(), 'target' => array(), 'rel' => array() ), 'strong' => array(), 'code' => array(), 'em' => array() ) ); ?></p>
        </div>

        <!-- MAGIC LINK -->
        <div class="sf-v12-card">
            <h2>✉️ <?php esc_html_e( 'Magic Login Links', 'brainwerk-security-suite' ); ?> <span class="status <?php echo $s('magic_link_enabled') ? 'on' : 'off'; ?>"><?php echo $s('magic_link_enabled') ? esc_html__( 'AN', 'brainwerk-security-suite' ) : esc_html__( 'AUS', 'brainwerk-security-suite' ); ?></span></h2>
            <p class="hint"><?php esc_html_e( 'Passwordless Login via E-Mail. User klickt „Magic-Link" am wp-login.php → bekommt 15-Min-gültigen Single-Use-Link per Mail. Rate-Limit: 3 Anforderungen/h. User-Enumeration-Schutz.', 'brainwerk-security-suite' ); ?></p>
            <label class="row"><input type="checkbox" name="sf[magic_link_enabled]" value="1" <?php checked( $s('magic_link_enabled') ); ?>> <?php echo wp_kses( __( '<strong>Modul aktiv</strong> (Mail-Versand muss funktionieren!)', 'brainwerk-security-suite' ), array( 'strong' => array(), 'code' => array(), 'em' => array() ) ); ?></label>
        </div>

        <!-- WAF -->
        <div class="sf-v12-card" style="border: 2px solid #cf222e;">
            <h2>🔥 <?php esc_html_e( 'WAF — Web Application Firewall', 'brainwerk-security-suite' ); ?> <span class="status <?php echo $s('waf_enabled') ? 'on' : 'off'; ?>"><?php echo $s('waf_enabled') ? esc_html__( 'AN', 'brainwerk-security-suite' ) : esc_html__( 'AUS', 'brainwerk-security-suite' ); ?></span></h2>
            <p class="hint"><?php echo wp_kses( __( '40+ kuratierte Regex-Signaturen für SQLi, XSS, LFI, RCE, SSRF, XXE, Cmdi, WP-User-Enum, Scanner-UAs. Blockiert mit 403. <strong>Kann False-Positives erzeugen</strong> — mit Level 1 starten, Whitelist pflegen.', 'brainwerk-security-suite' ), array( 'strong' => array(), 'code' => array(), 'em' => array() ) ); ?></p>
            <label class="row"><input type="checkbox" name="sf[waf_enabled]" value="1" <?php checked( $s('waf_enabled') ); ?>> <strong><?php esc_html_e( 'WAF aktiv', 'brainwerk-security-suite' ); ?></strong></label>
            <label class="row"><?php esc_html_e( 'Paranoia-Level:', 'brainwerk-security-suite' ); ?>
                <select name="sf[waf_paranoia_level]">
                    <option value="1" <?php selected( (int) $s('waf_paranoia_level', 1), 1 ); ?>><?php esc_html_e( '1 — Low (sicher, ~95 % Treffer, <0.1 % FP) ← Empfehlung', 'brainwerk-security-suite' ); ?></option>
                    <option value="2" <?php selected( (int) $s('waf_paranoia_level', 1), 2 ); ?>><?php esc_html_e( '2 — Medium (zusätzliche Heuristik)', 'brainwerk-security-suite' ); ?></option>
                    <option value="3" <?php selected( (int) $s('waf_paranoia_level', 1), 3 ); ?>><?php esc_html_e( '3 — High (aggressiv, FP-Whitelist nötig)', 'brainwerk-security-suite' ); ?></option>
                </select>
            </label>
            <label class="row"><input type="checkbox" name="sf[waf_whitelist_admins]" value="1" <?php checked( $s('waf_whitelist_admins', true) ); ?>> <?php esc_html_e( 'Admins (manage_options) von WAF ausnehmen', 'brainwerk-security-suite' ); ?></label>
            <label class="row"><input type="checkbox" name="sf[waf_autoblock_ip]" value="1" <?php checked( $s('waf_autoblock_ip', false) ); ?>> <?php esc_html_e( 'IP bei WAF-Treffer 24h sperren (sehr aggressiv!)', 'brainwerk-security-suite' ); ?></label>
            <label class="row" style="display:block;"><?php echo wp_kses( __( 'Pfad-Whitelist (eine Zeile pro Pfad — z. B. <code>/anmeldung/</code>):', 'brainwerk-security-suite' ), array( 'strong' => array(), 'code' => array(), 'em' => array() ) ); ?><br>
                <textarea name="sf[waf_path_whitelist]" rows="3" cols="40" style="font-family:monospace;font-size:12px;"><?php echo esc_textarea( implode( "\n", (array) $s( 'waf_path_whitelist', array() ) ) ); ?></textarea>
            </label>
        </div>

        <!-- WAF FALSE-POSITIVE-VIEWER -->
        <div class="sf-v12-card" style="grid-column: 1 / -1;">
            <h2>🔥 <?php esc_html_e( 'WAF — letzte Blocks & False-Positive-Whitelist', 'brainwerk-security-suite' ); ?></h2>
            <p class="hint"><?php echo wp_kses( __( 'Hier siehst du die letzten 30 WAF-Blocks. Wenn ein eigener legitimer Pfad fälschlich geblockt wurde, klicke „Whitelisten" — der Pfad wird in <code>waf_path_whitelist</code> aufgenommen und beim nächsten Aufruf nicht mehr geprüft.', 'brainwerk-security-suite' ), array( 'strong' => array(), 'code' => array(), 'em' => array() ) ); ?></p>
            <?php
            global $wpdb;
            $log_tbl = $wpdb->base_prefix . 'shieldforge_log';
            $waf_blocks = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT id, created_at, ip_anon, request_uri, context FROM ' . $log_tbl . ' WHERE event_type = %s ORDER BY id DESC LIMIT 30', 'waf_block' ), ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- $log_tbl is a trusted internal table name ($wpdb->base_prefix), never user input; %s placeholder used for the actual value; custom security table, direct live read by design, not cacheable.
            $current_wl = (array) $s( 'waf_path_whitelist', array() );
            if ( empty( $waf_blocks ) ) : ?>
                <p style="padding: 14px; background: #e6f5ea; border-left: 3px solid #2e8b3e; border-radius: 4px;">✓ <?php esc_html_e( 'Keine WAF-Blocks bisher — entweder keine Angriffe oder WAF nicht lange genug aktiv.', 'brainwerk-security-suite' ); ?></p>
            <?php else : ?>
                <table class="sf-v12-table">
                    <thead><tr><th><?php esc_html_e( 'Zeit', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'IP', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'Pfad', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'Regel', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'Aktion', 'brainwerk-security-suite' ); ?></th></tr></thead>
                    <tbody>
                    <?php foreach ( $waf_blocks as $b ) :
                        $ctx = json_decode( $b['context'], true );
                        $rule_name = $ctx['rule_name'] ?? ( $ctx['rule'] ?? '?' );
                        $path_only = (string) parse_url( $b['request_uri'], PHP_URL_PATH );
                        $already_wl = in_array( $path_only, $current_wl, true );
                    ?>
                        <tr>
                            <td><?php echo esc_html( substr( $b['created_at'], 11, 8 ) . ' ' . substr( $b['created_at'], 0, 10 ) ); ?></td>
                            <td><code><?php echo esc_html( $b['ip_anon'] ); ?></code></td>
                            <td><code><?php echo esc_html( mb_strimwidth( $b['request_uri'], 0, 60, '…' ) ); ?></code></td>
                            <td title="<?php echo esc_attr( wp_json_encode( $ctx ) ); ?>"><?php echo esc_html( mb_strimwidth( $rule_name, 0, 30, '…' ) ); ?></td>
                            <td>
                                <?php if ( $already_wl ) : ?>
                                    <span style="color: #2e8b3e;">✓ <?php esc_html_e( 'schon whitelisted', 'brainwerk-security-suite' ); ?></span>
                                <?php else : ?>
                                    <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" style="display:inline;">
                                        <?php wp_nonce_field( 'shieldforge_waf_whitelist_add' ); ?>
                                        <input type="hidden" name="action" value="shieldforge_waf_whitelist_add">
                                        <input type="hidden" name="path" value="<?php echo esc_attr( $path_only ); ?>">
                                        <button type="submit" class="button button-small" title="<?php echo esc_attr__( 'Diesen Pfad zur WAF-Whitelist hinzufügen', 'brainwerk-security-suite' ); ?>">+ <?php esc_html_e( 'Whitelisten', 'brainwerk-security-suite' ); ?></button>
                                    </form>
                                <?php endif; ?>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                    </tbody>
                </table>
                <?php if ( ! empty( $current_wl ) ) : ?>
                    <p style="margin-top: 12px; font-size: 12px;"><strong><?php esc_html_e( 'Aktuelle Whitelist:', 'brainwerk-security-suite' ); ?></strong> <code><?php echo esc_html( implode( ', ', $current_wl ) ); ?></code></p>
                <?php endif; ?>
            <?php endif; ?>
        </div>

        <!-- PRIVACY DASHBOARD -->
        <div class="sf-v12-card" style="grid-column: 1 / -1;">
            <h2>🇪🇺 <?php esc_html_e( 'DSGVO-Privacy-Dashboard', 'brainwerk-security-suite' ); ?> <span class="status on"><?php esc_html_e( 'immer aktiv', 'brainwerk-security-suite' ); ?></span></h2>
            <p class="hint"><?php esc_html_e( 'Datenkarte + DSGVO-Art.-15-Auskunft + Art.-17-Löschung in einem Klick.', 'brainwerk-security-suite' ); ?></p>

            <?php if ( class_exists( 'Shieldforge_Privacy_Dashboard' ) ) :
                $map = Shieldforge_Privacy_Dashboard::data_map(); ?>
            <details style="margin-top: 10px;"><summary style="cursor: pointer; font-size: 13px; font-weight: 600;"><?php esc_html_e( 'Datenkarte — wo werden welche personenbezogenen Daten gespeichert?', 'brainwerk-security-suite' ); ?></summary>
                <table class="sf-v12-table">
                    <thead><tr><th><?php esc_html_e( 'Kategorie', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'Tabelle', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'Felder', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'Zeilen', 'brainwerk-security-suite' ); ?></th><th><?php esc_html_e( 'Rechtsgrundlage', 'brainwerk-security-suite' ); ?></th></tr></thead>
                    <tbody>
                    <?php foreach ( $map as $row ) : ?>
                        <tr>
                            <td><strong><?php echo esc_html( $row['category'] ); ?></strong></td>
                            <td><code><?php echo esc_html( $row['table'] ); ?></code></td>
                            <td><?php echo esc_html( implode( ', ', $row['fields'] ) ); ?></td>
                            <td><?php echo esc_html( $row['rows'] ); ?></td>
                            <td><?php echo esc_html( $row['lawful_basis'] ); ?></td>
                        </tr>
                    <?php endforeach; ?>
                    </tbody>
                </table>
            </details>
            <?php endif; ?>

            <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px;">
                <div class="sf-v12-runner">
                    <strong>📤 <?php esc_html_e( 'DSGVO Art. 15 — Auskunft', 'brainwerk-security-suite' ); ?></strong>
                    <p style="font-size: 12px; margin: 4px 0;"><?php esc_html_e( 'Schickt eine Bestätigungsmail an die angegebene Adresse. Nach Bestätigung kann der User alle zu ihm gespeicherten Daten herunterladen (WP-Core-Mechanik).', 'brainwerk-security-suite' ); ?></p>
                    <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" style="margin-top:6px;">
                        <?php wp_nonce_field( 'shieldforge_privacy_export' ); ?>
                        <input type="hidden" name="action" value="shieldforge_privacy_export">
                        <input type="email" name="email" placeholder="<?php echo esc_attr__( 'user@example.com', 'brainwerk-security-suite' ); ?>" required style="width: 60%;">
                        <button type="submit" class="button button-primary"><?php esc_html_e( 'Anfrage starten', 'brainwerk-security-suite' ); ?></button>
                    </form>
                </div>
                <div class="sf-v12-runner" style="border-left-color:#cf222e;">
                    <strong>🗑 <?php esc_html_e( 'DSGVO Art. 17 — Löschung', 'brainwerk-security-suite' ); ?></strong>
                    <p style="font-size: 12px; margin: 4px 0;"><?php esc_html_e( 'Startet Lösch-Workflow für alle Daten dieser E-Mail. User bekommt Bestätigungsmail zur Authorisierung.', 'brainwerk-security-suite' ); ?></p>
                    <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" style="margin-top:6px;">
                        <?php wp_nonce_field( 'shieldforge_privacy_erase' ); ?>
                        <input type="hidden" name="action" value="shieldforge_privacy_erase">
                        <input type="email" name="email" placeholder="<?php echo esc_attr__( 'user@example.com', 'brainwerk-security-suite' ); ?>" required style="width: 60%;">
                        <button type="submit" class="button" style="color:#cf222e;"><?php esc_html_e( 'Löschen starten', 'brainwerk-security-suite' ); ?></button>
                    </form>
                </div>
            </div>
        </div>

    </div>

    <p style="margin: 20px 0;">
        <button type="submit" class="button button-primary button-large">💾 <?php esc_html_e( 'Alle Modul-Einstellungen speichern', 'brainwerk-security-suite' ); ?></button>
    </p>
</form>

<?php
// Core-compare AJAX runner. Server-generated JS is delivered through
// wp_add_inline_script() (via the helper) instead of a raw <script> tag; the
// nonce + translated strings ride along in a JSON config object.
$cc_cfg = array(
    'nonce' => wp_create_nonce( 'shieldforge_admin' ),
    'i18n'  => array(
        'running'  => __( 'Läuft… (kann 10-30 Sekunden dauern)', 'brainwerk-security-suite' ),
        'error'    => __( 'Fehler:', 'brainwerk-security-suite' ),
        'unknown'  => __( 'unbekannt', 'brainwerk-security-suite' ),
        'allOk'    => __( '✓ Alle %d Core-Files unverändert', 'brainwerk-security-suite' ),
        'issues'   => __( '⚠ %d Auffälligkeiten:', 'brainwerk-security-suite' ),
        'modified' => __( '%d modifizierte Files', 'brainwerk-security-suite' ),
        'missing'  => __( '%d fehlende Files', 'brainwerk-security-suite' ),
        'extra'    => __( '%d extra Files (verdächtig!)', 'brainwerk-security-suite' ),
    ),
);
$cc_js = 'var SF_CC = ' . wp_json_encode( $cc_cfg ) . ";\n" . <<<'JS'
(function () {
    var btn = document.getElementById('sf-run-core-compare');
    if (!btn) return;
    function esc(s) { var d = document.createElement('div'); d.textContent = (s == null ? '' : String(s)); return d.innerHTML; }
    btn.addEventListener('click', function () {
        var out = document.getElementById('sf-core-compare-result');
        out.textContent = SF_CC.i18n.running;
        var fd = new FormData();
        fd.append('action', 'shieldforge_core_compare');
        fd.append('nonce', SF_CC.nonce);
        fetch(ajaxurl, { method: 'POST', body: fd, credentials: 'same-origin' })
            .then(function (r) { return r.json(); })
            .then(function (r) {
                if (!r.ok && !r.summary) {
                    out.innerHTML = '<span style="color:#cf222e;">' + esc(SF_CC.i18n.error) + ' ' + esc(r.error || SF_CC.i18n.unknown) + '</span>';
                    return;
                }
                var s = r.summary || {};
                var color = r.ok ? '#2e8b3e' : '#cf222e';
                out.innerHTML = '<strong style="color:' + color + ';">' + (r.ok ? esc(SF_CC.i18n.allOk).replace('%d', s.total_checked) : esc(SF_CC.i18n.issues).replace('%d', (s.modified + s.missing + s.extra))) + '</strong>'
                    + (s.modified ? '<br>• ' + esc(SF_CC.i18n.modified).replace('%d', s.modified) : '')
                    + (s.missing  ? '<br>• ' + esc(SF_CC.i18n.missing).replace('%d', s.missing) : '')
                    + (s.extra    ? '<br>• ' + esc(SF_CC.i18n.extra).replace('%d', s.extra) : '');
            })
            .catch(function (e) { out.innerHTML = '<span style="color:#cf222e;">' + esc(SF_CC.i18n.error) + ' ' + esc(e.message) + '</span>'; });
    });
})();
JS;
Shieldforge_Utils::enqueue_inline_script( 'shieldforge-modules', $cc_js );

// Handler für das Settings-Save direkt in dieser View (kein separater handler nötig)
if ( ! empty( $_POST['action'] ) && 'shieldforge_modules_save' === $_POST['action'] && check_admin_referer( 'shieldforge_modules_save' ) ) {
    $input = isset( $_POST['sf'] ) && is_array( $_POST['sf'] ) ? wp_unslash( $_POST['sf'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- raw values are per-key sanitized in Shieldforge_Settings::sanitize() before being persisted.
    // Boolean-Keys, die nicht im POST sind → 0
    $bool_keys = array( 'headers_enabled', 'headers_x_frame', 'headers_x_content_type', 'headers_referrer_policy', 'headers_permissions_policy', 'headers_hsts', 'headers_coop', 'headers_corp', 'pwned_check_enabled', 'trusted_devices_enabled', 'live_traffic_enabled', 'magic_link_enabled', 'captcha_enabled', 'waf_enabled', 'waf_whitelist_admins', 'waf_autoblock_ip' );
    foreach ( $bool_keys as $k ) {
        if ( ! isset( $input[ $k ] ) ) $input[ $k ] = 0;
    }
    Shieldforge_Settings::update( $input );
    wp_safe_redirect( add_query_arg( 'shieldforge_modules_saved', '1', remove_query_arg( 'shieldforge_modules_saved' ) ) );
    exit;
}
