<?php
/**
 * Admin UI — top-level menu, tabbed pages, settings save handler.
 *
 * @package Brainwerk Security Suite
 */

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

class Shieldforge_Admin {

    const MENU_SLUG = 'brainwerk-security-suite';
    const NONCE     = 'shieldforge_save_settings';
    const CAP       = 'manage_options';

    public static function register( Shieldforge_Loader $loader ) {
        $loader->add_action( 'admin_menu', __CLASS__, 'register_menu' );
        $loader->add_action( 'network_admin_menu', __CLASS__, 'register_network_menu' );
        $loader->add_action( 'admin_init', __CLASS__, 'maybe_save_settings' );
        $loader->add_action( 'admin_init', __CLASS__, 'maybe_set_language' );
        $loader->add_action( 'admin_enqueue_scripts', __CLASS__, 'enqueue_assets' );
    }

    public static function tabs() {
        return array(
            'dashboard'     => __( 'Dashboard', 'brainwerk-security-suite' ),
            'login'         => __( 'Login & Auth', 'brainwerk-security-suite' ),
            'twofactor'     => __( '2FA', 'brainwerk-security-suite' ),
            'hardening'     => __( 'Hardening', 'brainwerk-security-suite' ),
            'hardening-plus' => __( 'Hardening+', 'brainwerk-security-suite' ),
            'firewall'      => __( 'Firewall', 'brainwerk-security-suite' ),
            'scanner'       => __( 'Scanner', 'brainwerk-security-suite' ),
            'vulnerabilities' => __( 'Vulnerabilities', 'brainwerk-security-suite' ),
            'anomaly'       => __( 'Anomaly (beta)', 'brainwerk-security-suite' ),
            'incident'      => __( 'Incident Response', 'brainwerk-security-suite' ),
            'audit'         => __( 'Audit', 'brainwerk-security-suite' ),
            'logs'          => __( 'Logs', 'brainwerk-security-suite' ),
            'notifications' => __( 'Notifications', 'brainwerk-security-suite' ),
            'multisite'     => __( 'Multisite', 'brainwerk-security-suite' ),
            'threat-network' => __( 'Threat Network', 'brainwerk-security-suite' ),
            'privacy'       => __( 'Privacy / GDPR', 'brainwerk-security-suite' ),
            'tools'         => __( 'Tools', 'brainwerk-security-suite' ),
            'license'       => __( 'License', 'brainwerk-security-suite' ),
            'modules'       => __( 'Extra Modules', 'brainwerk-security-suite' ),
        );
    }

    /**
     * Logical groupings for the tab nav. Helps non-experts find their way
     * around 16 tabs by visually clustering related ones.
     *
     * Each group: [ slug => label, tabs => [tab-slugs in order] ].
     */
    public static function tab_groups() {
        return array(
            'ops' => array(
                'label' => __( 'Operations', 'brainwerk-security-suite' ),
                'tabs'  => array( 'dashboard' ),
            ),
            'setup' => array(
                'label' => __( 'Setup & Hardening', 'brainwerk-security-suite' ),
                'tabs'  => array( 'login', 'twofactor', 'hardening', 'hardening-plus' ),
            ),
            'detect' => array(
                'label' => __( 'Detection & Response', 'brainwerk-security-suite' ),
                'tabs'  => array( 'firewall', 'scanner', 'vulnerabilities', 'anomaly', 'incident' ),
            ),
            'records' => array(
                'label' => __( 'Records & Alerts', 'brainwerk-security-suite' ),
                'tabs'  => array( 'audit', 'logs', 'notifications' ),
            ),
            'system' => array(
                'label' => __( 'System', 'brainwerk-security-suite' ),
                'tabs'  => array( 'multisite', 'threat-network', 'privacy', 'tools', 'license' ),
            ),
            'advanced' => array(
                'label' => __( 'Advanced', 'brainwerk-security-suite' ),
                'tabs'  => array( 'modules' ),
            ),
        );
    }

