<?php
/**
 * Class Renamer_File_Processor
 * Handles the actual file renaming operations
 */

// Impedisce l'accesso diretto
if (!defined('ABSPATH')) {
    exit;
}
class Renamer_File_Processor {
    
    /**
     * Singleton instance
     */
    private static $instance = null;
    
    /**
     * Managers interni
     */
    private $logs_manager;
    private $pattern_manager;
    private $integration_manager;
    private $settings_manager;
    
    /**
     * Initialize the class and set its properties.
     */
    private function __construct() {
        // Dipendenza da logs manager per le operazioni di logging
        require_once plugin_dir_path(__FILE__) . 'class-renamer-logs-manager.php';
        $this->logs_manager = Renamer_Logs_Manager::get_instance();
        
        // Le altre dipendenze potrebbero non essere ancora disponibili qui
        add_action('init', array($this, 'late_initialize'), 20);
    }
    
    /**
     * Inizializzazione tardiva per componenti che potrebbero non essere ancora disponibili
     */
    public function late_initialize() {
        if (class_exists('Renamer_Pattern_Manager')) {
            $this->pattern_manager = Renamer_Pattern_Manager::get_instance();
        }
        
        if (class_exists('Renamer_Settings_Manager')) {
            $this->settings_manager = Renamer_Settings_Manager::get_instance();
        }
        
        // Non caricare l'integration manager immediatamente per risparmiare memoria
        // Verrà caricato solo quando effettivamente necessario
    }
    
