<?php
/**
 * Audit Log AJAX Handlers
 *
 * @package VMPFence
 * @since 2.1.0
 * @since 2.2.2 Added auto-refresh functionality
 * @since 2.2.5 Added enhanced audit log integration for all critical actions across the plugin
 * @since 2.2.6 Added Custom pattern block to Firewall, Custom Pattern Block Message Updated
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Get audit log entry details
 */
add_action('wp_ajax_vmpfence_get_audit_entry', 'vmpfence_ajax_get_audit_entry');
function vmpfence_ajax_get_audit_entry() {
    // Verify nonce
    check_ajax_referer('vmpfence_audit_log_nonce', 'nonce');

    // Check permissions
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => 'Insufficient permissions'));
    }

    $entry_id = isset($_POST['entry_id']) ? absint($_POST['entry_id']) : 0;

    if (!$entry_id) {
        wp_send_json_error(array('message' => 'Invalid entry ID'));
    }

    global $wpdb;
    $table_name = VMPFence_Constants::get_table_name(VMPFence_Constants::TABLE_AUDIT_LOG);

    $entry = $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM `{$table_name}` WHERE id = %d",
        $entry_id
    ), ARRAY_A);

    if (!$entry) {
        wp_send_json_error(array('message' => 'Entry not found'));
    }

    // Unserialize data
    $entry['additional_info'] = maybe_unserialize($entry['additional_info']);
    $entry['old_value'] = maybe_unserialize($entry['old_value']);
    $entry['new_value'] = maybe_unserialize($entry['new_value']);

    // Format IP - use consistent logic with class method
    if (!empty($entry['source_ip'])) {
        if (filter_var($entry['source_ip'], FILTER_VALIDATE_IP)) {
            $entry['ip_formatted'] = $entry['source_ip'];
        } elseif (is_string($entry['source_ip']) && (strlen($entry['source_ip']) === 4 || strlen($entry['source_ip']) === 16)) {
            // Binary format (varbinary) - supports both IPv4 and IPv6
            $formatted = @inet_ntop($entry['source_ip']);
            $entry['ip_formatted'] = ($formatted !== false) ? $formatted : 'N/A';
        } elseif (is_numeric($entry['source_ip']) && $entry['source_ip'] <= 4294967295) {
            // Legacy numeric format (IPv4 only)
            $formatted = @long2ip((int)$entry['source_ip']);
            $entry['ip_formatted'] = ($formatted && $formatted !== '0.0.0.0') ? $formatted : 'N/A';
        } else {
            $entry['ip_formatted'] = 'N/A';
        }
    } else {
        $entry['ip_formatted'] = 'N/A';
    }

    // Format time
    $entry['time_formatted'] = date_i18n(
        get_option('date_format') . ' ' . get_option('time_format'),
        (int)$entry['time']
    );

    wp_send_json_success(array('entry' => $entry));
}

/**
 * Export audit log to CSV
 */