    /**
     * Dashicon class per tab — purely cosmetic. Picked from WordPress'
     * built-in dashicons set so we don't ship custom assets for this.
     */
    public static function tab_icons() {
        return array(
            'dashboard'     => 'dashicons-dashboard',
            'login'         => 'dashicons-lock',
            'twofactor'     => 'dashicons-smartphone',
            'hardening'     => 'dashicons-shield',
            'hardening-plus' => 'dashicons-superhero',
            'firewall'      => 'dashicons-shield-alt',
            'scanner'       => 'dashicons-search',
            'vulnerabilities' => 'dashicons-warning',
            'anomaly'       => 'dashicons-chart-line',
            'incident'      => 'dashicons-sos',
            'audit'         => 'dashicons-clipboard',
            'logs'          => 'dashicons-list-view',
            'notifications' => 'dashicons-email-alt',
            'multisite'     => 'dashicons-admin-multisite',
            'threat-network' => 'dashicons-networking',
            'privacy'       => 'dashicons-privacy',
            'tools'         => 'dashicons-admin-tools',
            'license'       => 'dashicons-id-alt',
        );
    }

    public static function register_menu() {
        add_menu_page(
            __( 'Brainwerk Security Suite', 'brainwerk-security-suite' ),
            __( 'Brainwerk Security Suite', 'brainwerk-security-suite' ),
            self::CAP,
            self::MENU_SLUG,
            array( __CLASS__, 'render_page' ),
            SHIELDFORGE_URL . 'assets/images/icon-32.png',
            71
        );
    }

    public static function register_network_menu() {
        add_menu_page(
            __( 'Brainwerk Security Suite', 'brainwerk-security-suite' ),
            __( 'Brainwerk Security Suite', 'brainwerk-security-suite' ),
            'manage_network_options',
            self::MENU_SLUG,
            array( __CLASS__, 'render_page' ),
            SHIELDFORGE_URL . 'assets/images/icon-32.png',
            71
        );
    }

    public static function enqueue_assets( $hook ) {
        if ( false === strpos( (string) $hook, self::MENU_SLUG ) && 'index.php' !== $hook ) {
            return;
        }
        wp_enqueue_style(
            'shieldforge-admin',
            SHIELDFORGE_URL . 'assets/css/admin.css',
            array(),
            SHIELDFORGE_VERSION
        );
        wp_enqueue_script(
            'shieldforge-admin',
            SHIELDFORGE_URL . 'assets/js/admin.js',
            array( 'jquery' ),
            SHIELDFORGE_VERSION,
            true
        );

        if ( 'threat-network' === self::current_tab() ) {
            wp_enqueue_style(
                'shieldforge-intel-command',
                SHIELDFORGE_URL . 'assets/css/intel-command.css',
                array( 'shieldforge-admin' ),
                SHIELDFORGE_VERSION
            );
        }
        wp_localize_script(
            'shieldforge-admin',
            'shieldforgeAjax',
            array(
                'url'   => admin_url( 'admin-ajax.php' ),
                'nonce' => wp_create_nonce( Shieldforge_Ajax::NONCE_ACTION ),
                'i18n'  => array(
                    'confirmUnblock' => __( 'Remove this block?', 'brainwerk-security-suite' ),
                    'confirmBlock'   => __( 'Block this IP?', 'brainwerk-security-suite' ),
                    'genericError'   => __( 'Request failed.', 'brainwerk-security-suite' ),
                ),
            )
        );
    }

    public static function current_tab() {
        $tabs   = array_keys( self::tabs() );
        $hidden = array( 'onboarding' );
        $tab    = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'dashboard'; // phpcs:ignore WordPress.Security.NonceVerification
        if ( in_array( $tab, $tabs, true ) || in_array( $tab, $hidden, true ) ) {
            return $tab;
        }
        return 'dashboard';
    }

