<?php
/**
 * Plugin Uninstaller
 *
 * Handles complete plugin removal for both single-site and multisite installations.
 * Removes all options, transients, scheduled events, cache files, media optimizations,
 * and database entries created by the plugin.
 *
 * @package Mamba\Lifecycle
 * @since   1.0.0
 */

namespace Mamba\Lifecycle;

/**
 * Class Uninstaller
 *
 * Manages complete plugin uninstallation including cleanup of all plugin data,
 * cache directories, media optimization files, and scheduled tasks.
 *
 * @since 1.0.0
 */
final class Uninstaller {
    
    /**
     * Main uninstall entry point
     * Handles both single-site and network-wide uninstall
     * 
     * Note: register_uninstall_hook doesn't pass $network_wide, so we detect it
     * by checking if the plugin is network-activated
     */
    public static function run(): void {
        // Detect if this is a network-wide uninstall
        // Plugin is network-activated if it's in the network-active plugins list
        if (is_multisite() && self::isNetworkActivated()) {
            self::uninstallNetworkWide();
        } else {
            self::uninstallSingleSite();
        }
        
        // Always clean up the shared cache directory (contains all sites' caches)
        self::cleanupCacheDirectory();
    }
    
    /**
     * Check if plugin is network-activated
     */
    private static function isNetworkActivated(): bool {
        if (!is_multisite()) {
            return false;
        }
        
        $networkPlugins = get_site_option('active_sitewide_plugins', []);
        
        // Check for both possible plugin file names
        foreach ($networkPlugins as $plugin => $time) {
            if (strpos($plugin, 'mamba-woo-cache.php') !== false || strpos($plugin, 'mamba-caching') !== false) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Uninstall plugin from all sites in the network
     */
    private static function uninstallNetworkWide(): void {
        $sites = get_sites([
            'fields' => 'ids',
            'number' => 0,
        ]);
        
        foreach ($sites as $siteId) {
            switch_to_blog($siteId);
            self::uninstallSingleSite();
            restore_current_blog();
        }
    }
    
    /**
     * Uninstall plugin from a single site
     * This contains all the original uninstall logic for options and data cleanup
     */
    public static function uninstallSingleSite(): void {
        // Licensing cleanup
        $existingKey = get_option('mamba_license_key');
        // Clear scheduled events related to licensing
        wp_clear_scheduled_hook('mamba_license_daily_validation');
        // Clear background validation lock
        delete_transient('mamba_license_check_lock');
        // Clear cached validation transient if we can compute the key
        if (!empty($existingKey)) {
            delete_transient('mamba_license_cache_' . md5($existingKey . 'mamba-woo-cache'));
        }
        // Remove license options
        delete_option('mamba_license_key');
        delete_option('mamba_license_status');
        delete_option('mamba_license_last_ok');
        delete_option('mamba_license_server_url');
        
        // Remove Cache options
        delete_option('mamba_enable_page_cache');
        delete_option('mamba_enable_store_api_cache');
        delete_option('mamba_cache_ttl');
        delete_option('mamba_browser_ttl');
        delete_option('mamba_store_api_browser_ttl');
        delete_option('mamba_store_api_ttl');
        delete_option('mamba_cache_size_limit');
        delete_option('mamba_cdn_ttl');
        delete_option('mamba_stale_if_error');
        // Additional cache/settings options
        delete_option('mamba_auto_setup_done');
        delete_option('mamba_preload_concurrency');
        delete_option('mamba_warmup_batch_size');
        delete_option('mamba_include_accept_language_vary');
        delete_option('mamba_last_sale_event_check');
        delete_option('mamba_stats_last_write');
        delete_option('mamba_enable_priority_warmup');
        delete_option('mamba_cache_last_cleanup');
        delete_option('mamba_do_activation_redirect');
        // Object cache namespace flags
        delete_option('mamba_ns_mamba_store_api');
        delete_option('mamba_ns_mamba_tags');
        delete_option('mamba_ns_mamba_stats');
        delete_option('mamba_ns_mamba_cart_fragments');
        // Rare/legacy flags if present
        delete_option('mamba_hourly_stats');
        delete_option('mamba_stats_last_hourly');
        delete_option('mamba_pretty_permalinks_done');
        delete_option('mamba_cdn_actions');
        delete_option('mamba_cdn_autoload_migrated');
        delete_option('mamba_cache_stats');
        delete_option('mamba_daily_stats');
        delete_option('mamba_warmup_stats');
        delete_option('mamba_warmup_errors');
        delete_option('mamba_admin_notifications');
        
        // Welcome screen and first-run options
        delete_option('mamba_welcome_shown');
        delete_option('mamba_first_visit_done');
        delete_transient('mamba_activation_redirect');
        
        // Logging options
        delete_option('mamba_debug_mode');
        delete_option('mamba_enable_logging');
        delete_option('mamba_log_level');
        delete_option('mamba_log_retention_days');
        
        // Remove savings stats
        delete_option('mamba_savings_stats');
        
        // Remove media optimization options
        delete_option('mamba_enable_webp_conversion');
        delete_option('mamba_webp_quality');
        delete_option('mamba_convert_full_size');
        delete_option('mamba_enable_image_compression');
        delete_option('mamba_compression_quality');
        delete_option('mamba_compression_type');
        delete_option('mamba_compress_full_size');
        delete_option('mamba_enable_lcp_optimization');
        delete_option('mamba_enable_avif_conversion');
        delete_option('mamba_avif_quality');
        delete_option('mamba_convert_full_size_avif');
        delete_option('mamba_add_image_dimensions');
        
        // Remove overhead optimization options
        delete_option('mamba_disable_wc_assets_on_non_wc');
        delete_option('mamba_disable_order_splitter_async');
        delete_option('mamba_simplify_price_html');
        delete_option('mamba_enable_hover_prefetch');
        delete_option('mamba_optimize_checkout_js');
        delete_option('mamba_optimize_checkout_css');
        delete_option('mamba_disable_checkout_fragments');
        delete_option('mamba_lazy_load_payments');
        delete_option('mamba_defer_transactional_emails');
        delete_option('mamba_preconnect_payment_sdks');
        delete_option('mamba_disable_woo_marketplace_suggestions');
        delete_option('mamba_suppress_woo_helper_notices');
        delete_option('mamba_disable_woo_payment_gateway_suggestions');
        delete_option('mamba_remove_woo_submenus');
        delete_option('mamba_disable_order_attribution');
        // HTML minification options
        delete_option('mamba_enable_html_minify');
        delete_option('mamba_html_minify_mode');
        // Font preloading options
        delete_option('mamba_enable_font_preload');
        delete_option('mamba_preload_fonts');
        // DNS prefetch options
        delete_option('mamba_enable_dns_prefetch');
        delete_option('mamba_dns_prefetch_domains');
        delete_option('mamba_dns_prefetch_auto_detect');
        // Preconnect options
        delete_option('mamba_enable_preconnect');
        delete_option('mamba_preconnect_domains');
        // Heartbeat control options
        delete_option('mamba_heartbeat_frontend');
        delete_option('mamba_heartbeat_admin');
        delete_option('mamba_heartbeat_editor');
        // Adaptive TTL option
        delete_option('mamba_enable_adaptive_ttl');
        
        // Critical CSS options
        delete_option('mamba_enable_critical_css');
        delete_option('mamba_enable_css_defer');
        delete_option('mamba_css_defer_all');
        delete_option('mamba_critical_css_force_include');
        // Critical CSS custom CSS per page type
        delete_option('mamba_critical_css_custom_product');
        delete_option('mamba_critical_css_custom_shop');
        delete_option('mamba_critical_css_custom_category');
        delete_option('mamba_critical_css_custom_cart');
        delete_option('mamba_critical_css_custom_checkout');
        delete_option('mamba_critical_css_custom_account');
        delete_option('mamba_critical_css_custom_generic');
        
        // JavaScript Delay options
        delete_option('mamba_enable_js_delay');
        delete_option('mamba_js_delay_timeout');
        delete_option('mamba_js_delay_scripts');
        delete_option('mamba_js_delay_exclusions');
        
        // Advanced Warmup options (Premium)
        delete_option('mamba_warmup_priority_mode');
        delete_option('mamba_warmup_selective_mode');
        delete_option('mamba_warmup_schedule_enabled');
        delete_option('mamba_warmup_schedule_time');
        delete_option('mamba_warmup_selected_categories');
        delete_option('mamba_warmup_selected_products');
        delete_option('mamba_warmup_exclusions');
        
        // Remove CDN options
        delete_option('mamba_cdn_provider');
        delete_option('mamba_cloudflare_zone_id');
        delete_option('mamba_cloudflare_api_token');
        delete_option('mamba_cloudflare_detect_apo');
        delete_option('mamba_cloudflare_send_cache_tags');
        delete_option('mamba_cloudflare_apo_status');
        delete_option('mamba_cloudflare_rocket_loader_status');
        delete_option('mamba_bunny_pull_zone_id');
        delete_option('mamba_bunny_api_key');
        delete_option('mamba_bunny_send_cdn_tags');
        delete_option('mamba_bunny_use_wildcard_purges');
        delete_option('mamba_generic_webhook_url');
        delete_option('mamba_generic_webhook_secret');
        delete_option('mamba_fastly_service_id');
        delete_option('mamba_fastly_api_token');
        delete_option('mamba_fastly_send_surrogate_keys');
        delete_option('mamba_fastly_soft_purge');
        delete_option('mamba_cdn_enable_rewriting');
        delete_option('mamba_cdn_hostname');
        delete_option('mamba_cdn_dirs');
        delete_option('mamba_cdn_exclusions');
        delete_option('mamba_cdn_buffer_rewriting');
        
        // Remove DB optimizer options
        delete_option('mamba_db_optimizer_settings');
        
        // Clear scheduled events
        wp_clear_scheduled_hook('mamba_stats_flush');
        wp_clear_scheduled_hook('mamba_cache_cleanup');
        wp_clear_scheduled_hook('mamba_warmup_job');
        wp_clear_scheduled_hook('mamba_background_warmup');
        // Clear any remaining scheduled hooks registered during runtime
        wp_clear_scheduled_hook('mamba_cache_preload');
        wp_clear_scheduled_hook('mamba_priority_warmup');
        wp_clear_scheduled_hook('mamba_cache_size_check');
        wp_clear_scheduled_hook('mamba_check_sale_boundaries');
        wp_clear_scheduled_hook('mamba_scheduled_warmup');
        
        // Clear accumulated stats buffers
        if (class_exists('\Mamba\Modules\Caching\Services\StatsBuffer')) {
            \Mamba\Modules\Caching\Services\StatsBuffer::resetAccumulatedStats();
            \Mamba\Modules\Caching\Services\StatsBuffer::resetDailyAccumulatedStats();
        }
        
        // Clear DB optimizer scheduled events
        $optimizer = new \Mamba\Modules\DB\Services\DatabaseOptimizer();
        foreach ($optimizer->getTaskIds() as $taskId) {
            $hook = 'mamba_db_task_' . $taskId;
            wp_clear_scheduled_hook($hook, [$taskId]);
        }
        
        // Clean up background job options
        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'mamba_warmup_job_%'");
        
        // Proactively remove any license cache/microcache/scheduler transients with mamba_ prefix
        // Single-key locks
        delete_transient('mamba_warmup_lock');
        delete_transient('mamba_stats_flush_lock');
        delete_transient('mamba_cache_counts_cache');
        // Pattern removals (options table stores transients as _transient_* and _transient_timeout_*)
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_mamba_license_cache_%' OR option_name LIKE '_transient_timeout_mamba_license_cache_%'");
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_mamba_sched_%' OR option_name LIKE '_transient_timeout_mamba_sched_%'");
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_mamba_mc_ver_%' OR option_name LIKE '_transient_timeout_mamba_mc_ver_%'");
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_%mamba_stats%' OR option_name LIKE '_transient_timeout_%mamba_stats%'");
        
        // Remove WebP rules from .htaccess
        $htaccessManager = new \Mamba\Modules\Media\Services\HtaccessManager();
        $htaccessManager->removeWebPRules();
        
        // Clean up post meta (optimization data)
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->query("DELETE FROM {$wpdb->postmeta} WHERE meta_key IN ('_mamba_compression_quality', '_mamba_webp_conversion', '_mamba_avif_conversion', '_mamba_last_significant_change')");
        
        // Media Cleanup - Remove all optimized files and backups
        self::cleanupMediaFiles();
    }
    
    /**
     * Clean up the shared cache directory
     * Called once after all sites are cleaned up
     */
    private static function cleanupCacheDirectory(): void {
        if (defined('WP_CONTENT_DIR')) {
            // Clean up cache directory
            $cacheDir = WP_CONTENT_DIR . '/cache/mamba';
            if (is_dir($cacheDir)) {
                $it = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($cacheDir, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST);
                foreach ($it as $fi) { $todo = $fi->isDir() ? 'rmdir' : 'unlink'; @$todo($fi->getRealPath()); }
                @rmdir($cacheDir);
            }
            
            // Clean up logs directory
            $logsDir = WP_CONTENT_DIR . '/mamba-logs';
            if (is_dir($logsDir)) {
                $it = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($logsDir, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST);
                foreach ($it as $fi) { $todo = $fi->isDir() ? 'rmdir' : 'unlink'; @$todo($fi->getRealPath()); }
                @rmdir($logsDir);
            }
        }
    }
    
    /**
     * Clean up all media optimization files and backups
     */
    private static function cleanupMediaFiles(): void {
        global $wpdb;
        
        // Get all attachments that have optimization metadata
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $optimizedAttachments = $wpdb->get_results("
            SELECT DISTINCT post_id 
            FROM {$wpdb->postmeta} 
            WHERE meta_key IN ('_mamba_compression_quality', '_mamba_webp_conversion', '_mamba_avif_conversion')
        ");
        
        // Log the cleanup for transparency
        $webpCount = 0;
        $compressionCount = 0;
        
        foreach ($optimizedAttachments as $attachment) {
            $attachmentId = (int) $attachment->post_id;
            
            // Count what we're cleaning up
            $webpData = get_post_meta($attachmentId, '_mamba_webp_conversion', true);
            $compressionData = get_post_meta($attachmentId, '_mamba_compression_quality', true);
            $avifData = get_post_meta($attachmentId, '_mamba_avif_conversion', true);
            
            if (!empty($webpData)) $webpCount++;
            if (!empty($compressionData)) $compressionCount++;
            
            // Clean up WebP and AVIF files
            self::cleanupNextGenFiles($attachmentId);
            
            // Clean up compression backups
            self::cleanupCompressionBackups($attachmentId);
        }
        
        // Log the cleanup operation
        if ($webpCount > 0 || $compressionCount > 0) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log("Mamba Uninstall: Cleaned up {$webpCount} WebP conversions and {$compressionCount} compression optimizations");
            }
        }
        
        // Clean up any orphaned optimization directories
        self::cleanupOptimizationDirectories();
    }
    
    /**
     * Remove WebP and AVIF files for an attachment
     */
    private static function cleanupNextGenFiles(int $attachmentId): void {
        $uploadDir = wp_upload_dir();
        $baseDir = $uploadDir['basedir'];
        
        // Get attachment metadata to find all file paths
        $metadata = wp_get_attachment_metadata($attachmentId);
        if (!$metadata) {
            return;
        }
        
        // Remove WebP and AVIF files for all sizes
        foreach ($metadata['sizes'] ?? [] as $sizeName => $sizeData) {
            $filePath = $baseDir . '/' . $sizeData['file'];
            $webpPath = $filePath . '.webp';
            $avifPath = $filePath . '.avif';
            
            if (file_exists($webpPath)) {
                @unlink($webpPath);
            }
            if (file_exists($avifPath)) {
                @unlink($avifPath);
            }
        }
        
        // Remove WebP and AVIF for full size
        $filePath = get_attached_file($attachmentId);
        if ($filePath) {
            $webpPath = $filePath . '.webp';
            $avifPath = $filePath . '.avif';
            if (file_exists($webpPath)) {
                @unlink($webpPath);
            }
            if (file_exists($avifPath)) {
                @unlink($avifPath);
            }
        }
    }
    
    /**
     * Remove compression backup files for an attachment
     */
    private static function cleanupCompressionBackups(int $attachmentId): void {
        $compressionData = get_post_meta($attachmentId, '_mamba_compression_quality', true);
        if (empty($compressionData) || !is_array($compressionData)) {
            return;
        }
        
        // Remove backup files
        foreach ($compressionData as $sizeName => $data) {
            $backupPath = $data['backup_path'] ?? '';
            if ($backupPath && file_exists($backupPath)) {
                @unlink($backupPath);
            }
        }
        
        // Try to remove backup directory if empty
        if (!empty($compressionData)) {
            $firstBackup = reset($compressionData);
            $backupPath = $firstBackup['backup_path'] ?? '';
            if ($backupPath) {
                $backupDir = dirname($backupPath);
                if (is_dir($backupDir)) {
                    $remainingFiles = glob($backupDir . '/*');
                    if (empty($remainingFiles)) {
                        @rmdir($backupDir);
                    }
                }
            }
        }
    }
    
    /**
     * Clean up any orphaned optimization directories
     */
    private static function cleanupOptimizationDirectories(): void {
        $uploadDir = wp_upload_dir();
        $baseDir = $uploadDir['basedir'];
        
        // Look for common backup directory patterns
        $backupPatterns = [
            $baseDir . '/mamba-backups',
            $baseDir . '/mamba-optimization-backups',
            $baseDir . '/mamba-compression-backups'
        ];
        
        foreach ($backupPatterns as $backupDir) {
            if (is_dir($backupDir)) {
                $files = glob($backupDir . '/*');
                if (empty($files)) {
                    @rmdir($backupDir);
                }
            }
        }
    }
}