    /**
     * Get the singleton instance
     */
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Rename an image file
     * 
     * @param int $attachment_id The attachment ID
     * @param string $new_filename The new filename (without extension)
     * @param array $options Opzioni aggiuntive per la rinomina
     * @return array|WP_Error Result of the rename operation
     */
    public function rename_image($attachment_id, $new_filename, $options = array()) {
        // Check if attachment exists
        $attachment = get_post($attachment_id);
        if (!$attachment || $attachment->post_type !== 'attachment') {
            return new WP_Error('invalid_attachment', __('Invalid attachment.', 'imgseo-ai-alt-text-generator'));
        }
        
        // Get attachment file path
        $file = get_attached_file($attachment_id);
        if (!$file || !file_exists($file)) {
            return new WP_Error('file_not_found', __('Attachment file not found.', 'imgseo-ai-alt-text-generator'));
        }
        
        // Get file info
        $path_parts = pathinfo($file);
        $old_filename = basename($file);
        $old_filename_base = $path_parts['filename'];
        $extension = isset($path_parts['extension']) ? $path_parts['extension'] : '';
        $dir_path = $path_parts['dirname'];
        
        if (empty($extension)) {
            return new WP_Error('no_extension', __('Could not determine file extension.', 'imgseo-ai-alt-text-generator'));
        }
        
        // Applica pattern se pattern manager è disponibile e l'opzione è attivata
        if (!empty($options['use_patterns']) && !empty($options['pattern']) && $this->pattern_manager) {
            $context = array(
                'original_filename' => $old_filename_base,
                'attachment_id' => $attachment_id,
            );
            
            // Genera il nuovo nome file usando il pattern fornito
            $pattern_result = $this->pattern_manager->apply_patterns($options['pattern'], $attachment_id, $context);
            
            // Usa il risultato del pattern solo se non è vuoto
            if (!empty($pattern_result)) {
                $new_filename = $pattern_result;
            }
        }
        
        // Applica sanitizzazione opzionale al nuovo nome file
        if (!empty($options['sanitize'])) {
            $sanitize_options = array();
            
            // Imposta opzioni di sanitizzazione dalle opzioni o dalle impostazioni
            $sanitize_options['remove_accents'] = isset($options['remove_accents']) ? 
                (bool)$options['remove_accents'] : 
                ($this->settings_manager ? $this->settings_manager->is_enabled('remove_accents') : true);
                
            $sanitize_options['lowercase'] = isset($options['lowercase']) ? 
                (bool)$options['lowercase'] : 
                ($this->settings_manager ? $this->settings_manager->is_enabled('lowercase') : true);
            
            // Sanitizza usando il pattern manager o una sanitizzazione base
            if ($this->pattern_manager) {
                $new_filename = $this->pattern_manager->sanitize_filename($new_filename, $sanitize_options);
            } else {
                // Sanitizzazione base fallback
                if ($sanitize_options['remove_accents']) {
                    $new_filename = remove_accents($new_filename);
                }
                
                if ($sanitize_options['lowercase']) {
                    $new_filename = strtolower($new_filename);
                }
                
                // Sostituisci caratteri non alfanumerici con trattini
                $new_filename = preg_replace('/[^a-zA-Z0-9\-_]/', '-', $new_filename);
                $new_filename = preg_replace('/-+/', '-', $new_filename);
                $new_filename = trim($new_filename, '-');
            }
        }
        
        // Gestisci i nomi file duplicati
        $handle_duplicates = isset($options['handle_duplicates']) ?
            $options['handle_duplicates'] :
            ($this->settings_manager ? $this->settings_manager->get_setting('handle_duplicates', 'increment') : 'increment');

        $new_filename_with_ext = $this->handle_duplicate_filename($new_filename, $extension, $dir_path, $handle_duplicates);

        // Se la gestione duplicati restituisce false, significa che non dobbiamo rinominare
        if ($new_filename_with_ext === false) {
            return new WP_Error('duplicate_filename', __('A file with this name already exists and duplicate handling is set to fail.', 'imgseo-ai-alt-text-generator'));
        }

        // Manteniamo il nuovo nome file come restituito dalla gestione duplicati
        // Non estraiamo nuovamente il filename base perché potrebbe contenere suffissi come -1, -2, etc.
        $final_new_filename = $new_filename_with_ext;
        
        // Check if new filename is same as old
        if ($old_filename === $final_new_filename) {
            return new WP_Error('same_filename', __('The new filename is the same as the current one.', 'imgseo-ai-alt-text-generator'));
        }

        // Create the new file path
        $new_file = str_replace($old_filename, $final_new_filename, $file);
        
        // Get the current metadata
        $old_metadata = wp_get_attachment_metadata($attachment_id);
        
        // Calculate OLD URL before any changes (for reference updates)
        $old_attachment_url = wp_get_attachment_url($attachment_id);
        
        // Get current thumbnails before rename
        $old_thumbnails = array();
        if (!empty($old_metadata['sizes'])) {
            foreach ($old_metadata['sizes'] as $size_name => $size_info) {
                $old_thumbnail_file = $dir_path . '/' . $size_info['file'];
                if (file_exists($old_thumbnail_file)) {
                    $old_thumbnails[$size_name] = $old_thumbnail_file;
                }
            }
        }
        
        try {
            // Start a transaction if possible
            global $wpdb;
            $wpdb->query('START TRANSACTION');
            
            // Rename the main file using WP_Filesystem
            if (!WP_Filesystem()) {
                $wpdb->query('ROLLBACK');
                $this->logs_manager->log_rename_operation($attachment_id, $old_filename, $final_new_filename, 'error');
                return false;
            }
            global $wp_filesystem;
            if (!$wp_filesystem->move($file, $new_file)) {
                $wpdb->query('ROLLBACK');
                $this->logs_manager->log_rename_operation($attachment_id, $old_filename, $final_new_filename, 'error');
                return new WP_Error('rename_failed', __('Failed to rename the file.', 'imgseo-ai-alt-text-generator'));
            }
            
            // Update attachment metadata file path
            update_attached_file($attachment_id, $new_file);
            
            // Manually rename all existing thumbnails - first get a complete inventory of all thumbnails
            $renamed_thumbnails = array();
            $upload_dir = wp_upload_dir();
            $base_dir = $upload_dir['basedir'];
            $file_dir = dirname($file);
            
            // First, rename thumbnails that are in the metadata
            foreach ($old_thumbnails as $size_name => $old_thumbnail_path) {
                $thumb_path_parts = pathinfo($old_thumbnail_path);
                $thumb_old_filename = $thumb_path_parts['basename'];
                
                // Replace the base filename part in the thumbnail filename
                $new_filename_base = pathinfo($final_new_filename, PATHINFO_FILENAME);
                $thumb_new_filename = str_replace($old_filename_base, $new_filename_base, $thumb_old_filename);
                $thumb_new_path = $thumb_path_parts['dirname'] . '/' . $thumb_new_filename;
                
                // Rename the thumbnail file
                if (file_exists($old_thumbnail_path)) {
                    if ($wp_filesystem->move($old_thumbnail_path, $thumb_new_path)) {
                        $renamed_thumbnails[$size_name] = $thumb_new_path;
                        // Debug: Renamed thumbnail
                    }
                }
            }
            
            // Then search for any other thumbnail sizes that might not be in the metadata
            // Common WordPress thumbnail pattern is: filename-WIDTHxHEIGHT.ext
            $dir_handle = opendir($file_dir);
            if ($dir_handle) {
                $pattern = '/^' . preg_quote($old_filename_base, '/') . '-\d+x\d+\.[a-zA-Z0-9]+$/';
                
                while (($file_in_dir = readdir($dir_handle)) !== false) {
                    // Skip . and .. directories
                    if ($file_in_dir == '.' || $file_in_dir == '..') {
                        continue;
                    }
                    
                    // Check if this is a thumbnail file for our image
                    if (preg_match($pattern, $file_in_dir)) {
                        $old_thumb_path = $file_dir . '/' . $file_in_dir;
                        
                        // Only continue if this thumbnail wasn't already renamed above
                        if (!in_array($old_thumb_path, $old_thumbnails)) {
                            // Create new thumbnail filename
                            $new_thumb_filename = str_replace($old_filename_base, $new_filename_base, $file_in_dir);
                            $new_thumb_path = $file_dir . '/' . $new_thumb_filename;
                            
                            // Rename the thumbnail
                            if ($wp_filesystem->move($old_thumb_path, $new_thumb_path)) {
                                $renamed_thumbnails['extra_' . count($renamed_thumbnails)] = $new_thumb_path;
                                // Debug: Renamed additional thumbnail
                            }
                        }
                    }
                }
                
                closedir($dir_handle);
            }
            
            // Generate metadata for the attachment
            $metadata = wp_generate_attachment_metadata($attachment_id, $new_file);
            
            // Update the database to use the new metadata
            wp_update_attachment_metadata($attachment_id, $metadata);
            
            // Update post guid if needed
            $guid = get_the_guid($attachment_id);
            if (strpos($guid, $old_filename) !== false) {
                $new_guid = str_replace($old_filename, $final_new_filename, $guid);
                $wpdb->update(
                    $wpdb->posts,
                    array('guid' => $new_guid),
                    array('ID' => $attachment_id)
                );
            }
            
            // Get old and new attachment URLs for reference updates
            $old_url_base = $old_attachment_url; // URL before rename (saved earlier)
            $new_url = wp_get_attachment_url($attachment_id); // URL after rename (updated)
            
            // Prepara array di vecchi e nuovi URL per gli aggiornamenti
            $old_urls = array($old_url_base);
            $new_urls = array($new_url);
            
            // Raccogli URL di miniature per gli aggiornamenti
            if (!empty($old_metadata['sizes'])) {
                foreach ($old_metadata['sizes'] as $size => $size_info) {
                    $old_size_file = $size_info['file'];
                    $old_size_url = str_replace(basename($old_url_base), $old_size_file, $old_url_base);
                    $old_urls[] = $old_size_url;
                    
                    // Calcola l'URL nuovo corrispondente
                    $new_size_file = str_replace($old_filename_base, $new_filename_base, $old_size_file);
                    $new_size_url = str_replace(basename($new_url), $new_size_file, $new_url);
                    $new_urls[] = $new_size_url;
                }
            }
            
            // Determina se dobbiamo aggiornare i riferimenti (manteniamo compatibilità con vecchie versioni)
            $update_references = isset($options['update_references']) ? (bool)$options['update_references'] : true;
            
            if ($update_references) {
                // Fix: Extract directory from old_url_base since it contains the full file URL
                $old_url_directory = dirname($old_url_base);
                $new_url_directory = dirname($new_url);
                
                // Update URLs in post content with correct directory paths
                $this->update_image_references($old_filename_base, $new_filename_base, $old_url_directory, $new_url_directory);
                
                // Aggiorna riferimenti nei page builder usando l'Integration Manager SOLO se necessario
                $integration_results = array();
                $enable_integrations = get_option('imgseo_renamer_enable_integrations', 1);
                
                if ($enable_integrations && !defined('IMGSEO_DISABLE_INTEGRATIONS')) {
                    // Carica l'integration manager solo se effettivamente necessario
                    if (!$this->integration_manager && class_exists('Renamer_Integration_Manager')) {
                        $this->integration_manager = Renamer_Integration_Manager::get_instance();
                    }
                    
                    if ($this->integration_manager) {
                        $integration_results = $this->integration_manager->update_all_references($old_urls, $new_urls, $attachment_id);
                    }
                }
                
                // Force refresh post caches (solo se stiamo aggiornando i riferimenti)
                clean_post_cache($attachment_id);
                
                // Clear all WordPress caches to ensure URL updates are reflected immediately
                wp_cache_flush();
                
                // Force regeneration of attachment metadata to update URLs
                wp_update_attachment_metadata($attachment_id, wp_get_attachment_metadata($attachment_id));
                
                // Debug: Cache cleared and metadata updated
            }
            
            // Update _wp_attached_file again to ensure it's correctly set
            update_post_meta($attachment_id, '_wp_attached_file', str_replace(trailingslashit($upload_dir['basedir']), '', $new_file));
            
            // Log the successful operation
            $this->logs_manager->log_rename_operation($attachment_id, $old_filename, $final_new_filename, 'success');
            
            // Commit the transaction
            $wpdb->query('COMMIT');
            
            return array(
                'old_filename' => $old_filename,
                'new_filename' => $final_new_filename,
                'new_url' => $new_url,
                'thumbnails_renamed' => count($renamed_thumbnails),
                'integration_results' => $integration_results
            );
            
        } catch (Exception $e) {
            // Rollback the transaction
            $wpdb->query('ROLLBACK');
            
            // Log the error
            $this->logs_manager->log_rename_operation($attachment_id, $old_filename, $final_new_filename, 'error');
            
            return new WP_Error('exception', $e->getMessage());
        }
    }
    