    public static function render_page() {
        if ( ! current_user_can( self::CAP ) && ! current_user_can( 'manage_network_options' ) ) {
            wp_die( esc_html__( 'You do not have permission to access this page.', 'brainwerk-security-suite' ) );
        }
        $tab = self::current_tab();
        ?>
        <div class="wrap shieldforge-wrap">
            <h1 class="shieldforge-title">
                <img src="<?php echo esc_url( SHIELDFORGE_URL . 'assets/images/icon-64.png' ); ?>" alt="Brainwerk Security Suite" class="shieldforge-brand-icon" width="36" height="36">
                <?php esc_html_e( 'Brainwerk Security Suite', 'brainwerk-security-suite' ); ?>
                <span class="shieldforge-version">v<?php echo esc_html( SHIELDFORGE_VERSION ); ?></span>
            </h1>

            <nav class="nav-tab-wrapper shieldforge-tabs shieldforge-tabs-grouped">
                <?php
                $icons = self::tab_icons();
                $tabs  = self::tabs();
                foreach ( self::tab_groups() as $group_key => $group ) :
                    ?>
                    <div class="sf-tab-group" data-group="<?php echo esc_attr( $group_key ); ?>">
                        <span class="sf-tab-group-label"><?php echo esc_html( $group['label'] ); ?></span>
                        <?php foreach ( $group['tabs'] as $slug ) :
                            if ( ! isset( $tabs[ $slug ] ) ) {
                                continue;
                            }
                            $label = $tabs[ $slug ];
                            $icon  = isset( $icons[ $slug ] ) ? $icons[ $slug ] : '';
                            ?>
                            <a class="nav-tab <?php echo $slug === $tab ? 'nav-tab-active' : ''; ?>"
                               href="<?php echo esc_url( self::tab_url( $slug ) ); ?>">
                                <?php if ( $icon ) : ?>
                                    <span class="dashicons <?php echo esc_attr( $icon ); ?>"></span>
                                <?php endif; ?>
                                <?php echo esc_html( $label ); ?>
                            </a>
                        <?php endforeach; ?>
                    </div>
                <?php endforeach; ?>
            </nav>

            <?php settings_errors( 'brainwerk-security-suite' ); ?>

            <div class="shieldforge-tab-content">
                <?php
                // Tab-intro card (short summary + expandable details). Shown
                // above every tab view to orient non-expert admins.
                if ( ! class_exists( 'Shieldforge_Admin_Intros' ) ) {
                    require_once SHIELDFORGE_PATH . 'includes/class-shieldforge-admin-intros.php';
                }
                Shieldforge_Admin_Intros::render( $tab );

                $view = SHIELDFORGE_PATH . 'admin/views/page-' . $tab . '.php';
                if ( file_exists( $view ) ) {
                    include $view;
                } else {
                    self::render_placeholder( $tab );
                }
                ?>
            </div>
        </div>
        <?php
    }

    public static function tab_url( $slug ) {
        return add_query_arg(
            array( 'page' => self::MENU_SLUG, 'tab' => $slug ),
            is_network_admin() ? network_admin_url( 'admin.php' ) : admin_url( 'admin.php' )
        );
    }

    private static function render_placeholder( $tab ) {
        $labels = self::tabs();
        $label  = isset( $labels[ $tab ] ) ? $labels[ $tab ] : ucfirst( $tab );
        echo '<div class="shieldforge-card"><h2>' . esc_html( $label ) . '</h2>';
        echo '<p>' . esc_html__( 'This section is coming soon.', 'brainwerk-security-suite' ) . '</p></div>';
    }

