<?php
/**
 * Export Manager Class
 *
 * Handles the WordPress site export process including core files, database, and configuration.
 *
 * @category WordPress
 * @package  Lcmigrator\LcMigrator\Migrator\Export
 * @author   LC Team <support@leadconnectorhq.com>
 * @license  https://www.gnu.org/licenses/gpl-2.0.html GPL-2.0
 * @link     https://www.leadconnectorhq.com/
 * @since    1.0.0
 */

namespace Lcmigrator\LcMigrator\Migrator\Export;

use Exception;
use Lcmigrator\LcMigrator\Migrator\Database\DatabaseExporter;
use Lcmigrator\LcMigrator\ServerConfig\Config;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use ZipArchive;
use Lcmigrator\LcMigrator\Logger\Logger;
use Lcmigrator\LcMigrator\Migrator\BackupInProgress\BackupInProgress;
use Lcmigrator\LcMigrator\Database\DatabaseUtilityFunctions;
/**
 * Class ExportManager
 *
 * Manages the WordPress site export process
 *
 * @category WordPress
 * @package  Lcmigrator\LcMigrator\Migrator\Export
 * @author   LC Team <support@leadconnectorhq.com>
 * @license  https://www.gnu.org/licenses/gpl-2.0.html GPL-2.0
 * @link     https://www.leadconnectorhq.com/
 * @since    1.0.0
 */
class ExportManager
{
    /** @var string Directory to store backup files */
    private $_backup_dir;

    /** @var Logger Logger instance */
    private $_logger;

    /** @var string Unique identifier for the backup */
    private $_backup_id;

    /** @var ZipArchive ZIP archive instance */
    private $_zip;

    /** @var array List of essential WordPress files to backup */
    private $_essential_files = [
        'index.php',
        'wp-config.php',
        'wp-load.php',
        'wp-login.php',
        'wp-settings.php',
        '.htaccess'
    ];

    /** @var array List of essential WordPress directories to backup */
    private $_essential_dirs = [
        'wp-admin',
        'wp-includes',
        'wp-content'
    ];

    /**
     * List of patterns for files and directories to exclude from backup
     * 
     * @var array
     */
    private $_exclude_patterns = [
        // WordPress specific exclusions
        '*.wpress',
        '*object-cache-pro/*',
        '*object-cache.php',
        '*plugin-check/*',
        '*mu-plugins/*',
        
        // Common cache and temporary files
        '*.log',
        '*.tmp',
        '*.temp',
        '*.cache',
        'cache/*',
        'tmp/*',
        'temp/*',
        
        // Development and version control
        '.git',
        '.git/*',
        '.svn',
        '.svn/*',
        'node_modules',
        'node_modules/*',
        '.env',
        '.env.*',
        '.DS_Store',
        'Thumbs.db',
        
        // Backup and archive files
        '*.bak',
        '*.old',
        '*.zip',
        '*.tar',
        '*.gz',
        '*.rar',
        '*.7z',
        
        // Debug and error logs
        'debug.log',
        'error_log',
        'php_error.log',
        'mysql.log',
        'access.log',
        
        // Large media and binary files 
        '*.mov',
        '*.avi',
        '*.wmv',
        '*.iso',
        '*.dmg',
        '*.exe',
        '*.bin'
    ];

    /** @var BackupInProgress BackupInProgress instance */
    private $_backupInProgress;

    /**
     * Size of each batch when processing files (25MB for better performance with large sites)
     *
     * @var int
     */
    private $_batch_size = 26214400; // Increased from 5MB to 25MB

    /**
     * Maximum number of files per batch
     *
     * @var int
     */
    private $_max_files_per_batch = 1000;

    /**
     * Maximum size for direct file copying (2GB)
     *
     * @var int
     */
    private $_max_direct_copy_size = 2147483648;

    /**
     * Maximum memory limit for ZIP operations (256MB)
     *
     * @var int
     */
    private $_memory_limit = 268435456;

    /**
     * Track processed directories to avoid infinite loops
     *
     * @var array
     */
    private $_processed_dirs = [];

    /**
     * Maximum execution time per batch (in seconds)
     *
     * @var int
     */
    private $_max_batch_time = 30;

    /**
     * Start time of current batch
     *
     * @var float
     */
    private $_batch_start_time;