    /**
     * Gestisce la generazione di nomi file in caso di duplicati
     * 
     * @param string $filename Nome file base (senza estensione)
     * @param string $extension Estensione del file
     * @param string $dir_path Percorso della directory
     * @param string $mode Modalità di gestione ("increment", "timestamp", "fail")
     * @return string|false Nuovo nome file con estensione o false se fallisce
     */
    private function handle_duplicate_filename($filename, $extension, $dir_path, $mode = 'increment') {
        $filename_with_ext = $filename . '.' . $extension;
        $file_path = $dir_path . '/' . $filename_with_ext;
        
        // Se il file non esiste già, usa il nome originale
        if (!file_exists($file_path)) {
            return $filename_with_ext;
        }
        
        // Gestisci il caso in cui esiste già un file con questo nome
        switch ($mode) {
            case 'increment':
                // Aggiungi un numero incrementale (file-1.jpg, file-2.jpg, ecc.)
                $i = 1;
                while (file_exists($dir_path . '/' . $filename . '-' . $i . '.' . $extension)) {
                    $i++;
                }
                return $filename . '-' . $i . '.' . $extension;
                
            case 'timestamp':
                // Aggiungi un timestamp (file-1679419361.jpg)
                return $filename . '-' . time() . '.' . $extension;
                
            case 'fail':
                // Non rinominare se esiste già un file con lo stesso nome
                return false;
                
            default:
                return $filename_with_ext;
        }
    }
    