add_action('wp_ajax_vmpfence_export_audit_log', 'vmpfence_ajax_export_audit_log');
function vmpfence_ajax_export_audit_log() {
    // Verify nonce
    check_ajax_referer('vmpfence_audit_log_nonce', 'nonce');

    // Check permissions
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => 'Insufficient permissions'));
    }

    // Get filter parameters with proper sanitization and validation
    $args = array();
    
    if (!empty($_POST['event_type'])) {
        $args['event_type'] = sanitize_text_field(wp_unslash($_POST['event_type']));
    }
    
    if (!empty($_POST['user_id'])) {
        $args['user_id'] = absint($_POST['user_id']);
    }
    
    if (!empty($_POST['date_from'])) {
        $date_from = sanitize_text_field(wp_unslash($_POST['date_from']));
        // Validate date format YYYY-MM-DD
        if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $date_from)) {
            $args['date_from'] = $date_from;
        }
    }
    
    if (!empty($_POST['date_to'])) {
        $date_to = sanitize_text_field(wp_unslash($_POST['date_to']));
        // Validate date format YYYY-MM-DD
        if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $date_to)) {
            $args['date_to'] = $date_to;
        }
    }
    
    if (!empty($_POST['search'])) {
        $args['search'] = sanitize_text_field(wp_unslash($_POST['search']));
    }

    // Generate CSV
    $csv_content = VMPFence_Audit_Log::export_csv($args);

    if (empty($csv_content)) {
        wp_send_json_error(array('message' => 'No data to export'));
    }

    // Store in transient for download
    $transient_key = 'vmpfence_audit_export_' . md5(current_time('timestamp') . wp_get_current_user()->ID);
    set_transient($transient_key, $csv_content, 300); // 5 minutes

    wp_send_json_success(array(
        'download_key' => $transient_key,
        'download_url' => add_query_arg(array(
            'action' => 'vmpfence_download_audit_export',
            'key' => $transient_key,
            'nonce' => wp_create_nonce('vmpfence_download_' . $transient_key)
        ), admin_url('admin-ajax.php'))
    ));
}

/**
 * Download exported audit log CSV
 */
add_action('wp_ajax_vmpfence_download_audit_export', 'vmpfence_ajax_download_audit_export');
function vmpfence_ajax_download_audit_export() {
    // Check permissions
    if (!current_user_can('manage_options')) {
        wp_die('Insufficient permissions');
    }

    $key = isset($_GET['key']) ? sanitize_text_field($_GET['key']) : '';
    $nonce = isset($_GET['nonce']) ? sanitize_text_field($_GET['nonce']) : '';

    if (!$key || !wp_verify_nonce($nonce, 'vmpfence_download_' . $key)) {
        wp_die('Invalid download link');
    }

    $csv_content = get_transient($key);

    if (!$csv_content) {
        wp_die('Download link expired or invalid');
    }

    // Delete transient
    delete_transient($key);

    // Send file
    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename="audit-log-' . date('Y-m-d-His') . '.csv"');
    header('Pragma: no-cache');
    header('Expires: 0');

    echo $csv_content;
    exit;
}

/**
 * Delete old audit log entries
 */
add_action('wp_ajax_vmpfence_cleanup_audit_log', 'vmpfence_ajax_cleanup_audit_log');
function vmpfence_ajax_cleanup_audit_log() {
    // Verify nonce
    check_ajax_referer('vmpfence_audit_log_nonce', 'nonce');

    // Check permissions
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => 'Insufficient permissions'));
    }

    $days = isset($_POST['days']) ? absint($_POST['days']) : 90;

    if ($days < 1) {
        wp_send_json_error(array('message' => 'Invalid retention days'));
    }

    $deleted = VMPFence_Audit_Log::cleanup_old_entries();

    wp_send_json_success(array(
        'deleted' => $deleted,
        'message' => sprintf('Deleted %d old audit log entries', $deleted)
    ));
}

/**
 * Get recent audit log entries (for auto-refresh)
 * @since 2.2.2 Added auto-refresh functionality
 */