    /**
     * Plugin-language selector (Dashboard tab). Stores into the same option
     * the onboarding wizard uses; empty choice = follow WordPress locale.
     */
    public static function maybe_set_language() {
        if ( empty( $_POST['shieldforge_action'] ) || 'set_language' !== $_POST['shieldforge_action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
            return;
        }
        if ( ! check_admin_referer( 'shieldforge_set_language' ) ) {
            return;
        }
        if ( ! current_user_can( self::CAP ) && ! current_user_can( 'manage_network_options' ) ) {
            return;
        }
        $choice = isset( $_POST['shieldforge_language'] )
            ? sanitize_key( wp_unslash( $_POST['shieldforge_language'] ) )
            : '';
        Shieldforge_I18n::set_admin_language( $choice );

        wp_safe_redirect( self::tab_url( 'dashboard' ) );
        exit;
    }

    /**
     * Settings save handler — POSTs from any tab go through here.
     */
    public static function maybe_save_settings() {
        if ( empty( $_POST['shieldforge_action'] ) || 'save_settings' !== $_POST['shieldforge_action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
            return;
        }
        if ( ! check_admin_referer( self::NONCE ) ) {
            return;
        }
        if ( ! current_user_can( self::CAP ) && ! current_user_can( 'manage_network_options' ) ) {
            return;
        }
        // NOTE: the form field prefix is shieldforge[...] (all 62 view fields use
        // it), matching the deliberately-kept internal identifiers. The v0.14
        // rebrand sed over-replaced this POST key to 'brainwerk-security-suite',
        // which silently broke ALL settings saving — restored here.
        $input = isset( $_POST['shieldforge'] ) && is_array( $_POST['shieldforge'] )
            ? wp_unslash( $_POST['shieldforge'] ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- raw values are per-key sanitized in Shieldforge_Settings::sanitize() before being persisted.
            : array();

        // Coerce missing checkboxes to false (browsers don't submit unchecked boxes).
        $boolean_keys = array(
            'login_log_enabled', 'bruteforce_enabled', 'bf_user_lockout_enabled',
            'probing_track_enabled',
            'hardening_disable_xmlrpc', 'hardening_disable_editor', 'hardening_hide_version',
            'hardening_block_authors', 'hardening_security_headers', 'hardening_rest_restrict',
            'notify_email_enabled', 'digest_enabled', 'privacy_anonymize_ip',
            'privacy_pseudonym_users', 'anomaly_enabled',
            'scanner_enabled', 'scanner_pattern_enabled',
            'twofactor_enabled',
            'vulnscan_enabled', 'vulnscan_check_themes', 'vulnscan_check_core',
            'audit_enabled', 'audit_track_posts', 'audit_track_users',
            'audit_track_options', 'audit_track_updates',
            'login_url_enabled',
            'honeypot_enabled', 'honeypot_login', 'honeypot_register', 'honeypot_comment',
            'hardening_header_xcto', 'hardening_header_xfo', 'hardening_header_referrer',
            'hardening_header_permissions', 'hardening_header_hsts',
            'hardening_csp_enabled', 'hardening_csp_report_only',
            'sensor_enabled', 'sensor_share_with_feed',
            'incident_enabled',
            'repo_integrity_enabled',
            'ratelimit_enabled', 'ratelimit_verify_bots', 'ratelimit_block_fake_bots',
            'badge_enabled',
            'sf_site_cc_autodetect',
        );
        $current_tab_keys = isset( $_POST['shieldforge_tab_keys'] ) // phpcs:ignore WordPress.Security.NonceVerification
            ? array_map( 'sanitize_key', (array) wp_unslash( $_POST['shieldforge_tab_keys'] ) )
            : array();
        foreach ( $current_tab_keys as $key ) {
            if ( in_array( $key, $boolean_keys, true ) && ! isset( $input[ $key ] ) ) {
                $input[ $key ] = 0;
            }
        }

        Shieldforge_Settings::update( $input );

        add_settings_error(
            'brainwerk-security-suite',
            'shieldforge_saved',
            __( 'Settings saved.', 'brainwerk-security-suite' ),
            'updated'
        );
        wp_safe_redirect( self::tab_url( self::current_tab() ) );
        exit;
    }
}