    /**
     * Restore a previously renamed image file to its original filename
     * 
     * @param int $attachment_id The attachment ID
     * @param string $original_filename The original filename to restore to
     * @param string $current_filename The current filename
     * @return array|WP_Error Result of the restore operation
     */
    public function restore_image($attachment_id, $original_filename, $current_filename) {
        // Check if attachment exists
        $attachment = get_post($attachment_id);
        if (!$attachment || $attachment->post_type !== 'attachment') {
            return new WP_Error('invalid_attachment', __('Invalid attachment.', 'imgseo-ai-alt-text-generator'));
        }
        
        // Get attachment file path
        $file = get_attached_file($attachment_id);
        if (!$file || !file_exists($file)) {
            return new WP_Error('file_not_found', __('Attachment file not found.', 'imgseo-ai-alt-text-generator'));
        }
        
        // Extract original and current filename components
        $orig_path_parts = pathinfo($original_filename);
        $curr_path_parts = pathinfo($current_filename);
        
        $original_base = $orig_path_parts['filename'];
        $current_base = $curr_path_parts['filename'];
        $extension = isset($curr_path_parts['extension']) ? $curr_path_parts['extension'] : '';
        
        if (empty($extension)) {
            return new WP_Error('no_extension', __('Could not determine file extension.', 'imgseo-ai-alt-text-generator'));
        }
        
        // Get the directory from the current file path
        $dir_path = pathinfo($file, PATHINFO_DIRNAME);
        
        // Set the paths for renaming
        $current_path = $file;
        $original_path = $dir_path . '/' . $original_filename;
        
        // Check if the original filename already exists (to prevent conflicts)
        if (file_exists($original_path)) {
            return new WP_Error('file_exists', __('Cannot restore: a file with the original filename already exists.', 'imgseo-ai-alt-text-generator'));
        }
        
        // Get the current metadata
        $old_metadata = wp_get_attachment_metadata($attachment_id);
        
        // Calculate CURRENT URL before any changes (for reference updates during restore)
        $current_attachment_url = wp_get_attachment_url($attachment_id);
        
        // Get current thumbnails before rename
        $current_thumbnails = array();
        if (!empty($old_metadata['sizes'])) {
            foreach ($old_metadata['sizes'] as $size_name => $size_info) {
                $current_thumbnail_file = $dir_path . '/' . $size_info['file'];
                if (file_exists($current_thumbnail_file)) {
                    $current_thumbnails[$size_name] = $current_thumbnail_file;
                }
            }
        }
        
        try {
            // Start a transaction if possible
            global $wpdb;
            $wpdb->query('START TRANSACTION');
            
            // Rename the main file using WP_Filesystem
            if (!WP_Filesystem()) {
                $wpdb->query('ROLLBACK');
                $this->logs_manager->log_rename_operation($attachment_id, $current_filename, $original_filename, 'error');
                return false;
            }
            global $wp_filesystem;
            if (!$wp_filesystem->move($current_path, $original_path)) {
                $wpdb->query('ROLLBACK');
                $this->logs_manager->log_rename_operation($attachment_id, $current_filename, $original_filename, 'error');
                return new WP_Error('rename_failed', __('Failed to restore the file.', 'imgseo-ai-alt-text-generator'));
            }
            
            // Update attachment metadata file path
            update_attached_file($attachment_id, $original_path);
            
            // Manually rename all existing thumbnails - first get a complete inventory of all thumbnails
            $restored_thumbnails = array();
            $upload_dir = wp_upload_dir();
            $base_dir = $upload_dir['basedir'];
            $file_dir = dirname($file);
            
            // First, rename thumbnails that are in the metadata
            foreach ($current_thumbnails as $size_name => $current_thumb_path) {
                $thumb_path_parts = pathinfo($current_thumb_path);
                $thumb_current_filename = $thumb_path_parts['basename'];
                
                // Replace the base filename part in the thumbnail filename
                $thumb_original_filename = str_replace($current_base, $original_base, $thumb_current_filename);
                $thumb_original_path = $thumb_path_parts['dirname'] . '/' . $thumb_original_filename;
                
                // Rename the thumbnail file
                if (file_exists($current_thumb_path)) {
                    if ($wp_filesystem->move($current_thumb_path, $thumb_original_path)) {
                        $restored_thumbnails[$size_name] = $thumb_original_path;
                        // Debug: Restored thumbnail
                    }
                }
            }
            
            // Then search for any other thumbnail sizes that might not be in the metadata
            // Common WordPress thumbnail pattern is: filename-WIDTHxHEIGHT.ext
            $dir_handle = opendir($file_dir);
            if ($dir_handle) {
                $pattern = '/^' . preg_quote($current_base, '/') . '-\d+x\d+\.[a-zA-Z0-9]+$/';
                
                while (($file_in_dir = readdir($dir_handle)) !== false) {
                    // Skip . and .. directories
                    if ($file_in_dir == '.' || $file_in_dir == '..') {
                        continue;
                    }
                    
                    // Check if this is a thumbnail file for our image
                    if (preg_match($pattern, $file_in_dir)) {
                        $current_thumb_path = $file_dir . '/' . $file_in_dir;
                        
                        // Only continue if this thumbnail wasn't already renamed above
                        if (!in_array($current_thumb_path, $current_thumbnails)) {
                            // Create new thumbnail filename
                            $thumb_original_filename = str_replace($current_base, $original_base, $file_in_dir);
                            $thumb_original_path = $file_dir . '/' . $thumb_original_filename;
                            
                            // Rename the thumbnail
                            if ($wp_filesystem->move($current_thumb_path, $thumb_original_path)) {
                                $restored_thumbnails['extra_' . count($restored_thumbnails)] = $thumb_original_path;
                                // Debug: Restored additional thumbnail
                            }
                        }
                    }
                }
                
                closedir($dir_handle);
            }
            
            // Generate metadata for the attachment
            $metadata = wp_generate_attachment_metadata($attachment_id, $original_path);
            
            // Update the database to use the new metadata
            wp_update_attachment_metadata($attachment_id, $metadata);
            
            // Update post guid if needed
            $guid = get_the_guid($attachment_id);
            if (strpos($guid, $current_filename) !== false) {
                $new_guid = str_replace($current_filename, $original_filename, $guid);
                $wpdb->update(
                    $wpdb->posts,
                    array('guid' => $new_guid),
                    array('ID' => $attachment_id)
                );
            }
            
            // Get old and new attachment URLs for reference updates (restore operation)
            $old_url_base = $current_attachment_url; // URL before restore (saved earlier)  
            $new_url = wp_get_attachment_url($attachment_id); // URL after restore (updated)
            
            // Prepara array di vecchi e nuovi URL per gli aggiornamenti
            $old_urls = array($old_url_base);
            $new_urls = array($new_url);
            
            // Raccogli URL di miniature per gli aggiornamenti
            if (!empty($old_metadata['sizes'])) {
                foreach ($old_metadata['sizes'] as $size => $size_info) {
                    $current_size_file = $size_info['file'];
                    $current_size_url = str_replace(basename($old_url_base), $current_size_file, $old_url_base);
                    $old_urls[] = $current_size_url;
                    
                    // Calcola l'URL originale corrispondente
                    $original_size_file = str_replace($current_base, $original_base, $current_size_file);
                    $original_size_url = str_replace(basename($new_url), $original_size_file, $new_url);
                    $new_urls[] = $original_size_url;
                }
            }
            
            // Update URLs in post content
            $this->update_image_references($current_base, $original_base, dirname($old_url_base), dirname($new_url));
            
            // Aggiorna riferimenti nei page builder usando l'Integration Manager SOLO se necessario
            $integration_results = array();
            $enable_integrations = get_option('imgseo_renamer_enable_integrations', 1);
            
            if ($enable_integrations && !defined('IMGSEO_DISABLE_INTEGRATIONS')) {
                // Carica l'integration manager solo se effettivamente necessario
                if (!$this->integration_manager && class_exists('Renamer_Integration_Manager')) {
                    $this->integration_manager = Renamer_Integration_Manager::get_instance();
                }
                
                if ($this->integration_manager) {
                    $integration_results = $this->integration_manager->update_all_references($old_urls, $new_urls, $attachment_id);
                }
            }
            
            // Add a short delay to let WordPress process the file changes
            usleep(300000); // 0.3 secondi invece di 1 secondo
            
            // Force refresh post caches
            $this->force_refresh_content_caches();
            
            // Update _wp_attached_file again to ensure it's correctly set
            update_post_meta($attachment_id, '_wp_attached_file', str_replace(trailingslashit($upload_dir['basedir']), '', $original_path));
            
            // Log the successful operation
            $this->logs_manager->log_rename_operation($attachment_id, $current_filename, $original_filename, 'restore');
            
            // Commit the transaction
            $wpdb->query('COMMIT');
            
            return array(
                'old_filename' => $current_filename,
                'new_filename' => $original_filename,
                'new_url' => $new_url,
                'thumbnails_restored' => count($restored_thumbnails),
                'integration_results' => $integration_results
            );
            
        } catch (Exception $e) {
            // Rollback the transaction
            $wpdb->query('ROLLBACK');
            
            // Log the error
            $this->logs_manager->log_rename_operation($attachment_id, $current_filename, $original_filename, 'error');
            
            return new WP_Error('exception', $e->getMessage());
        }
    }