add_action('wp_ajax_vmpfence_get_recent_audit_entries', 'vmpfence_ajax_get_recent_audit_entries');
function vmpfence_ajax_get_recent_audit_entries() {
    // Verify nonce
    check_ajax_referer('vmpfence_audit_log_nonce', 'nonce');

    // Check permissions
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => 'Insufficient permissions'));
    }

    $since_time = isset($_POST['since_time']) ? floatval($_POST['since_time']) : 0;
    $limit = isset($_POST['limit']) ? absint($_POST['limit']) : 20;

    // Use the class method instead of direct query
    $entries = VMPFence_Audit_Log::get_recent_entries($since_time, $limit);

    // Generate HTML for each entry
    $entries_html = array();
    foreach ($entries as $entry) {
        ob_start();
        ?>
        <tr data-entry-id="<?php echo esc_attr($entry['id']); ?>" style="animation: fadeIn 0.5s;">
            <td class="column-time">
                <span class="timestamp" title="<?php echo esc_attr(date('Y-m-d H:i:s', $entry['time'])); ?>">
                    <?php echo esc_html(human_time_diff($entry['time'], time()) . ' ago'); ?>
                </span>
            </td>
            <td class="column-event">
                <span class="event-type-indicator">
                    <?php
                    $event_type = $entry['event_type'];
                    $color_class = 'event-color-default';
                    
                    if (strpos($event_type, 'login') !== false || strpos($event_type, 'logout') !== false || strpos($event_type, 'auth') !== false || strpos($event_type, 'password') !== false) {
                        $color_class = 'event-color-authentication';
                    } elseif (strpos($event_type, 'user') !== false || strpos($event_type, 'role') !== false || strpos($event_type, 'capabilities') !== false || strpos($event_type, 'super_admin') !== false) {
                        $color_class = 'event-color-user';
                    } elseif (strpos($event_type, 'plugin') !== false || strpos($event_type, 'theme') !== false || strpos($event_type, 'core_update') !== false || strpos($event_type, 'auto_update') !== false) {
                        $color_class = 'event-color-plugin';
                    } elseif (strpos($event_type, 'waf') !== false || strpos($event_type, 'block') !== false || strpos($event_type, 'brute') !== false || strpos($event_type, 'lockout') !== false || strpos($event_type, 'threat') !== false || strpos($event_type, 'banned') !== false || strpos($event_type, 'rate_limit') !== false || strpos($event_type, 'custom_pattern') !== false) {
                        $color_class = 'event-color-firewall';
                    } elseif (strpos($event_type, 'config') !== false || strpos($event_type, 'setting') !== false || strpos($event_type, 'option') !== false || strpos($event_type, 'vmpfence') !== false || strpos($event_type, 'license') !== false) {
                        $color_class = 'event-color-settings';
                    } elseif (strpos($event_type, 'multisite') !== false || strpos($event_type, 'network') !== false) {
                        $color_class = 'event-color-multisite';
                    } elseif (strpos($event_type, 'post') !== false || strpos($event_type, 'page') !== false || strpos($event_type, 'content') !== false || strpos($event_type, 'comment') !== false || strpos($event_type, 'media') !== false || strpos($event_type, 'term') !== false || strpos($event_type, 'menu') !== false || strpos($event_type, 'file_upload') !== false) {
                        $color_class = 'event-color-content';
                    } elseif (strpos($event_type, 'scan') !== false || strpos($event_type, 'mail') !== false || strpos($event_type, 'recovery') !== false || strpos($event_type, 'file_editor') !== false || strpos($event_type, 'database') !== false || strpos($event_type, 'backup') !== false || strpos($event_type, 'xmlrpc') !== false || strpos($event_type, 'rest_api') !== false || strpos($event_type, 'wp_die') !== false || strpos($event_type, 'customizer') !== false || strpos($event_type, 'support') !== false || strpos($event_type, 'feedback') !== false) {
                        $color_class = 'event-color-system';
                    }
                    ?>
                    <span class="event-color-dot <?php echo esc_attr($color_class); ?>"></span>
                    <?php echo esc_html(VMPFence_Audit_Log::get_event_type_name($event_type)); ?>
                </span>
            </td>
            <td class="column-user"><?php echo esc_html($entry['username'] ?: 'System'); ?></td>
            <td class="column-action"><?php echo esc_html($entry['action']); ?></td>
            <td class="column-object"><?php echo esc_html($entry['object_type'] ?: '—'); ?></td>
            <td class="column-ip"><?php echo esc_html(!empty($entry['ip_address']) ? $entry['ip_address'] : 'N/A'); ?></td>
            <td class="column-message"><?php echo esc_html($entry['message']); ?></td>
            <td class="column-details">
                <?php if ($entry['id']): ?>
                    <button class="button button-small view-details" data-entry-id="<?php echo esc_attr($entry['id']); ?>">
                        View Details
                    </button>
                <?php else: ?>
                    —
                <?php endif; ?>
            </td>
        </tr>
        <?php
        $entries_html[] = ob_get_clean();
    }

    wp_send_json_success(array(
        'entries' => $entries_html,
        'count' => count($entries)
    ));
}