    /**
     * ExportManager constructor.
     *
     * @param string $backup_dir Directory to store backup files
     * @param string $backup_id  Unique identifier for the backup
     * @param Logger $logger     Logger instance
     */
    public function __construct($backup_dir, $backup_id, Logger $logger, BackupInProgress $backupInProgress = null) 
    {
        $this->_backup_dir = $backup_dir;
        $this->_backup_id = $backup_id;
        $this->_logger = $logger;
        $this->_backupInProgress = $backupInProgress;
    }

    /**
     * Initialize the export process
     * 
     * @return array Success status and backup path or error message
     */
    public function initializeExport() 
    {
        try {
            $this->_logger->info("Starting export process");
            
            // Reset processed directories tracker
            $this->_processed_dirs = [];
            
            // Set optimal memory limit based on available system memory
            $system_memory = $this->_getSystemMemoryLimit();
            $optimal_memory = min($system_memory / 2, 1024 * 1024 * 1024); // Use half of system memory or 1GB max
            $this->_memory_limit = max($this->_memory_limit, $optimal_memory);
            
            ini_set('memory_limit', $this->_memory_limit);
            
            // Increase execution time for large sites
            if (function_exists('set_time_limit')) {
                set_time_limit(0);
            }
            
            // Enable garbage collection and optimize
            gc_enable();
            gc_collect_cycles();
            
            // Create ZIP archive with optimized settings
            $backup_path = $this->_backup_dir . 'lc_migrator_' . date('Y-m-d_H-i-s') . '.zip';
            $this->_zip = new ZipArchive();
            
            if ($this->_zip->open($backup_path, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
                throw new Exception("Failed to create ZIP archive");
            }

            // Optimize ZIP settings for large files
            $this->_zip->setArchiveComment('Created by LC Migrator');
            
            // Store the backup path for later use
            if ($this->_backupInProgress) {
                $this->_backupInProgress->setMetadata('backup_path', $backup_path);
                $this->_backupInProgress->setMetadata('start_time', time());
            }

            return [
                'success' => true,
                'backup_path' => $backup_path
            ];
        } catch (Exception $e) {
            $this->_logger->error("Export initialization failed: " . $e->getMessage());
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Export WordPress core files
     * 
     * @return bool True on success, false on failure
     */
    public function exportWordPressCore() 
    {
        try {
            $this->_logger->info("Exporting WordPress core files");
            
            $backup_path = $this->_backupInProgress ? 
                $this->_backupInProgress->getMetadata('backup_path') : 
                $this->_backup_dir . 'lc_migrator_' . date('Y-m-d_H-i-s') . '.zip';
            
            $batch_files = [];
            $current_batch_size = 0;
            
            // Track progress
            $total_files_processed = 0;
            $total_size_processed = 0;
            
            // Add essential files first
            foreach ($this->_essential_files as $file) {
                $file_path = ABSPATH . $file;
                if (file_exists($file_path) && !$this->_shouldExclude($file_path)) {
                    $file_size = filesize($file_path);
                    if (($current_batch_size + $file_size) > $this->_batch_size) {
                        $this->_processBatch($batch_files, $backup_path);
                        $total_files_processed += count($batch_files);
                        $total_size_processed += $current_batch_size;
                        $batch_files = [];
                        $current_batch_size = 0;
                        gc_collect_cycles();
                    }
                    
                    $batch_files[] = [
                        'source' => $file_path,
                        'destination' => $file
                    ];
                    $current_batch_size += $file_size;
                }
            }

            // Process wp-admin and wp-includes first (usually smaller)
            $prioritized_dirs = ['wp-admin', 'wp-includes'];
            foreach ($prioritized_dirs as $dir) {
                $this->_logger->info("Processing directory: " . $dir);
                
                $dir_path = ABSPATH . $dir;
                if (is_dir($dir_path)) {
                    list($batch_files, $current_batch_size) = $this->_collectFilesFromDirectoryBatched(
                        $dir_path, 
                        $dir, 
                        $batch_files, 
                        $current_batch_size,
                        $backup_path
                    );
                }
            }

            // Process any remaining files before wp-content
            if (!empty($batch_files)) {
                $this->_processBatch($batch_files, $backup_path);
                $total_files_processed += count($batch_files);
                $total_size_processed += $current_batch_size;
                $batch_files = [];
                $current_batch_size = 0;
                gc_collect_cycles();
            }

            // Process wp-content separately with special handling
            $wp_content_processed = $this->_processWpContent($backup_path);
            
            if (!$wp_content_processed) {
                $this->_logger->error("Failed to process wp-content directory");
                return false;
            }

            $this->_logger->info(sprintf(
                "WordPress core export completed successfully"
            ));

            return true;
        } catch (Exception $e) {
            $this->_logger->error("Failed to export WordPress core: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Process a batch of files with optimized handling for large files
     *
     * @param array  $batch_files Array of files to process
     * @param string $backup_path Path to the backup file
     * 
     * @return void
     */
    private function _processBatch($batch_files, $backup_path) 
    {
        if (empty($batch_files)) {
            return;
        }

        // Check if we're running too long
        if ($this->_shouldYieldForTimeout()) {
            $this->_logger->info("Batch processing yielding due to timeout");
            return;
        }

        try {
            $large_files = [];
            $regular_files = [];

            // Separate large files for special handling
            foreach ($batch_files as $file) {
                if ($this->_backupInProgress && $this->_backupInProgress->getMetadata('force_closed') === true) {
                    $this->_logger->info("Backup was force closed during batch processing");
                    $this->_backupInProgress->setMetadata('status', 'failed');
                    $this->_backupInProgress->setMetadata('error', 'Backup was stopped during compression');
                    return;
                }

                if (!file_exists($file['source'])) {
                    $this->_logger->warning("File not found during batch processing: " . $file['source']);
                    continue;
                }

                $file_size = filesize($file['source']);
                if ($file_size > $this->_max_direct_copy_size) {
                    $large_files[] = $file;
                } else {
                    $regular_files[] = $file;
                }
            }

            // Process regular files in bulk
            foreach ($regular_files as $file) {
                if (!$this->_zip->addFile($file['source'], $file['destination'])) {
                    $this->_logger->error("Failed to add file to ZIP: " . $file['source']);
                }
                $this->_zip->setCompressionName($file['destination'], ZipArchive::CM_STORE);
            }

            // Process large files with streaming
            foreach ($large_files as $file) {
                $this->_addLargeFile($file['source'], $file['destination']);
            }

            // Only close and reopen if we've added files
            if (!empty($regular_files) || !empty($large_files)) {
                $this->_zip->close();
                
                // Use CREATE flag without OVERWRITE to append to existing archive
                if ($this->_zip->open($backup_path, ZipArchive::CREATE) !== true) {
                    throw new Exception("Failed to reopen ZIP archive: " . $backup_path);
                }
            }
            
            gc_collect_cycles();
            
        } catch (Exception $e) {
            $this->_logger->error("Error in batch processing: " . $e->getMessage());
            throw $e;
        }
    }

    /**
     * Check if we should yield processing due to timeout
     *
     * @return bool
     */
    private function _shouldYieldForTimeout()
    {
        if (!isset($this->_batch_start_time)) {
            $this->_batch_start_time = microtime(true);
            return false;
        }
        
        $elapsed = microtime(true) - $this->_batch_start_time;
        return $elapsed > $this->_max_batch_time;
    }

    /**
     * Add a large file to the ZIP archive using streaming
     *
     * @param string $source      Source file path
     * @param string $destination Destination in ZIP
     * 
     * @return void
     */
    private function _addLargeFile($source, $destination)
    {
        $chunk_size = 1024 * 1024 * 10; // 10MB chunks for better performance
        $handle = fopen($source, 'rb');
        
        if ($handle) {
            // Use ZipArchive::addFile with streaming for large files
            // This is more efficient than addFromString
            $temp_file = tempnam(sys_get_temp_dir(), 'lc_migrator_chunk_');
            $temp_handle = fopen($temp_file, 'wb');
            
            while (!feof($handle)) {
                if ($this->_backupInProgress && $this->_backupInProgress->getMetadata('force_closed') === true) {
                    fclose($handle);
                    fclose($temp_handle);
                    unlink($temp_file);
                    $this->_logger->info("Large file processing interrupted: " . $destination);
                    return;
                }
                
                $chunk = fread($handle, $chunk_size);
                fwrite($temp_handle, $chunk);
            }
            
            fclose($handle);
            fclose($temp_handle);
            
            // Add the complete file to ZIP
            $this->_zip->addFile($temp_file, $destination);
            $this->_zip->setCompressionName($destination, ZipArchive::CM_STORE);
            
            // Clean up temp file after ZIP processes it
            register_shutdown_function(function() use ($temp_file) {
                if (file_exists($temp_file)) {
                    unlink($temp_file);
                }
            });
        }
    }

    /**
     * Get system memory limit
     *
     * @return int Memory limit in bytes
     */
    private function _getSystemMemoryLimit()
    {
        if (function_exists('sys_get_temp_dir')) {
            $memory_limit = trim(shell_exec('free -b | grep Mem | awk \'{print $2}\''));
            if ($memory_limit) {
                return (int)$memory_limit;
            }
        }
        return 2147483648; // Default to 2GB if cannot determine
    }

    /**
     * Collect files from directory recursively with batch processing
     *
     * @param string $source           Source directory
     * @param string $destination      Destination in ZIP
     * @param array  $batch_files      Reference to batch files array
     * @param int    $current_size     Current batch size
     * @param string $backup_path      Path to the backup file
     * 
     * @return array Updated batch files array
     */
    private function _collectFilesFromDirectoryBatched($source, $destination, $batch_files, $current_size, $backup_path) 
    {
        if (!is_dir($source) || !($dir = opendir($source))) {
            $this->_logger->warning("Cannot open directory: " . $source);
            return [$batch_files, $current_size];
        }

        $files_in_current_batch = count($batch_files);

        while (($file = readdir($dir)) !== false) {
            // Check for force close
            if ($this->_backupInProgress && $this->_backupInProgress->getMetadata('force_closed') === true) {
                $this->_logger->info("Directory traversal interrupted at: " . $source);
                closedir($dir);
                return [$batch_files, $current_size];
            }

            if ($file === '.' || $file === '..' || $this->_shouldExclude($source . '/' . $file)) {
                continue;
            }

            $source_path = $source . '/' . $file;
            $dest_path = $destination . '/' . $file;

            if (is_dir($source_path)) {
                // Process subdirectory
                list($batch_files, $current_size) = $this->_collectFilesFromDirectoryBatched(
                    $source_path, 
                    $dest_path, 
                    $batch_files, 
                    $current_size,
                    $backup_path
                );
                $files_in_current_batch = count($batch_files);
            } else {
                if (!is_readable($source_path)) {
                    $this->_logger->warning("File not readable: " . $source_path);
                    continue;
                }

                $file_size = filesize($source_path);
                
                // Check if we need to process the current batch
                if (($current_size + $file_size) > $this->_batch_size || 
                    $files_in_current_batch >= $this->_max_files_per_batch) {
                    
                    $this->_logger->info(sprintf(
                        "Processing batch: %d files, %.2f MB", 
                        count($batch_files), 
                        $current_size / 1024 / 1024
                    ));
                    
                    $this->_processBatch($batch_files, $backup_path);
                    $batch_files = [];
                    $current_size = 0;
                    $files_in_current_batch = 0;
                    gc_collect_cycles();
                }

                $batch_files[] = [
                    'source' => $source_path,
                    'destination' => $dest_path
                ];
                $current_size += $file_size;
                $files_in_current_batch++;
            }
        }
        closedir($dir);

        return [$batch_files, $current_size];
    }

    /**
     * Check if a file or directory should be excluded from backup
     *
     * @param string $path Path to check (can be file or directory)
     * 
     * @return bool True if should be excluded, false otherwise
     */
    private function _shouldExclude($path) 
    {
        // Get both the basename and full relative path
        $basename = basename($path);
        $relative_path = str_replace(ABSPATH, '', $path);
        
        foreach ($this->_exclude_patterns as $pattern) {
            // Check if pattern matches either the basename or the full relative path
            if (fnmatch($pattern, $basename) || fnmatch($pattern, $relative_path)) {
                $this->_logger->debug("Excluding path based on pattern '$pattern': $path");
                return true;
            }
            
            // Handle directory wildcards (pattern ending with /*)
            if (substr($pattern, -2) === '/*' && is_dir($path)) {
                $dir_pattern = rtrim($pattern, '/*');
                if (fnmatch($dir_pattern, $basename) || fnmatch($dir_pattern, $relative_path)) {
                    $this->_logger->debug("Excluding directory based on pattern '$pattern': $path");
                    return true;
                }
            }
        }
        
        // Check file size limit (e.g., 500MB)
        if (is_file($path) && filesize($path) > 524288000) { // 500MB in bytes
            $this->_logger->warning("Excluding large file (>500MB): $path");
            return true;
        }
        
        return false;
    }

    /**
     * Export database
     * 
     * @return bool True on success, false on failure
     */
    public function exportDatabase() 
    {
        try {
            $this->_logger->info("Starting database export");

            $databaseFile = $this->_backup_dir . 'database_backup.sql';
            $databaseExporter = DatabaseExporter::execute(["db_path" => $databaseFile]);
            $this->_logger->info("Database dump executed");
            $this->_zip->addFile($databaseFile, 'database_backup.sql');
            $this->_zip->setCompressionName('database_backup.sql', ZipArchive::CM_STORE);
            
            return true;
        } catch (Exception $e) {
            $this->_logger->error("Database export failed: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Export site configuration
     * 
     * @return bool True on success, false on failure
     */
    public function exportSiteConfig() 
    {
        try {
            $this->_logger->info("Exporting site configuration");

            $config_file = $this->_backup_dir . 'site_config.json';
            $configBuilder = Config::execute([], $config_file, $this->_logger);
            $this->_zip->addFile($config_file, 'package.json');
            $this->_zip->setCompressionName('site_config.json', ZipArchive::CM_STORE);

            return true;
        } catch (Exception $e) {
            $this->_logger->error("Site configuration export failed: " . $e->getMessage());
            return false;
        }
    }

    public function exportWordpresContent(){
        try{
            $this->_logger->info("Exporting WordPress content");
            $this->_backupInProgress->setMetadata('message', 'Adding wp-content directory...');
            $this->add_directory_to_zip($this->_zip, ABSPATH . 'wp-content', 'wp-content');
            return true;
        } catch (Exception $e) {
            $this->_logger->error("WordPress content export failed: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Recursively add a directory to the ZIP archive
     * 
     * @param string $source      Source directory
     * @param string $destination Destination in ZIP
     * 
     * @return void
     */
    private function _addDirectoryToZip($source, $destination) 
    {
        $dir = opendir($source);
        while ($file = readdir($dir)) {
            if ($file == '.' || $file == '..') {
                continue;
            }

            $source_path = $source . '/' . $file;
            $dest_path = $destination . '/' . $file;

            if (is_dir($source_path)) {
                $this->_addDirectoryToZip($source_path, $dest_path);
            } else {
                $this->_zip->addFile($source_path, $dest_path);
            }
        }
        closedir($dir);
    }

    /**
     * Finalize the export process
     * 
     * @return array Success status and message or error details
     */
    public function finalizeExport() 
    {
        try {
            $this->_logger->info("Finalizing export");
            $this->_zip->close();

            return [
                'success' => true,
                'message' => 'Export completed successfully'
            ];
        } catch (Exception $e) {
            $this->_logger->error("Export finalization failed: " . $e->getMessage());
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Process wp-content directory with special handling for large directories
     *
     * @param string $backup_path Path to the backup file
     * 
     * @return bool
     */
    private function _processWpContent($backup_path)
    {
        $wp_content_path = WP_CONTENT_DIR;
        if (!is_dir($wp_content_path)) {
            $this->_logger->error("wp-content directory not found: " . $wp_content_path);
            return false;
        }

        $this->_logger->info("Starting special processing for wp-content directory");
        
        // Process wp-content subdirectories individually for better control
        $subdirs = ['themes', 'plugins', 'uploads', 'mu-plugins', 'languages'];
        
        foreach ($subdirs as $subdir) {
            $subdir_path = $wp_content_path . '/' . $subdir;
            if (!is_dir($subdir_path)) {
                continue;
            }
            
            $this->_logger->info("Processing wp-content/$subdir");
            
            // Update progress
            if ($this->_backupInProgress) {
                $this->_backupInProgress->setMetadata('current_directory', "wp-content/$subdir");
            }
            
            $batch_files = [];
            $current_batch_size = 0;
            
            list($batch_files, $current_batch_size) = $this->_collectFilesFromDirectoryBatched(
                $subdir_path,
                "wp-content/$subdir",
                $batch_files,
                $current_batch_size,
                $backup_path
            );
            
            // Process any remaining files
            if (!empty($batch_files)) {
                $this->_processBatch($batch_files, $backup_path);
            }
            
            gc_collect_cycles();
        }
        
        // Process any remaining files in wp-content root
        $this->_processWpContentRoot($wp_content_path, $backup_path);
        
        // Verify wp-content was added successfully
        return $this->_verifyWpContentInZip($backup_path);
    }

    /**
     * Process files in wp-content root directory
     *
     * @param string $wp_content_path Path to wp-content
     * @param string $backup_path Path to backup file
     * 
     * @return void
     */
    private function _processWpContentRoot($wp_content_path, $backup_path)
    {
        // These are the subdirectories already processed by _processWpContent's loop
        $processed_subdirs = ['themes', 'plugins', 'uploads', 'mu-plugins', 'languages'];

        $dir = opendir($wp_content_path);
        if (!$dir) {
            $this->_logger->warning("Cannot open wp-content root directory: " . $wp_content_path);
            return;
        }
        
        $batch_files = [];
        $current_batch_size = 0;
        
        while (($file = readdir($dir)) !== false) {
            if ($file === '.' || $file === '..' || $this->_shouldExclude($wp_content_path . '/' . $file)) {
                continue;
            }
            
            $file_path = $wp_content_path . '/' . $file;
            $destination_path = 'wp-content/' . $file; // Destination path in ZIP

            if (is_dir($file_path)) {
                // If this directory is one of the predefined subdirs, skip it, as it was already processed.
                if (in_array($file, $processed_subdirs, true)) {
                    continue; 
                }

                // This is an "other" directory in wp-content root that wasn't in the predefined list. Process it.
                $this->_logger->info("Processing additional directory in wp-content root: " . $file);
                
                list($batch_files, $current_batch_size) = $this->_collectFilesFromDirectoryBatched(
                    $file_path,          // Full source path of the directory
                    $destination_path,   // Destination path in ZIP (e.g., wp-content/custom-folder)
                    $batch_files,
                    $current_batch_size,
                    $backup_path
                );
                // Batching and gc_collect_cycles are handled within _collectFilesFromDirectoryBatched
                // or by the final _processBatch call after this loop.
            } else { // It's a file at the root of wp-content
                if (!is_readable($file_path)) {
                    $this->_logger->warning("File not readable in wp-content root: " . $file_path);
                    continue;
                }
                
                $file_size = filesize($file_path);
                
                // Check if we need to process the current batch (due to size or file count)
                if (($current_batch_size + $file_size) > $this->_batch_size || 
                    count($batch_files) >= $this->_max_files_per_batch) { 
                    
                    $this->_logger->info(sprintf(
                        "Processing batch from wp-content root: %d files, %.2f MB", 
                        count($batch_files), 
                        $current_batch_size / 1024 / 1024
                    ));

                    $this->_processBatch($batch_files, $backup_path);
                    $batch_files = [];
                    $current_batch_size = 0;
                    gc_collect_cycles();
                }
                
                $batch_files[] = [
                    'source' => $file_path,
                    'destination' => $destination_path
                ];
                $current_batch_size += $file_size;
            }
        }
        
        closedir($dir);
        
        // Process any remaining files accumulated from the wp-content root or "other" directories
        if (!empty($batch_files)) {
            $this->_logger->info(sprintf(
                "Processing final batch from wp-content root: %d files, %.2f MB", 
                count($batch_files), 
                $current_batch_size / 1024 / 1024
            ));
            $this->_processBatch($batch_files, $backup_path);
        }
    }

    /**
     * Verify wp-content exists in the ZIP archive
     *
     * @param string $backup_path Path to backup file
     * 
     * @return bool
     */
    private function _verifyWpContentInZip($backup_path)
    {
        try {
            // Close current ZIP handle
            $this->_zip->close();
            
            // Open for reading
            $verify_zip = new ZipArchive();
            if ($verify_zip->open($backup_path, ZipArchive::RDONLY) !== true) {
                $this->_logger->error("Failed to open ZIP for verification");
                return false;
            }
            
            // Check for wp-content entries
            $wp_content_found = false;
            for ($i = 0; $i < $verify_zip->numFiles; $i++) {
                $stat = $verify_zip->statIndex($i);
                if (strpos($stat['name'], 'wp-content/') === 0) {
                    $wp_content_found = true;
                    break;
                }
            }
            
            $verify_zip->close();
            
            if (!$wp_content_found) {
                $this->_logger->error("wp-content not found in ZIP archive!");
            } else {
                $this->_logger->info("wp-content verified in ZIP archive");
            }
            
            // Reopen for further operations
            $this->_zip->open($backup_path, ZipArchive::CREATE);
            
            return $wp_content_found;
            
        } catch (Exception $e) {
            $this->_logger->error("Error verifying wp-content: " . $e->getMessage());
            return false;
        }
    }
} 