    /**
     * Update image references in post content and metadata
     * 
     * @param string $old_base Old filename base (without extension)
     * @param string $new_base New filename base (without extension)
     * @param string $old_url_base Old URL base (directory part)
     * @param string $new_url_base New URL base (directory part)
     */
    private function update_image_references($old_base, $new_base, $old_url_base, $new_url_base) {
        global $wpdb;
        
        // Update image references in post content
        
        // Make absolutely sure we have trailing slashes for path components
        $old_url_base = rtrim($old_url_base, '/');
        $new_url_base = rtrim($new_url_base, '/');
        
        // First, get ALL posts that could possibly contain images
        // This is more aggressive than before, but ensures we catch everything
        // Build targeted query for posts likely containing the old image reference
        $uploads = wp_get_upload_dir();
        $uploads_baseurl = isset($uploads['baseurl']) ? $uploads['baseurl'] : '';
        $uploads_basepath = $uploads_baseurl ? wp_parse_url($uploads_baseurl, PHP_URL_PATH) : '';
        if (empty($uploads_basepath)) { $uploads_basepath = '/wp-content/uploads'; }
        
        $like_abs = '%' . $wpdb->esc_like(rtrim($old_url_base, '/') . '/' . $old_base) . '%';
        $like_rel = '%' . $wpdb->esc_like(rtrim($uploads_basepath, '/') . '/' . $old_base) . '%';
        $like_name = '%' . $wpdb->esc_like($old_base) . '%';
        
        $posts = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT ID, post_content FROM {$wpdb->posts}
                 WHERE post_type NOT IN ('revision','nav_menu_item')
                   AND post_status NOT IN ('auto-draft')
                   AND (post_content LIKE %s OR post_content LIKE %s OR post_content LIKE %s)",
                $like_abs, $like_rel, $like_name
            )
        );
     
         // Process posts that may contain image references
         
         // Direct replacement of URLs with old base
         $old_url_pattern = $old_url_base . '/' . $old_base;
         $new_url_pattern = $new_url_base . '/' . $new_base;
                 
         $posts_updated = 0;
         foreach ($posts as $post) {
             $original_content = $post->post_content;
             $updated_content = $original_content;
             $content_changed = false;
             
             // Check if this post contains any of our old URLs
             $contains_old_url = false;
             $old_url_pattern = $old_url_base . '/' . $old_base;
             if (strpos($original_content, $old_url_pattern) !== false) {
                 $contains_old_url = true;
             }
             
             // 1. Replace all occurrences of the old base filename with the new one
             // This handles both main files and thumbnails in a more robust way
             $old_pattern = preg_quote($old_url_base . '/' . $old_base, '/');
             $new_replacement = $new_url_base . '/' . $new_base;
             
             // Pattern to match the old filename with any extension or thumbnail suffix
             $pattern = '/' . $old_pattern . '((?:-\d+x\d+)?\.\w+)/';
             
             if (preg_match_all($pattern, $updated_content, $matches, PREG_SET_ORDER)) {
                 foreach ($matches as $match) {
                     $old_full_url = $match[0];
                     $suffix = $match[1]; // This includes thumbnail dimensions and extension
                     $new_full_url = $new_replacement . $suffix;
                     
                     $updated_content = str_replace($old_full_url, $new_full_url, $updated_content);
                     $content_changed = true;
                 }
             }
             
             // 2. Additional fallback: direct string replacement for any remaining occurrences
             $simple_old = $old_url_base . '/' . $old_base;
             $simple_new = $new_url_base . '/' . $new_base;
             if (strpos($updated_content, $simple_old) !== false) {
                 $updated_content = str_replace($simple_old, $simple_new, $updated_content);
                 $content_changed = true;
             }

            // 2b. Generic, domain-agnostic replacement that also handles relative/protocol-relative URLs
            // Preserve the existing directory in the URL/path and only swap the filename base
            $uploads_path_quoted = preg_quote(rtrim($uploads_basepath, '/'), '/');
            $generic_pattern = '/((?:https?:)?//[^"\')\s]+)?(' . $uploads_path_quoted . '\/[^"\')\s]+\/)' . preg_quote($old_base, '/') . '((?:-\d+x\d+)?\.\w+)/i';
            $generic_replacement = '$1$2' . $new_base . '$3';
            $updated_tmp = preg_replace($generic_pattern, $generic_replacement, $updated_content, -1, $generic_count);
            if ($updated_tmp !== null && $generic_count > 0) {
                $updated_content = $updated_tmp;
                $content_changed = true;
            }
             
             // 3. Replace srcset attributes which may contain multiple thumbnail URLs
             $srcset_pattern = '/srcset="([^"]*' . preg_quote($old_url_base . '/' . $old_base, '/') . '[^"]*)"/';
             if (preg_match_all($srcset_pattern, $updated_content, $srcset_matches, PREG_SET_ORDER)) {
                 foreach ($srcset_matches as $srcset_match) {
                     $old_srcset = $srcset_match[0];
                     $srcset_content = $srcset_match[1];
                     $new_srcset_content = str_replace(
                         $old_url_base . '/' . $old_base, 
                         $new_url_base . '/' . $new_base,
                         $srcset_content
                     );
                     $new_srcset = 'srcset="' . $new_srcset_content . '"';
                     
                     $updated_content = str_replace($old_srcset, $new_srcset, $updated_content);
                     $content_changed = true;
                 }
             }
 
             // 4. Replace data-* attributes which may contain image URLs
             $data_pattern = '/data-(?:large|medium|thumb|small|orig|src|image)="([^"]*' . preg_quote($old_url_base . '/' . $old_base, '/') . '[^"]*)"/i';
             if (preg_match_all($data_pattern, $updated_content, $data_matches, PREG_SET_ORDER)) {
                 foreach ($data_matches as $data_match) {
                     $old_data = $data_match[0];
                     $data_content = $data_match[1];
                     $new_data_content = str_replace(
                         $old_url_base . '/' . $old_base, 
                         $new_url_base . '/' . $new_base,
                         $data_content
                     );
                     $new_data = str_replace($data_content, $new_data_content, $old_data);
                     
                     $updated_content = str_replace($old_data, $new_data, $updated_content);
                     $content_changed = true;
                 }
             }
 
             // Update the post if content has changed
             if ($content_changed) {
                 $wpdb->update(
                     $wpdb->posts,
                     array('post_content' => $updated_content),
                     array('ID' => $post->ID)
                 );
                 $posts_updated++;
                 
                 // Clear any post cache
                 clean_post_cache($post->ID);
             }
         }
 
         // Posts updated: $posts_updated (removed verbose logging)
 
         // Update postmeta (for galleries, featured images, etc.)
         $meta_items = $wpdb->get_results(
             $wpdb->prepare(
                 "SELECT meta_id, post_id, meta_key, meta_value FROM {$wpdb->postmeta} 
                 WHERE meta_value LIKE %s OR meta_value LIKE %s",
                 '%' . $wpdb->esc_like($old_url_base) . '%',
                 '%' . $wpdb->esc_like($old_base) . '%'
             )
         );
         
         foreach ($meta_items as $meta) {
             $updated_value = $meta->meta_value;
             $value_changed = false;
             
             // Handle serialized data
             if (is_serialized($meta->meta_value)) {
                 // Unserialize, modify, and reserialize
                 $unserialized = @unserialize($meta->meta_value);
                 if ($unserialized !== false) {
                     // Convert to JSON and back to handle nested structures
                     $json = json_encode($unserialized);
                     if ($json !== false) {
                         // Replace in JSON string
                         $old_patterns = array(
                             $old_url_base . '/' . $old_base . '.',
                             '"' . $old_url_base . '/' . $old_base . '-',
                             '{' . $old_url_base . '/' . $old_base . '-',
                             '[' . $old_url_base . '/' . $old_base . '-',
                             ' ' . $old_url_base . '/' . $old_base . '-'
                         );
                         
                         $new_patterns = array(
                             $new_url_base . '/' . $new_base . '.',
                             '"' . $new_url_base . '/' . $new_base . '-',
                             '{' . $new_url_base . '/' . $new_base . '-',
                             '[' . $new_url_base . '/' . $new_base . '-',
                             ' ' . $new_url_base . '/' . $new_base . '-'
                         );
                         
                         $json_new = str_replace($old_patterns, $new_patterns, $json);

                        // Generic fallback (domain-agnostic) inside JSON string
                        $uploads_path_quoted = preg_quote(rtrim($uploads_basepath, '/'), '/');
                        $generic_pattern = '/((?:https?:)?\/\/[^"\'\)\s]+)?(' . $uploads_path_quoted . '\/[^"\'\)\s]+\/)' . preg_quote($old_base, '/') . '((?:-\d+x\d+)?\.\w+)/i';
                        $json_fallback = preg_replace($generic_pattern, '$1$2' . $new_base . '$3', $json_new, -1, $json_count);
                        if ($json_fallback !== null && $json_count > 0) {
                            $json_new = $json_fallback;
                        }
                         
                         if ($json_new !== $json) {
                             $value_changed = true;
                             // Convert back to PHP array
                             $modified = json_decode($json_new, true);
                             if (json_last_error() === JSON_ERROR_NONE) {
                                 // Reserialize
                                 $updated_value = serialize($modified);
                             }
                         }
                     }
                 }
             } 
             // Handle JSON data
             else if (($meta->meta_value[0] === '{' && substr($meta->meta_value, -1) === '}') || 
                     ($meta->meta_value[0] === '[' && substr($meta->meta_value, -1) === ']')) {
                 
                 // Replace in JSON string
                 $json = $meta->meta_value;
                 $old_patterns = array(
                     $old_url_base . '/' . $old_base . '.',
                     '"' . $old_url_base . '/' . $old_base . '-',
                     ' ' . $old_url_base . '/' . $old_base . '-'
                 );
                 
                 $new_patterns = array(
                     $new_url_base . '/' . $new_base . '.',
                     '"' . $new_url_base . '/' . $new_base . '-',
                     ' ' . $new_url_base . '/' . $new_base . '-'
                 );
                 
                 $json_new = str_replace($old_patterns, $new_patterns, $json);

                // Generic fallback (domain-agnostic) inside JSON string
                $uploads_path_quoted = preg_quote(rtrim($uploads_basepath, '/'), '/');
                $generic_pattern = '/((?:https?:)?\/\/[^"\'\)\s]+)?(' . $uploads_path_quoted . '\/[^"\'\)\s]+\/)' . preg_quote($old_base, '/') . '((?:-\d+x\d+)?\.\w+)/i';
                $json_fallback = preg_replace($generic_pattern, '$1$2' . $new_base . '$3', $json_new, -1, $json_count);
                if ($json_fallback !== null && $json_count > 0) {
                    $json_new = $json_fallback;
                }
                 
                 if ($json_new !== $json) {
                     $updated_value = $json_new;
                     $value_changed = true;
                 }
             }
             // Handle regular string metadata
             else {
                 // Direct replacement for full URLs
                 if (strpos($meta->meta_value, $old_url_base . '/' . $old_base) !== false) {
                     $updated_value = str_replace(
                         $old_url_base . '/' . $old_base,
                         $new_url_base . '/' . $new_base,
                         $meta->meta_value
                     );
                     $value_changed = true;
                 }
             }

            // Generic fallback for any remaining meta values (domain-agnostic, relative/absolute)
            if (!$value_changed && is_string($updated_value)) {
                $uploads_path_quoted = preg_quote(rtrim($uploads_basepath, '/'), '/');
                $generic_pattern = '/((?:https?:)?\/\/[^"\'\)\s]+)?(' . $uploads_path_quoted . '\/[^"\'\)\s]+\/)' . preg_quote($old_base, '/') . '((?:-\d+x\d+)?\.\w+)/i';
                $meta_tmp = preg_replace($generic_pattern, '$1$2' . $new_base . '$3', $updated_value, -1, $meta_count);
                if ($meta_tmp !== null && $meta_count > 0) {
                    $updated_value = $meta_tmp;
                    $value_changed = true;
                }
            }
             
             // Update the meta if it has changed
             if ($value_changed && $updated_value !== $meta->meta_value) {
                 $wpdb->update(
                     $wpdb->postmeta,
                     array('meta_value' => $updated_value),
                     array('meta_id' => $meta->meta_id)
                 );
             }
         }
         
         // Clear any caches that might be holding old URLs
         if (function_exists('wp_cache_flush')) {
             wp_cache_flush();
         }
     }
    
    /**
     * Force refresh all content caches
     * This addresses persistent reference issues after renaming
     */
    private function force_refresh_content_caches() {
        global $wpdb;
        
        // Refresh post caches
        $posts_with_images = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%<img%' OR post_content LIKE '%wp-image-%' LIMIT 100");
        
        if (!empty($posts_with_images)) {
            foreach ($posts_with_images as $post_id) {
                clean_post_cache($post_id);
            }
        }
        
        // Flush object cache per specifiche chiavi, non tutto
        if (function_exists('wp_cache_delete_many')) {
            $keys = array('posts', 'post_meta');
            wp_cache_delete_many($keys);
        }
    }
}