/**
 * Reload audit log table (for auto-refresh with full table reload)
 * @since 2.2.2
 */
add_action('wp_ajax_vmpfence_reload_audit_table', 'vmpfence_ajax_reload_audit_table');
function vmpfence_ajax_reload_audit_table() {
    // Verify nonce
    check_ajax_referer('vmpfence_audit_log_nonce', 'nonce');

    // Check permissions
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => 'Insufficient permissions'));
    }

    // Get filter parameters
    $filter_event_type = isset($_POST['filter_event_type']) ? sanitize_text_field($_POST['filter_event_type']) : '';
    $filter_user = isset($_POST['filter_user']) ? sanitize_text_field($_POST['filter_user']) : '';
    $filter_date_from = isset($_POST['filter_date_from']) ? sanitize_text_field($_POST['filter_date_from']) : '';
    $filter_date_to = isset($_POST['filter_date_to']) ? sanitize_text_field($_POST['filter_date_to']) : '';
    $filter_search = isset($_POST['filter_search']) ? sanitize_text_field($_POST['filter_search']) : '';
    $current_page = isset($_POST['paged']) ? absint($_POST['paged']) : 1;
    $per_page = 50;

    // Build query args
    $query_args = array(
        'limit' => $per_page,
        'offset' => ($current_page - 1) * $per_page,
        'order_by' => 'time',
        'order' => 'DESC'
    );

    if (!empty($filter_event_type)) {
        $query_args['event_type'] = $filter_event_type;
    }

    if (!empty($filter_user)) {
        $query_args['user_id'] = absint($filter_user);
    }

    if (!empty($filter_date_from)) {
        $query_args['date_from'] = $filter_date_from;
    }

    if (!empty($filter_date_to)) {
        $query_args['date_to'] = $filter_date_to;
    }

    if (!empty($filter_search)) {
        $query_args['search'] = $filter_search;
    }

    // Check if user has premium license
    $is_premium = (VMPFence_License::get_license_type() === 'premium');

    // Limit free users to 50 entries total
    if (!$is_premium) {
        $max_free_entries = 50;
        $available_entries = max(0, $max_free_entries - (($current_page - 1) * $per_page));
        if ($available_entries > 0) {
            $query_args['limit'] = min($query_args['limit'], $available_entries);
        } else {
            $query_args['limit'] = 0;
        }
    }

    // Get entries
    $entries = VMPFence_Audit_Log::get_entries($query_args);

    // Group entries by request_id and generate HTML
    $grouped = VMPFence_Audit_Log::group_entries($entries);

    ob_start();
    foreach ($grouped as $group):
        $primary = $group['primary'];
        ?>
        <tr data-entry-id="<?php echo esc_attr($primary['id']); ?>">
            <td class="column-time">
                <span class="timestamp" title="<?php echo esc_attr($primary['time_formatted']); ?>">
                    <?php echo esc_html(human_time_diff((int)$primary['time'], time()) . ' ago'); ?>
                </span>
            </td>
            <td class="column-event">
                <?php $total = count($group['entries']); $i = 0; foreach ($group['entries'] as $ge): $i++; ?>
                    <span class="event-type-indicator">
                        <?php
                        $event_type = $ge['event_type'];
                        $color_class = 'event-color-default';
                        
                        if (strpos($event_type, 'login') !== false || strpos($event_type, 'logout') !== false || strpos($event_type, 'auth') !== false || strpos($event_type, 'password') !== false) {
                            $color_class = 'event-color-authentication';
                        } elseif (strpos($event_type, 'user') !== false || strpos($event_type, 'role') !== false || strpos($event_type, 'capabilities') !== false || strpos($event_type, 'super_admin') !== false) {
                            $color_class = 'event-color-user';
                        } elseif (strpos($event_type, 'plugin') !== false || strpos($event_type, 'theme') !== false || strpos($event_type, 'core_update') !== false || strpos($event_type, 'auto_update') !== false) {
                            $color_class = 'event-color-plugin';
                        } elseif (strpos($event_type, 'waf') !== false || strpos($event_type, 'block') !== false || strpos($event_type, 'brute') !== false || strpos($event_type, 'lockout') !== false || strpos($event_type, 'threat') !== false || strpos($event_type, 'banned') !== false || strpos($event_type, 'rate_limit') !== false || strpos($event_type, 'custom_pattern') !== false) {
                            $color_class = 'event-color-firewall';
                        } elseif (strpos($event_type, 'config') !== false || strpos($event_type, 'setting') !== false || strpos($event_type, 'option') !== false || strpos($event_type, 'vmpfence') !== false || strpos($event_type, 'license') !== false) {
                            $color_class = 'event-color-settings';
                        } elseif (strpos($event_type, 'multisite') !== false || strpos($event_type, 'network') !== false) {
                            $color_class = 'event-color-multisite';
                        } elseif (strpos($event_type, 'post') !== false || strpos($event_type, 'page') !== false || strpos($event_type, 'content') !== false || strpos($event_type, 'comment') !== false || strpos($event_type, 'media') !== false || strpos($event_type, 'term') !== false || strpos($event_type, 'menu') !== false || strpos($event_type, 'file_upload') !== false) {
                            $color_class = 'event-color-content';
                        } elseif (strpos($event_type, 'scan') !== false || strpos($event_type, 'mail') !== false || strpos($event_type, 'recovery') !== false || strpos($event_type, 'file_editor') !== false || strpos($event_type, 'database') !== false || strpos($event_type, 'backup') !== false || strpos($event_type, 'xmlrpc') !== false || strpos($event_type, 'rest_api') !== false || strpos($event_type, 'wp_die') !== false || strpos($event_type, 'customizer') !== false || strpos($event_type, 'support') !== false || strpos($event_type, 'feedback') !== false) {
                            $color_class = 'event-color-system';
                        }
                        ?>
                        <span class="event-dot <?php echo esc_attr($color_class); ?>"></span>
                        <?php echo esc_html(VMPFence_Audit_Log::get_event_type_name($ge['event_type'])); ?>
                    </span><?php if ($i < $total): ?><br><?php endif; ?>
                <?php endforeach; ?>
            </td>
            <td class="column-user">
                <?php if ($primary['username']): ?>
                    <strong><?php echo esc_html($primary['username']); ?></strong>
                    <?php if ($primary['user_role']): ?>
                        <br><small class="user-role"><?php echo esc_html($primary['user_role']); ?></small>
                    <?php endif; ?>
                <?php else: ?>
                    <em>System</em>
                <?php endif; ?>
            </td>
            <td class="column-ip">
                <?php echo esc_html(!empty($primary['ip_formatted']) ? $primary['ip_formatted'] : 'N/A'); ?>
            </td>
            <td class="column-message">
                <?php $total_m = count($group['entries']); $m = 0; foreach ($group['entries'] as $me): $m++; ?>
                    <?php echo esc_html(wp_trim_words($me['message'], 20)); ?><?php if ($m < $total_m): ?><br><?php endif; ?>
                <?php endforeach; ?>
            </td>
            <td class="column-details">
                <button class="button button-small view-details" style="color: #191970; border-color: #191970;" data-entry-id="<?php echo esc_attr($primary['id']); ?>">
                    <span class="dashicons dashicons-visibility"></span> View
                </button>
            </td>
        </tr>
        <?php
    endforeach;
    $html = ob_get_clean();

    wp_send_json_success(array(
        'html' => $html,
        'count' => count($entries)
    ));
}
