<?php
/**
 * AJAX request handlers for the admin UI quick actions.
 *
 * Every handler validates nonce + capability before doing anything.
 *
 * @package Brainwerk Security Suite
 */

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

class Shieldforge_Ajax {

    const NONCE_ACTION = 'shieldforge_ajax';

    public static function register( Shieldforge_Loader $loader ) {
        $loader->add_action( 'wp_ajax_shieldforge_unblock_ip',  __CLASS__, 'unblock_ip' );
        $loader->add_action( 'wp_ajax_shieldforge_quick_block', __CLASS__, 'quick_block' );
        $loader->add_action( 'wp_ajax_shieldforge_test_mail',   __CLASS__, 'test_mail' );
        $loader->add_action( 'wp_ajax_shieldforge_cleanup',     __CLASS__, 'cleanup' );
    }

    private static function guard() {
        if ( ! check_ajax_referer( self::NONCE_ACTION, 'nonce', false ) ) {
            wp_send_json_error( array( 'message' => __( 'Invalid nonce.', 'brainwerk-security-suite' ) ), 400 );
        }
        if ( ! current_user_can( Shieldforge_Admin::CAP ) && ! current_user_can( 'manage_network_options' ) ) {
            wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'brainwerk-security-suite' ) ), 403 );
        }
    }

    public static function unblock_ip() {
        self::guard();
        global $wpdb;
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above via self::guard() -> check_ajax_referer( self::NONCE_ACTION, 'nonce' ).
        $ip = isset( $_POST['ip'] ) ? sanitize_text_field( wp_unslash( $_POST['ip'] ) ) : '';
        if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) ) {
            wp_send_json_error( array( 'message' => __( 'Invalid IP.', 'brainwerk-security-suite' ) ), 400 );
        }
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- custom security table; direct live write by design; not cacheable.
        $deleted = $wpdb->delete(
            Shieldforge_Utils::table( 'blocks' ),
            array( 'ip' => $ip ),
            array( '%s' )
        );
        wp_send_json_success( array(
            'ip'      => $ip,
            'removed' => (int) $deleted,
        ) );
    }

    public static function quick_block() {
        self::guard();
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above via self::guard() -> check_ajax_referer( self::NONCE_ACTION, 'nonce' ).
        $ip      = isset( $_POST['ip'] ) ? sanitize_text_field( wp_unslash( $_POST['ip'] ) ) : '';
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above via self::guard() -> check_ajax_referer( self::NONCE_ACTION, 'nonce' ).
        $minutes = isset( $_POST['minutes'] ) ? max( 1, (int) $_POST['minutes'] ) : 60;
        if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) ) {
            wp_send_json_error( array( 'message' => __( 'Invalid IP.', 'brainwerk-security-suite' ) ), 400 );
        }
        $id = Shieldforge_Bruteforce::block_ip( $ip, $minutes, 'admin_quick_block' );
        wp_send_json_success( array(
            'ip'       => $ip,
            'block_id' => (int) $id,
            'minutes'  => $minutes,
        ) );
    }

    public static function test_mail() {
        self::guard();
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified above via self::guard() -> check_ajax_referer( self::NONCE_ACTION, 'nonce' ).
        $to     = isset( $_POST['to'] ) ? sanitize_email( wp_unslash( $_POST['to'] ) ) : '';
        $result = Shieldforge_Tools::send_test_mail( $to );
        if ( is_wp_error( $result ) ) {
            wp_send_json_error( array( 'message' => $result->get_error_message() ), 500 );
        }
        wp_send_json_success( array( 'sent' => true ) );
    }

    public static function cleanup() {
        self::guard();
        $deleted = Shieldforge_Tools::cleanup_now();
        wp_send_json_success( array( 'deleted' => (int) $deleted ) );
    }
}
