<?php
/**
 * Classe principal de otimização do Upgram
 * 
 * Gerencia todas as otimizações de performance:
 * - Minificação e combinação de CSS/JS
 * - Compressão de HTML
 * - Cache de objetos
 * - Cache do navegador
 * - Cache móvel
 * - Bloqueio de CSS/JS não utilizado
 * - Lazy loading de imagens
 * - Integração com Cloudflare
 * - Bloqueio de render blocking requests
 */

if (!defined('ABSPATH')) {
    exit;
}

class Upgram_Optimizer {
    
    private static $instance = null;
    private $cache_dir;
    private $cache_url;
    private $query_start_time = 0;
    private $query_count = 0;
    private $slow_queries = array();
    
    /**
     * Singleton instance
     */
    public static function get_instance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Constructor
     */
    private function __construct() {
        $upload_dir = wp_upload_dir();
        $this->cache_dir = $upload_dir['basedir'] . '/upgram-cache';
        $this->cache_url = $upload_dir['baseurl'] . '/upgram-cache';
        
        // Criar diretório de cache se não existir
        if (!file_exists($this->cache_dir)) {
            wp_mkdir_p($this->cache_dir);
            // Criar .htaccess para proteger o diretório
            $this->create_cache_protection();
        }
        
        $this->init_hooks();
    }
    
    /**
     * Inicializar hooks
     */
    private function init_hooks() {
        // HTML Compression
        if (get_option('upgram_optimizer_html_compress', false)) {
            add_action('template_redirect', array($this, 'start_html_compression'), 1);
        }
        
        // CSS Optimization
        if (get_option('upgram_optimizer_css_enable', false)) {
            add_action('wp_enqueue_scripts', array($this, 'optimize_css'), 999);
        }
        
        // JS Optimization
        if (get_option('upgram_optimizer_js_enable', false)) {
            add_action('wp_enqueue_scripts', array($this, 'optimize_js'), 999);
        }
        
        // Block unused CSS/JS
        add_action('wp_head', array($this, 'block_unused_resources'), 1);
        add_action('wp_footer', array($this, 'block_unused_resources'), 1);
        
        // Block render blocking requests
        if (get_option('upgram_optimizer_block_render_blocking', false)) {
            add_action('wp_enqueue_scripts', array($this, 'defer_render_blocking_scripts'), 999);
            add_action('wp_head', array($this, 'add_render_blocking_fix'), 1);
        }
        
        // Defer/Async por handle
        add_filter('script_loader_tag', array($this, 'apply_defer_async_by_handle'), 10, 3);
        
        // Delay JS até interação do usuário
        if (get_option('upgram_optimizer_delay_js_enable', false)) {
            add_action('wp_footer', array($this, 'inject_delay_js_loader'), 999);
            add_filter('script_loader_tag', array($this, 'delay_js_scripts'), 10, 3);
        }
        
        // Asset Manager - Desativar scripts/CSS por página
        add_action('wp_enqueue_scripts', array($this, 'disable_assets_by_rules'), 999);
        
        // INP Monitor
        if (get_option('upgram_optimizer_inp_monitor_enable', false)) {
            add_action('wp_footer', array($this, 'inject_inp_monitor'), 999);
        }
        
        // Desativar emojis (pode ser chamado cedo)
        if (get_option('upgram_optimizer_disable_emojis', true)) {
            $this->disable_emojis();
        }
        
        // Desativar embeds (deve ser no hook correto)
        if (get_option('upgram_optimizer_disable_embeds', true)) {
            // Remover hooks relacionados a embeds cedo (no init)
            add_action('init', array($this, 'disable_embeds_early'), 1);
            // Remover script wp-embed no hook correto
            add_action('wp_enqueue_scripts', array($this, 'disable_embeds_script'), 1);
        }
        
        // Controle de Heartbeat (deve ser no hook correto)
        if (get_option('upgram_optimizer_heartbeat_control', false)) {
            add_action('wp_enqueue_scripts', array($this, 'control_heartbeat_frontend'), 999);
            add_action('admin_enqueue_scripts', array($this, 'control_heartbeat_admin'), 999);
            add_filter('heartbeat_settings', array($this, 'control_heartbeat_frequency'), 10, 1);
        }
        
        // Remover CSS de blocos se não usa Gutenberg
        if (get_option('upgram_optimizer_remove_block_css', false) && !$this->uses_gutenberg()) {
            add_action('wp_enqueue_scripts', array($this, 'remove_block_css'), 999);
        }
        
        // Cache de objetos
        if (get_option('upgram_optimizer_object_cache_enable', false)) {
            $this->init_object_cache();
        }
        
        // Browser Cache Headers
        if (get_option('upgram_optimizer_browser_cache_enable', false)) {
            add_action('template_redirect', array($this, 'set_browser_cache_headers'), 1);
        }
        
        // Mobile Cache
        if (get_option('upgram_optimizer_mobile_cache_enable', false)) {
            add_action('template_redirect', array($this, 'set_mobile_cache_headers'), 1);
        }
        
        // Lazy Loading Images
        if (get_option('upgram_optimizer_lazy_load_images', true)) {
            add_filter('wp_get_attachment_image_attributes', array($this, 'add_lazy_loading'), 10, 3);
            add_filter('the_content', array($this, 'add_lazy_loading_to_content'), 99);
            add_filter('wp_lazy_loading_enabled', '__return_true', 10);
            add_filter('wp_img_tag_add_loading_attr', array($this, 'add_loading_attr_to_img'), 10, 2);
            // Hook para capturar output antes de enviar
            add_action('template_redirect', array($this, 'start_lazy_load_buffer'), 2);
        }
        
        // Cloudflare Integration
        if (get_option('upgram_optimizer_cloudflare_enable', false)) {
            add_action('template_redirect', array($this, 'set_cloudflare_headers'), 1);
        }
        
        // Full Page Cache Mobile/Desktop
        if (get_option('upgram_optimizer_full_page_cache_enable', false)) {
            add_action('template_redirect', array($this, 'init_full_page_cache'), 1);
        }
        
        // Mobile: Desativar assets por dispositivo
        if (get_option('upgram_optimizer_mobile_disable_assets_enable', false)) {
            add_action('wp_enqueue_scripts', array($this, 'disable_mobile_assets'), 999);
        }
        
        // Mobile: Delay JS extra
        if (get_option('upgram_optimizer_mobile_delay_js_enable', false)) {
            add_filter('script_loader_tag', array($this, 'delay_mobile_js'), 10, 3);
            add_action('wp_footer', array($this, 'inject_mobile_delay_js_loader'), 999);
        }
        
        // Mobile: Bloquear queries antes do carregamento
        // SEMPRE bloquear consultas no mobile para priorizar carregamento da página
        // Independente da configuração, no mobile sempre bloqueia
        if (function_exists('wp_is_mobile') && wp_is_mobile()) {
            add_action('init', array($this, 'block_mobile_queries_early'), 1);
        } elseif (get_option('upgram_optimizer_mobile_block_queries_enable', false)) {
            add_action('init', array($this, 'block_mobile_queries_early'), 1);
        }
        
        // Query Logger
        if (get_option('upgram_optimizer_query_log_enable', false)) {
            add_action('init', array($this, 'init_query_logger'), 1);
        }
        
        // Priorização de Renderização - Deferir recursos não críticos
        add_action('wp_enqueue_scripts', array($this, 'prioritize_renderization'), 999);
        
        // Melhorar Lazy Loading de Imagens
        if (get_option('upgram_optimizer_lazy_load_images', true)) {
            add_filter('wp_get_attachment_image_attributes', array($this, 'improve_lazy_loading_attributes'), 10, 3);
        }
        
    }
    
    /**
     * Criar proteção para diretório de cache
     */
    private function create_cache_protection() {
        $htaccess_content = "# Upgram Cache Protection\n";
        $htaccess_content .= "<IfModule mod_authz_core.c>\n";
        $htaccess_content .= "    Require all granted\n";
        $htaccess_content .= "</IfModule>\n";
        $htaccess_content .= "<IfModule !mod_authz_core.c>\n";
        $htaccess_content .= "    Order allow,deny\n";
        $htaccess_content .= "    Allow from all\n";
        $htaccess_content .= "</IfModule>\n";
        
        file_put_contents($this->cache_dir . '/.htaccess', $htaccess_content);
    }
    
    /**
     * Iniciar compressão de HTML
     */
    public function start_html_compression() {
        if (is_admin() || (defined('WP_CLI') && WP_CLI)) {
            return;
        }
        
        // Não comprimir se já foi iniciado
        if (ob_get_level() > 0) {
            return;
        }
        
        ob_start(array($this, 'compress_html'));
    }
    
    /**
     * Comprimir HTML
     */
    public function compress_html($html) {
        if (empty($html)) {
            return '';
        }
        
        // Remover comentários HTML (exceto condicionais)
        $html = preg_replace('/<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->/s', '', $html);
        
        // Remover espaços em branco desnecessários
        $html = preg_replace('/\s+/', ' ', $html);
        $html = preg_replace('/>\s+</', '><', $html);
        
        // Remover espaços antes de tags de fechamento
        $html = preg_replace('/\s+>/', '>', $html);
        $html = preg_replace('/>\s+/', '>', $html);
        
        return trim($html);
    }
    
    /**
     * Otimizar CSS
     */
    public function optimize_css() {
        global $wp_styles;
        
        if (empty($wp_styles->queue)) {
            return;
        }
        
        $minify = get_option('upgram_optimizer_css_minify', true);
        $combine = get_option('upgram_optimizer_css_combine', true);
        $async = get_option('upgram_optimizer_css_async', false);
        
        if (!$minify && !$combine && !$async) {
            return;
        }
        
        $css_files = array();
        $handles_to_remove = array();
        
        foreach ($wp_styles->queue as $handle) {
            $style = $wp_styles->registered[$handle];
            
            // Pular se for condicional ou inline
            if (isset($style->extra['conditional']) || !empty($style->extra['after'])) {
                continue;
            }
            
            // Pular se estiver na lista de bloqueio
            if ($this->is_resource_blocked($style->src, 'css')) {
                $handles_to_remove[] = $handle;
                continue;
            }
            
            if (!empty($style->src)) {
                $css_files[$handle] = $style;
                $handles_to_remove[] = $handle;
            }
        }
        
        if (empty($css_files)) {
            return;
        }
        
        // Remover estilos originais
        foreach ($handles_to_remove as $handle) {
            wp_dequeue_style($handle);
        }
        
        // Gerar arquivo combinado/minificado
        $cache_key = $this->generate_cache_key($css_files, 'css');
        $cache_file = $this->cache_dir . '/css/' . $cache_key . '.css';
        $cache_url = $this->cache_url . '/css/' . $cache_key . '.css';
        
        if (!file_exists($cache_file) || $this->is_cache_expired($cache_file)) {
            $this->combine_and_minify_css($css_files, $cache_file);
        }
        
        // Enfileirar arquivo otimizado
        wp_enqueue_style(
            'upgram-optimized-css',
            $cache_url,
            array(),
            filemtime($cache_file)
        );
        
        if ($async) {
            add_filter('style_loader_tag', array($this, 'make_css_async'), 10, 2);
        }
    }
    
    /**
     * Combinar e minificar CSS
     */
    private function combine_and_minify_css($css_files, $output_file) {
        $css_dir = $this->cache_dir . '/css';
        if (!file_exists($css_dir)) {
            wp_mkdir_p($css_dir);
        }
        
        $combined_css = '';
        
        foreach ($css_files as $handle => $style) {
            $src = $style->src;
            
            // Converter URL relativa para absoluta
            if (strpos($src, 'http') !== 0) {
                $src = site_url($src);
            }
            
            // Buscar conteúdo do arquivo
            $response = wp_remote_get($src);
            if (is_wp_error($response)) {
                continue;
            }
            
            $css_content = wp_remote_retrieve_body($response);
            
            // Ajustar URLs relativas
            $css_content = $this->fix_css_urls($css_content, $src);
            
            // Minificar
            $css_content = $this->minify_css($css_content);
            
            $combined_css .= "\n/* {$handle} */\n" . $css_content;
        }
        
        // Adicionar font-display: swap se configurado
        if (get_option('upgram_optimizer_font_display_swap', true)) {
            $combined_css = preg_replace(
                '/@font-face\s*\{/i',
                '@font-face { font-display: swap; ',
                $combined_css
            );
        }
        
        file_put_contents($output_file, $combined_css);
    }
    
    /**
     * Minificar CSS
     */
    private function minify_css($css) {
        // Remover comentários
        $css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
        
        // Remover espaços desnecessários
        $css = str_replace(array("\r\n", "\r", "\n", "\t", '  ', '    ', '    '), '', $css);
        $css = preg_replace('/\s+/', ' ', $css);
        $css = preg_replace('/\s*([{}:;,])\s*/', '$1', $css);
        $css = preg_replace('/;\s*}/', '}', $css);
        
        return trim($css);
    }
    
    /**
     * Corrigir URLs relativas no CSS
     */
    private function fix_css_urls($css, $base_url) {
        $base_path = dirname($base_url);
        
        // Substituir URLs relativas
        $css = preg_replace_callback(
            '/url\s*\(\s*["\']?([^"\'()]+)["\']?\s*\)/i',
            function($matches) use ($base_path) {
                $url = trim($matches[1]);
                
                // Se já é absoluta, retornar como está
                if (strpos($url, 'http') === 0 || strpos($url, '//') === 0) {
                    return $matches[0];
                }
                
                // Se começa com /, é relativa ao site
                if (strpos($url, '/') === 0) {
                    return 'url(' . site_url($url) . ')';
                }
                
                // URL relativa ao arquivo CSS
                return 'url(' . $base_path . '/' . $url . ')';
            },
            $css
        );
        
        return $css;
    }
    
    /**
     * Tornar CSS assíncrono
     */
    public function make_css_async($tag, $handle) {
        if ($handle === 'upgram-optimized-css') {
            $tag = str_replace("rel='stylesheet'", "rel='preload' as='style' onload=\"this.onload=null;this.rel='stylesheet'\"", $tag);
            $tag .= '<noscript>' . str_replace("rel='preload' as='style'", "rel='stylesheet'", $tag) . '</noscript>';
        }
        return $tag;
    }
    
    /**
     * Otimizar JavaScript
     */
    public function optimize_js() {
        global $wp_scripts;
        
        if (empty($wp_scripts->queue)) {
            return;
        }
        
        $minify = get_option('upgram_optimizer_js_minify', true);
        $combine = get_option('upgram_optimizer_js_combine', true);
        $combine_inline = get_option('upgram_optimizer_js_combine_inline', false);
        
        if (!$minify && !$combine) {
            return;
        }
        
        $js_files = array();
        $inline_scripts = array();
        $handles_to_remove = array();
        
        foreach ($wp_scripts->queue as $handle) {
            $script = $wp_scripts->registered[$handle];
            
            // Pular se for condicional
            if (isset($script->extra['conditional'])) {
                continue;
            }
            
            // Pular se estiver na lista de bloqueio
            if (!empty($script->src) && $this->is_resource_blocked($script->src, 'js')) {
                $handles_to_remove[] = $handle;
                continue;
            }
            
            // Scripts inline
            if (!empty($script->extra['data'])) {
                if ($combine_inline) {
                    $inline_scripts[$handle] = $script->extra['data'];
                }
                continue;
            }
            
            // Scripts externos
            if (!empty($script->src)) {
                $js_files[$handle] = $script;
                $handles_to_remove[] = $handle;
            }
        }
        
        if (empty($js_files) && empty($inline_scripts)) {
            return;
        }
        
        // Remover scripts originais
        foreach ($handles_to_remove as $handle) {
            wp_dequeue_script($handle);
        }
        
        // Gerar arquivo combinado/minificado
        $cache_key = $this->generate_cache_key($js_files, 'js', $inline_scripts);
        $cache_file = $this->cache_dir . '/js/' . $cache_key . '.js';
        $cache_url = $this->cache_url . '/js/' . $cache_key . '.js';
        
        if (!file_exists($cache_file) || $this->is_cache_expired($cache_file)) {
            $this->combine_and_minify_js($js_files, $inline_scripts, $cache_file);
        }
        
        // Enfileirar arquivo otimizado
        wp_enqueue_script(
            'upgram-optimized-js',
            $cache_url,
            array(),
            filemtime($cache_file),
            true
        );
    }
    
    /**
     * Combinar e minificar JavaScript
     */
    private function combine_and_minify_js($js_files, $inline_scripts, $output_file) {
        $js_dir = $this->cache_dir . '/js';
        if (!file_exists($js_dir)) {
            wp_mkdir_p($js_dir);
        }
        
        $combined_js = '';
        
        // Adicionar scripts externos
        foreach ($js_files as $handle => $script) {
            $src = $script->src;
            
            // Converter URL relativa para absoluta
            if (strpos($src, 'http') !== 0 && strpos($src, '//') !== 0) {
                $src = site_url($src);
            }
            
            // Buscar conteúdo do arquivo
            $response = wp_remote_get($src);
            if (is_wp_error($response)) {
                continue;
            }
            
            $js_content = wp_remote_retrieve_body($response);
            
            // Minificar
            $js_content = $this->minify_js($js_content);
            
            $combined_js .= "\n/* {$handle} */\n" . $js_content;
        }
        
        // Adicionar scripts inline
        if (!empty($inline_scripts)) {
            foreach ($inline_scripts as $handle => $inline) {
                $combined_js .= "\n/* {$handle} (inline) */\n" . $this->minify_js($inline);
            }
        }
        
        file_put_contents($output_file, $combined_js);
    }
    
    /**
     * Minificar JavaScript
     */
    private function minify_js($js) {
        // Remover comentários de linha única
        $js = preg_replace('/\/\/.*$/m', '', $js);
        
        // Remover comentários de múltiplas linhas
        $js = preg_replace('/\/\*[^*]*\*+([^\/][^*]*\*+)*\//', '', $js);
        
        // Remover espaços desnecessários
        $js = preg_replace('/\s+/', ' ', $js);
        $js = preg_replace('/\s*([{}:;,\[\]()=+\-*\/])\s*/', '$1', $js);
        
        return trim($js);
    }
    
    /**
     * Bloquear recursos não utilizados
     */
    public function block_unused_resources() {
        $blocked_css = get_option('upgram_optimizer_block_css', '');
        $blocked_js = get_option('upgram_optimizer_block_js', '');
        
        if (empty($blocked_css) && empty($blocked_js)) {
            return;
        }
        
        // Bloquear CSS
        if (!empty($blocked_css)) {
            $css_patterns = array_map('trim', explode("\n", $blocked_css));
            foreach ($css_patterns as $pattern) {
                if (empty($pattern)) continue;
                wp_dequeue_style($pattern);
                wp_deregister_style($pattern);
            }
        }
        
        // Bloquear JS
        if (!empty($blocked_js)) {
            $js_patterns = array_map('trim', explode("\n", $blocked_js));
            foreach ($js_patterns as $pattern) {
                if (empty($pattern)) continue;
                wp_dequeue_script($pattern);
                wp_deregister_script($pattern);
            }
        }
    }
    
    /**
     * Verificar se recurso está bloqueado
     */
    private function is_resource_blocked($src, $type) {
        $blocked = $type === 'css' 
            ? get_option('upgram_optimizer_block_css', '')
            : get_option('upgram_optimizer_block_js', '');
        
        if (empty($blocked)) {
            return false;
        }
        
        $patterns = array_map('trim', explode("\n", $blocked));
        foreach ($patterns as $pattern) {
            if (empty($pattern)) continue;
            if (strpos($src, $pattern) !== false) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Definir headers de cache do navegador
     */
    public function set_browser_cache_headers() {
        if (is_admin() || (defined('WP_CLI') && WP_CLI)) {
            return;
        }
        
        // Verificar se está ativado
        if (!get_option('upgram_optimizer_browser_cache_enable', false)) {
            return;
        }
        
        $ttl_days = get_option('upgram_optimizer_browser_cache_ttl', 30);
        $ttl_seconds = $ttl_days * 24 * 60 * 60;
        
        // Cache para recursos estáticos
        $request_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
        if (preg_match('/\.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$/i', $request_uri)) {
            if (!headers_sent()) {
                header('Cache-Control: public, max-age=' . $ttl_seconds);
                header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $ttl_seconds) . ' GMT');
            }
        }
    }
    
    /**
     * Definir headers de cache móvel
     */
    public function set_mobile_cache_headers() {
        if (is_admin() || (defined('WP_CLI') && WP_CLI)) {
            return;
        }
        
        // Verificar se está ativado
        if (!get_option('upgram_optimizer_mobile_cache_enable', false)) {
            return;
        }
        
        if (!wp_is_mobile()) {
            return;
        }
        
        $ttl_days = get_option('upgram_optimizer_mobile_cache_ttl', 7);
        $ttl_seconds = $ttl_days * 24 * 60 * 60;
        
        // Aplicar headers apenas se ainda não foram enviados
        if (!headers_sent()) {
            header('Cache-Control: public, max-age=' . $ttl_seconds);
            header('Vary: User-Agent');
            header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $ttl_seconds) . ' GMT');
        }
    }
    
    /**
     * Iniciar buffer para lazy loading
     */
    public function start_lazy_load_buffer() {
        if (is_admin() || (defined('WP_CLI') && WP_CLI)) {
            return;
        }
        
        
        // Iniciar output buffering para capturar todo o HTML
        // Apenas se não houver outro buffer ativo
        if (ob_get_level() === 0) {
            ob_start(array($this, 'add_lazy_loading_to_output'));
        }
    }
    
    /**
     * Adicionar lazy loading a imagens no output final
     */
    public function add_lazy_loading_to_output($buffer) {
        if (empty($buffer)) {
            return $buffer;
        }
        
        // Contar quantas imagens foram processadas (para debug)
        $images_processed = 0;
        $image_count = 0;
        
        // Adicionar loading="lazy" e decoding="async" a todas as imagens que não têm
        // Regex melhorada que funciona mesmo com atributos em qualquer ordem
        $buffer = preg_replace_callback(
            '/<img\s+([^>]*?)>/i',
            function($matches) use (&$images_processed, &$image_count) {
                $attrs = $matches[1];
                $images_processed++;
                $image_count++;
                
                // Pular imagens que já têm loading="eager" explicitamente
                if (preg_match('/\s+loading\s*=\s*["\']eager["\']/i', $attrs)) {
                    return $matches[0];
                }
                
                // Primeira imagem do conteúdo principal deve ser eager (LCP)
                $is_first_image = ($image_count === 1);
                
                // Verificar se já tem loading
                if (preg_match('/\s+loading\s*=\s*["\']([^"\']*)["\']/i', $attrs)) {
                    // Já tem loading, apenas adicionar decoding se não tiver
                    if (!preg_match('/\s+decoding\s*=\s*["\']([^"\']*)["\']/i', $attrs)) {
                        return '<img ' . $attrs . ' decoding="async">';
                    }
                    return $matches[0];
                }
                
                // Não tem loading, adicionar ambos
                $loading_attr = $is_first_image ? 'loading="eager"' : 'loading="lazy"';
                $decoding_attr = 'decoding="async"';
                
                // Adicionar fetchpriority apenas se não for primeira imagem
                $fetchpriority = $is_first_image ? ' fetchpriority="high"' : ' fetchpriority="low"';
                
                return '<img ' . $attrs . ' ' . $loading_attr . ' ' . $decoding_attr . $fetchpriority . '>';
            },
            $buffer
        );
        
        // Log para debug (apenas se ativado)
        if (defined('WP_DEBUG') && WP_DEBUG && isset($_GET['upgram_debug'])) {
            error_log("Upgram Optimizer: Processadas {$images_processed} imagens para lazy loading");
        }
        
        return $buffer;
    }
    
    /**
     * Adicionar lazy loading a imagens (hook do WordPress)
     */
    public function add_lazy_loading($attr, $attachment, $size) {
        if (!isset($attr['loading'])) {
            $attr['loading'] = 'lazy';
        }
        if (!isset($attr['decoding'])) {
            $attr['decoding'] = 'async';
        }
        return $attr;
    }
    
    /**
     * Adicionar atributo loading a tags img (novo hook do WordPress 5.5+)
     */
    public function add_loading_attr_to_img($value, $image) {
        // Se já retornou um valor, usar ele
        if ($value !== null) {
            return $value;
        }
        
        // Retornar 'lazy' por padrão
        return 'lazy';
    }
    
    /**
     * Adicionar lazy loading ao conteúdo
     */
    public function add_lazy_loading_to_content($content) {
        if (empty($content)) {
            return $content;
        }
        
        // Adicionar loading="lazy" a imagens que não têm
        $content = preg_replace_callback(
            '/<img\s+([^>]*?)>/i',
            function($matches) {
                $attrs = $matches[1];
                
                // Verificar se já tem loading
                if (preg_match('/\s+loading\s*=\s*["\']([^"\']*)["\']/i', $attrs)) {
                    // Já tem loading, apenas adicionar decoding se não tiver
                    if (!preg_match('/\s+decoding\s*=\s*["\']([^"\']*)["\']/i', $attrs)) {
                        return '<img ' . $attrs . ' decoding="async">';
                    }
                    return $matches[0];
                }
                
                // Não tem loading, adicionar ambos
                return '<img ' . $attrs . ' loading="lazy" decoding="async">';
            },
            $content
        );
        
        return $content;
    }
    
    /**
     * Definir headers do Cloudflare
     */
    public function set_cloudflare_headers() {
        if (is_admin() || (defined('WP_CLI') && WP_CLI)) {
            return;
        }
        
        $api_token = get_option('upgram_optimizer_cloudflare_api_token', '');
        $zone_id = get_option('upgram_optimizer_cloudflare_zone_id', '');
        
        if (empty($api_token) || empty($zone_id)) {
            return;
        }
        
        // Headers para cache do Cloudflare
        header('CF-Cache-Status: HIT');
        header('CF-Ray: ' . (isset($_SERVER['HTTP_CF_RAY']) ? $_SERVER['HTTP_CF_RAY'] : ''));
    }
    
    /**
     * Gerar chave de cache
     */
    private function generate_cache_key($files, $type, $extra = array()) {
        $key_data = array();
        
        foreach ($files as $handle => $file) {
            $key_data[] = $handle . ':' . $file->src . ':' . (isset($file->ver) ? $file->ver : '');
        }
        
        if (!empty($extra)) {
            $key_data[] = md5(serialize($extra));
        }
        
        return md5(implode('|', $key_data));
    }
    
    /**
     * Verificar se cache expirou
     */
    private function is_cache_expired($file) {
        if (!file_exists($file)) {
            return true;
        }
        
        $ttl_hours = get_option('upgram_optimizer_cache_ttl', 24);
        $expires = filemtime($file) + ($ttl_hours * 60 * 60);
        
        return time() >= $expires;
    }
    
    /**
     * Limpar todo o cache
     */
    public function clear_all_cache() {
        $this->clear_directory($this->cache_dir . '/css');
        $this->clear_directory($this->cache_dir . '/js');
    }
    
    /**
     * Limpar diretório
     */
    private function clear_directory($dir) {
        if (!file_exists($dir)) {
            return;
        }
        
        $files = array_diff(scandir($dir), array('.', '..'));
        foreach ($files as $file) {
            $file_path = $dir . '/' . $file;
            if (is_file($file_path)) {
                unlink($file_path);
            }
        }
    }
    
    /**
     * Adiar scripts que causam render blocking
     */
    public function defer_render_blocking_scripts() {
        global $wp_scripts;
        
        if (empty($wp_scripts->queue)) {
            return;
        }
        
        // Lista de padrões que causam render blocking (configurável)
        $blocking_patterns = get_option('upgram_optimizer_render_blocking_patterns', '');
        $patterns = !empty($blocking_patterns) 
            ? array_map('trim', explode("\n", $blocking_patterns))
            : array('frontend.min.js', 'astra', 'theme'); // Padrões padrão
        
        if (empty($patterns)) {
            return;
        }
        
        foreach ($wp_scripts->queue as $handle) {
            if (!isset($wp_scripts->registered[$handle])) {
                continue;
            }
            
            $script = $wp_scripts->registered[$handle];
            
            // Pular se não tiver src (script inline)
            if (empty($script->src)) {
                continue;
            }
            
            $src = $script->src;
            
            // Verificar se o script corresponde a algum padrão
            $should_defer = false;
            foreach ($patterns as $pattern) {
                if (empty($pattern)) continue;
                
                // Verificar por handle ou URL
                if (stripos($handle, $pattern) !== false || 
                    stripos($src, $pattern) !== false) {
                    $should_defer = true;
                    break;
                }
            }
            
            if ($should_defer) {
                // Adiar o script usando add_data
                $wp_scripts->add_data($handle, 'defer', true);
                
                // Remover async se existir (defer e async não devem ser usados juntos)
                if (isset($wp_scripts->registered[$handle]->extra['async'])) {
                    unset($wp_scripts->registered[$handle]->extra['async']);
                }
            }
        }
        
        // Adicionar filtro para modificar a tag do script
        add_filter('script_loader_tag', array($this, 'modify_script_tag_for_defer'), 10, 3);
    }
    
    /**
     * Modificar tag do script para adicionar defer
     */
    public function modify_script_tag_for_defer($tag, $handle, $src) {
        global $wp_scripts;
        
        if (!isset($wp_scripts->registered[$handle])) {
            return $tag;
        }
        
        // Verificar se o script deve ser adiado
        $defer = $wp_scripts->get_data($handle, 'defer');
        
        if ($defer) {
            // Se já tem defer, não fazer nada
            if (strpos($tag, ' defer') !== false || strpos($tag, " defer='defer'") !== false) {
                return $tag;
            }
            
            // Adicionar defer antes do fechamento da tag
            $tag = str_replace('></script>', ' defer></script>', $tag);
            $tag = str_replace("'></script>", "' defer></script>", $tag);
            $tag = str_replace('"></script>', '" defer></script>', $tag);
        }
        
        return $tag;
    }
    
    /**
     * Adicionar fix para reflows forçados
     */
    public function add_render_blocking_fix() {
        if (is_admin()) {
            return;
        }
        
        ?>
        <script>
        (function() {
            'use strict';
            
            // Prevenir reflows forçados causados por consultas de propriedades geométricas
            // Esta solução agrupa leituras e escritas do DOM usando requestAnimationFrame
            
            var readQueue = [];
            var writeQueue = [];
            var scheduled = false;
            
            // Função para agendar leituras (batch reads)
            function batchReads(callback) {
                readQueue.push(callback);
                if (!scheduled) {
                    scheduled = true;
                    requestAnimationFrame(function() {
                        scheduled = false;
                        // Executar todas as leituras juntas
                        readQueue.forEach(function(fn) {
                            try {
                                fn();
                            } catch (e) {
                                console.warn('Upgram Optimizer: Erro em leitura agendada', e);
                            }
                        });
                        readQueue = [];
                    });
                }
            }
            
            // Função para agendar escritas (batch writes)
            function batchWrites(callback) {
                writeQueue.push(callback);
                if (!scheduled) {
                    scheduled = true;
                    requestAnimationFrame(function() {
                        scheduled = false;
                        // Executar todas as escritas primeiro
                        writeQueue.forEach(function(fn) {
                            try {
                                fn();
                            } catch (e) {
                                console.warn('Upgram Optimizer: Erro em escrita agendada', e);
                            }
                        });
                        writeQueue = [];
                        
                        // Depois executar leituras
                        readQueue.forEach(function(fn) {
                            try {
                                fn();
                            } catch (e) {
                                console.warn('Upgram Optimizer: Erro em leitura agendada', e);
                            }
                        });
                        readQueue = [];
                    });
                }
            }
            
            // Interceptar propriedades geométricas que causam reflow
            var geometryProps = ['offsetWidth', 'offsetHeight', 'offsetTop', 'offsetLeft',
                                'clientWidth', 'clientHeight', 'clientTop', 'clientLeft',
                                'scrollWidth', 'scrollHeight', 'scrollTop', 'scrollLeft'];
            
            // Wrapper para Element.prototype que previne reflows forçados
            var originalOffsetWidth = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'offsetWidth');
            var originalOffsetHeight = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'offsetHeight');
            
            // Interceptar apenas as propriedades mais problemáticas
            ['offsetWidth', 'offsetHeight'].forEach(function(prop) {
                try {
                    var descriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, prop);
                    if (descriptor && descriptor.get) {
                        var originalGet = descriptor.get;
                        Object.defineProperty(HTMLElement.prototype, prop, {
                            get: function() {
                                // Se já estamos em um requestAnimationFrame, retornar diretamente
                                if (scheduled) {
                                    return originalGet.call(this);
                                }
                                
                                // Caso contrário, agendar leitura
                                var value;
                                batchReads(function() {
                                    value = originalGet.call(this);
                                }.bind(this));
                                return value || 0; // Retornar valor padrão se ainda não foi calculado
                            },
                            configurable: true
                        });
                    }
                } catch (e) {
                    // Se não conseguir interceptar, continuar normalmente
                    console.warn('Upgram Optimizer: Não foi possível interceptar', prop, e);
                }
            });
            
            // Interceptar getBoundingClientRect que é muito usado e causa reflow
            var originalGetBoundingClientRect = Element.prototype.getBoundingClientRect;
            Element.prototype.getBoundingClientRect = function() {
                if (scheduled) {
                    return originalGetBoundingClientRect.call(this);
                }
                
                var result;
                batchReads(function() {
                    result = originalGetBoundingClientRect.call(this);
                }.bind(this));
                
                // Se não temos resultado ainda, retornar um objeto vazio para evitar erro
                if (!result) {
                    return {
                        top: 0,
                        left: 0,
                        bottom: 0,
                        right: 0,
                        width: 0,
                        height: 0,
                        x: 0,
                        y: 0
                    };
                }
                
                return result;
            };
            
            // Prevenir reflows em eventos que podem causar mudanças de layout
            var debounceTimers = {};
            ['resize', 'scroll', 'orientationchange'].forEach(function(eventName) {
                window.addEventListener(eventName, function() {
                    // Debounce para evitar muitas execuções
                    if (debounceTimers[eventName]) {
                        cancelAnimationFrame(debounceTimers[eventName]);
                    }
                    
                    debounceTimers[eventName] = requestAnimationFrame(function() {
                        // Limpar timers antigos
                        delete debounceTimers[eventName];
                    });
                }, { passive: true });
            });
            
            // Log para debug (apenas em desenvolvimento)
            if (window.location.search.indexOf('upgram_debug=1') !== -1) {
                console.log('Upgram Optimizer: Prevenção de reflows forçados ativada');
            }
        })();
        </script>
        <?php
    }
    
    /**
     * Aplicar defer/async por handle de script
     */
    public function apply_defer_async_by_handle($tag, $handle, $src) {
        // Lista de handles para defer
        $defer_handles = get_option('upgram_optimizer_defer_handles', array());
        if (empty($defer_handles)) {
            $defer_handles = array();
        } else {
            $defer_handles = is_array($defer_handles) ? $defer_handles : explode("\n", $defer_handles);
            $defer_handles = array_map('trim', $defer_handles);
        }
        
        // Lista de handles para async
        $async_handles = get_option('upgram_optimizer_async_handles', array());
        if (empty($async_handles)) {
            $async_handles = array();
        } else {
            $async_handles = is_array($async_handles) ? $async_handles : explode("\n", $async_handles);
            $async_handles = array_map('trim', $async_handles);
        }
        
        // Lista de handles que não podem ser mexidos (safelist)
        $safelist_handles = get_option('upgram_optimizer_safelist_handles', array());
        if (empty($safelist_handles)) {
            $safelist_handles = array();
        } else {
            $safelist_handles = is_array($safelist_handles) ? $safelist_handles : explode("\n", $safelist_handles);
            $safelist_handles = array_map('trim', $safelist_handles);
        }
        
        // Se está na safelist, não mexer
        if (in_array($handle, $safelist_handles)) {
            return $tag;
        }
        
        // Aplicar defer
        if (in_array($handle, $defer_handles)) {
            // Se já tem defer, não fazer nada
            if (strpos($tag, ' defer') === false && strpos($tag, " defer='defer'") === false) {
                $tag = str_replace('></script>', ' defer></script>', $tag);
                $tag = str_replace("'></script>", "' defer></script>", $tag);
                $tag = str_replace('"></script>', '" defer></script>', $tag);
            }
            return $tag;
        }
        
        // Aplicar async
        if (in_array($handle, $async_handles)) {
            // Se já tem async, não fazer nada
            if (strpos($tag, ' async') === false && strpos($tag, " async='async'") === false) {
                // Remover defer se existir (defer e async não devem ser usados juntos)
                $tag = str_replace(' defer', '', $tag);
                $tag = str_replace(" defer='defer'", '', $tag);
                $tag = str_replace(' defer="defer"', '', $tag);
                
                $tag = str_replace('></script>', ' async></script>', $tag);
                $tag = str_replace("'></script>", "' async></script>", $tag);
                $tag = str_replace('"></script>', '" async></script>', $tag);
            }
            return $tag;
        }
        
        return $tag;
    }
    
    /**
     * Delay JS - Marcar scripts para carregar apenas após interação do usuário
     */
    public function delay_js_scripts($tag, $handle, $src) {
        // Lista de handles para delay
        $delay_handles = get_option('upgram_optimizer_delay_js_handles', array());
        if (empty($delay_handles)) {
            $delay_handles = array();
        } else {
            $delay_handles = is_array($delay_handles) ? $delay_handles : explode("\n", $delay_handles);
            $delay_handles = array_map('trim', $delay_handles);
        }
        
        // Lista de handles que não podem ser atrasados (safelist)
        $delay_safelist = get_option('upgram_optimizer_delay_js_safelist', array());
        if (empty($delay_safelist)) {
            $delay_safelist = array();
        } else {
            $delay_safelist = is_array($delay_safelist) ? $delay_safelist : explode("\n", $delay_safelist);
            $delay_safelist = array_map('trim', $delay_safelist);
        }
        
        // Se está na safelist, não atrasar
        if (in_array($handle, $delay_safelist)) {
            return $tag;
        }
        
        // Se está na lista de delay, marcar para atrasar
        if (in_array($handle, $delay_handles)) {
            // Extrair src da tag
            if (preg_match('/src=["\']([^"\']+)["\']/', $tag, $matches)) {
                $script_src = $matches[1];
                
                // Substituir tag por placeholder que será carregado depois
                return '<script type="text/upgram-delayed" data-src="' . esc_attr($script_src) . '" data-handle="' . esc_attr($handle) . '"></script>';
            }
        }
        
        return $tag;
    }
    
    /**
     * Injetar loader de Delay JS
     */
    public function inject_delay_js_loader() {
        ?>
        <script>
        (function() {
            'use strict';
            
            // Lista de scripts atrasados
            var delayedScripts = [];
            var userInteracted = false;
            
            // Coletar todos os scripts marcados para delay
            document.querySelectorAll('script[type="text/upgram-delayed"]').forEach(function(script) {
                delayedScripts.push({
                    src: script.getAttribute('data-src'),
                    handle: script.getAttribute('data-handle'),
                    element: script
                });
            });
            
            if (delayedScripts.length === 0) {
                return;
            }
            
            // Função para carregar scripts atrasados
            function loadDelayedScripts() {
                if (userInteracted) {
                    return; // Já carregou
                }
                
                userInteracted = true;
                
                delayedScripts.forEach(function(scriptData) {
                    var script = document.createElement('script');
                    script.src = scriptData.src;
                    script.async = true;
                    
                    // Substituir placeholder pelo script real
                    if (scriptData.element && scriptData.element.parentNode) {
                        scriptData.element.parentNode.replaceChild(script, scriptData.element);
                    } else {
                        document.head.appendChild(script);
                    }
                });
            }
            
            // Escutar eventos de interação
            var events = ['scroll', 'touchstart', 'mousedown', 'keydown', 'click'];
            events.forEach(function(eventName) {
                window.addEventListener(eventName, function() {
                    loadDelayedScripts();
                }, { once: true, passive: true });
            });
            
            // Timeout de segurança (carregar após 3 segundos mesmo sem interação)
            setTimeout(function() {
                if (!userInteracted) {
                    loadDelayedScripts();
                }
            }, 3000);
        })();
        </script>
        <?php
    }
    
    /**
     * Asset Manager - Desativar scripts/CSS por regras
     */
    public function disable_assets_by_rules() {
        global $wp_scripts, $wp_styles;
        
        // Obter regras de desativação
        $disable_rules_raw = get_option('upgram_optimizer_disable_assets_rules', '');
        
        if (empty($disable_rules_raw)) {
            return;
        }
        
        // Tentar decodificar JSON
        $disable_rules = json_decode($disable_rules_raw, true);
        
        // Se não for JSON válido, tentar como texto simples (legado)
        if (json_last_error() !== JSON_ERROR_NONE || !is_array($disable_rules)) {
            return;
        }
        
        // Verificar contexto atual
        $context = $this->get_current_context();
        
        foreach ($disable_rules as $rule) {
            if (empty($rule['handle']) || empty($rule['type'])) {
                continue;
            }
            
            $handle = trim($rule['handle']);
            $type = trim($rule['type']); // 'script' ou 'style'
            $conditions = isset($rule['conditions']) ? $rule['conditions'] : array();
            
            // Verificar se a regra se aplica ao contexto atual
            if (!$this->rule_applies($conditions, $context)) {
                continue;
            }
            
            // Desativar asset
            if ($type === 'script') {
                wp_dequeue_script($handle);
                wp_deregister_script($handle);
            } elseif ($type === 'style') {
                wp_dequeue_style($handle);
                wp_deregister_style($handle);
            }
        }
    }
    
    /**
     * Obter contexto atual da página
     */
    private function get_current_context() {
        $context = array(
            'is_home' => is_front_page() || is_home(),
            'is_single' => is_single(),
            'is_page' => is_page(),
            'is_product' => is_product(),
            'is_archive' => is_archive(),
            'is_mobile' => wp_is_mobile(),
            'is_desktop' => !wp_is_mobile(),
            'slug' => '',
            'post_type' => ''
        );
        
        if (is_singular()) {
            global $post;
            if ($post) {
                $context['slug'] = $post->post_name;
                $context['post_type'] = $post->post_type;
            }
        }
        
        return $context;
    }
    
    /**
     * Verificar se regra se aplica ao contexto
     */
    private function rule_applies($conditions, $context) {
        if (empty($conditions)) {
            return false;
        }
        
        // Verificar cada condição
        foreach ($conditions as $condition) {
            $type = isset($condition['type']) ? $condition['type'] : '';
            $value = isset($condition['value']) ? $condition['value'] : '';
            
            switch ($type) {
                case 'everywhere':
                    return true;
                    
                case 'home':
                    if ($context['is_home']) {
                        return true;
                    }
                    break;
                    
                case 'posts':
                    if ($context['is_single'] && $context['post_type'] === 'post') {
                        return true;
                    }
                    break;
                    
                case 'pages':
                    if ($context['is_page']) {
                        return true;
                    }
                    break;
                    
                case 'products':
                    if ($context['is_product']) {
                        return true;
                    }
                    break;
                    
                case 'slug':
                    if (!empty($value) && $context['slug'] === $value) {
                        return true;
                    }
                    break;
                    
                case 'mobile':
                    if ($context['is_mobile']) {
                        return true;
                    }
                    break;
                    
                case 'desktop':
                    if ($context['is_desktop']) {
                        return true;
                    }
                    break;
            }
        }
        
        return false;
    }
    
    /**
     * Injetar monitor de INP
     */
    public function inject_inp_monitor() {
        if (is_admin()) {
            return;
        }
        ?>
        <script>
        (function() {
            'use strict';
            
            // Monitor de INP (Interaction to Next Paint)
            var inpEntries = [];
            var observer = null;
            
            // Verificar se PerformanceObserver está disponível
            if ('PerformanceObserver' in window) {
                try {
                    observer = new PerformanceObserver(function(list) {
                        var entries = list.getEntries();
                        entries.forEach(function(entry) {
                            // Capturar apenas interações lentas (> 200ms)
                            if (entry.duration > 200) {
                                var target = entry.target;
                                var selector = '';
                                
                                // Obter seletor do elemento
                                if (target && target.nodeName) {
                                    // Tentar obter ID, classe ou tag
                                    if (target.id) {
                                        selector = '#' + target.id;
                                    } else if (target.className && typeof target.className === 'string') {
                                        selector = '.' + target.className.split(' ')[0];
                                    } else {
                                        selector = target.nodeName.toLowerCase();
                                    }
                                    
                                    // Obter texto do elemento (limitado)
                                    var text = target.textContent ? target.textContent.substring(0, 50) : '';
                                    
                                    inpEntries.push({
                                        duration: Math.round(entry.duration),
                                        selector: selector,
                                        text: text,
                                        type: entry.name,
                                        timestamp: Date.now(),
                                        is_mobile: /Mobile|Android|iPhone|iPad/.test(navigator.userAgent)
                                    });
                                }
                            }
                        });
                        
                        // Enviar para servidor a cada 10 entradas ou a cada 5 segundos
                        if (inpEntries.length >= 10) {
                            sendINPData();
                        }
                    });
                    
                    // Observar eventos de interação
                    observer.observe({ entryTypes: ['event'] });
                    
                    // Enviar dados periodicamente
                    setInterval(sendINPData, 5000);
                    
                    // Enviar dados antes de sair da página
                    window.addEventListener('beforeunload', sendINPData);
                    
                } catch (e) {
                    console.warn('Upgram INP Monitor: Erro ao inicializar', e);
                }
            }
            
            // Função para enviar dados de INP
            function sendINPData() {
                if (inpEntries.length === 0) {
                    return;
                }
                
                var data = inpEntries.splice(0); // Remover e enviar
                
                // Enviar via AJAX
                if (typeof jQuery !== 'undefined') {
                    jQuery.post(ajaxurl || '<?php echo admin_url('admin-ajax.php'); ?>', {
                        action: 'upgram_log_inp_data',
                        data: data,
                        security: '<?php echo wp_create_nonce('upgram_inp_log_nonce'); ?>'
                    }).fail(function() {
                        // Se falhar, tentar novamente depois
                        inpEntries.unshift.apply(inpEntries, data);
                    });
                } else {
                    // Fallback sem jQuery
                    var xhr = new XMLHttpRequest();
                    xhr.open('POST', ajaxurl || '<?php echo admin_url('admin-ajax.php'); ?>', true);
                    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                    xhr.send('action=upgram_log_inp_data&data=' + encodeURIComponent(JSON.stringify(data)) + '&security=<?php echo wp_create_nonce('upgram_inp_log_nonce'); ?>');
                }
            }
        })();
        </script>
        <?php
    }
    
    /**
     * Desativar emojis do WordPress
     */
    private function disable_emojis() {
        // Remover scripts e estilos de emojis
        remove_action('wp_head', 'print_emoji_detection_script', 7);
        remove_action('admin_print_scripts', 'print_emoji_detection_script');
        remove_action('wp_print_styles', 'print_emoji_styles');
        remove_action('admin_print_styles', 'print_emoji_styles');
        remove_filter('the_content_feed', 'wp_staticize_emoji');
        remove_filter('comment_text_rss', 'wp_staticize_emoji');
        remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
        
        // Remover DNS prefetch de emojis
        add_filter('emoji_svg_url', '__return_false');
        
        // Remover do TinyMCE
        add_filter('tiny_mce_plugins', array($this, 'disable_emojis_tinymce'));
    }
    
    /**
     * Desativar emojis no TinyMCE
     */
    public function disable_emojis_tinymce($plugins) {
        if (is_array($plugins)) {
            return array_diff($plugins, array('wpemoji'));
        }
        return $plugins;
    }
    
    /**
     * Desativar embeds do WordPress (remover hooks cedo)
     */
    public function disable_embeds_early() {
        // Remover o endpoint oEmbed
        remove_action('rest_api_init', 'wp_oembed_register_route');
        
        // Desabilitar oEmbed discovery
        remove_filter('oembed_dataparse', 'wp_filter_oembed_result', 10);
        remove_action('wp_head', 'wp_oembed_add_discovery_links');
        remove_action('wp_head', 'wp_oembed_add_host_js');
        
        // Remover filtros de oEmbed
        remove_filter('pre_oembed_result', 'wp_filter_pre_oembed_result', 10);
        
        // Remover o hook que registra o script wp-embed
        // O script wp-embed é registrado no hook 'wp_enqueue_scripts' com prioridade 1
        // Precisamos remover isso antes que seja executado
        remove_action('wp_enqueue_scripts', 'wp_oembed_add_host_js');
    }
    
    /**
     * Desativar embeds do WordPress (remover script no hook correto)
     */
    public function disable_embeds_script() {
        // Remover o script wp-embed se foi registrado
        // Usar wp_script_is para verificar antes de desregistrar
        if (wp_script_is('wp-embed', 'registered')) {
            wp_deregister_script('wp-embed');
        }
        if (wp_script_is('wp-embed', 'enqueued')) {
            wp_dequeue_script('wp-embed');
        }
    }
    
    /**
     * Controlar Heartbeat do WordPress no frontend
     */
    public function control_heartbeat_frontend() {
        // Remover heartbeat no frontend (apenas no hook correto)
        if (!is_admin()) {
            if (wp_script_is('heartbeat', 'registered')) {
                wp_deregister_script('heartbeat');
            }
            if (wp_script_is('heartbeat', 'enqueued')) {
                wp_dequeue_script('heartbeat');
            }
        }
    }
    
    /**
     * Controlar Heartbeat do WordPress no admin
     */
    public function control_heartbeat_admin() {
        // No admin, apenas reduzir frequência (não remover)
        // A frequência é controlada pelo filtro heartbeat_settings
    }
    
    /**
     * Controlar frequência do Heartbeat
     */
    public function control_heartbeat_frequency($settings) {
        $frequency = get_option('upgram_optimizer_heartbeat_frequency', 60);
        if (isset($settings) && is_array($settings)) {
            $settings['interval'] = intval($frequency);
        }
        return $settings;
    }
    
    /**
     * Verificar se o site usa Gutenberg
     */
    private function uses_gutenberg() {
        // Verificar se Gutenberg está ativo
        if (function_exists('has_blocks')) {
            return true;
        }
        
        // Verificar se o tema suporta editor de blocos
        if (current_theme_supports('editor-styles')) {
            return true;
        }
        
        return false;
    }
    
    /**
     * Remover CSS de blocos se não usa Gutenberg
     */
    public function remove_block_css() {
        wp_dequeue_style('wp-block-library');
        wp_dequeue_style('wp-block-library-theme');
        wp_dequeue_style('wc-block-style');
        wp_dequeue_style('global-styles');
    }
    
    /**
     * Inicializar cache de objetos
     */
    private function init_object_cache() {
        // Usar transients do WordPress com TTL configurável
        // O WordPress já usa cache de objetos se estiver disponível (Redis, Memcached, etc.)
        // Aqui apenas garantimos que o TTL está configurado corretamente
        
        $ttl_seconds = get_option('upgram_optimizer_object_cache_ttl', 3600);
        
        // Filtrar TTL padrão de transients
        add_filter('transient_timeout', function($timeout, $transient) use ($ttl_seconds) {
            // Aplicar TTL customizado apenas para transients do Upgram
            if (strpos($transient, 'upgram_') === 0) {
                return intval($ttl_seconds);
            }
            return $timeout;
        }, 10, 2);
    }
    
    /**
     * Obter do cache de objetos
     */
    public static function get_object_cache($key, $group = 'upgram') {
        $full_key = $group . '_' . $key;
        
        // Tentar wp_cache primeiro (Redis, Memcached, etc.)
        $value = wp_cache_get($full_key, $group);
        if ($value !== false) {
            return $value;
        }
        
        // Fallback para transient
        return get_transient($full_key);
    }
    
    /**
     * Salvar no cache de objetos
     */
    public static function set_object_cache($key, $value, $group = 'upgram', $ttl = null) {
        $full_key = $group . '_' . $key;
        
        if ($ttl === null) {
            $ttl = get_option('upgram_optimizer_object_cache_ttl', 3600);
        }
        
        // Salvar em wp_cache (Redis, Memcached, etc.)
        wp_cache_set($full_key, $value, $group, intval($ttl));
        
        // Fallback para transient
        set_transient($full_key, $value, intval($ttl));
    }
    
    /**
     * Limpar cache de objetos
     */
    public static function clear_object_cache($key = null, $group = 'upgram') {
        if ($key === null) {
            // Limpar todo o grupo
            wp_cache_flush_group($group);
            
            // Limpar transients do grupo
            global $wpdb;
            $wpdb->query($wpdb->prepare(
                "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s",
                '_transient_' . $group . '_%',
                '_transient_timeout_' . $group . '_%'
            ));
        } else {
            $full_key = $group . '_' . $key;
            wp_cache_delete($full_key, $group);
            delete_transient($full_key);
        }
    }
    
    /**
     * Inicializar Full Page Cache com variante Mobile/Desktop
     */
    public function init_full_page_cache() {
        if (is_admin() || (defined('WP_CLI') && WP_CLI)) {
            return;
        }
        
        // Não cachear requisições AJAX
        if (defined('DOING_AJAX') && DOING_AJAX) {
            return;
        }
        
        // Não cachear requisições POST
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            return;
        }
        
        // Não cachear se usuário está logado (opcional - pode ser configurável)
        if (is_user_logged_in() && !get_option('upgram_optimizer_full_page_cache_logged_in', false)) {
            return;
        }
        
        // Não cachear páginas com query strings específicas (ex: ?nocache=1)
        if (isset($_GET['nocache']) && $_GET['nocache'] == '1') {
            return;
        }
        
        // Não cachear páginas de checkout/carrinho
        if (function_exists('is_checkout') && (is_checkout() || is_cart())) {
            return;
        }
        
        // Determinar se é mobile ou desktop
        $is_mobile = wp_is_mobile() ? 'm' : 'd';
        $request_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
        $cache_key = $is_mobile . '-' . md5($request_uri);
        
        // Diretório de cache para páginas
        $page_cache_dir = $this->cache_dir . '/pages';
        if (!file_exists($page_cache_dir)) {
            wp_mkdir_p($page_cache_dir);
        }
        
        $cache_file = $page_cache_dir . '/' . $cache_key . '.html';
        $ttl_seconds = get_option('upgram_optimizer_full_page_cache_ttl', 3600);
        
        // Verificar se cache existe e não expirou
        if (file_exists($cache_file)) {
            $file_time = filemtime($cache_file);
            if ((time() - $file_time) < $ttl_seconds) {
                // Cache válido - servir arquivo
                $cached_content = file_get_contents($cache_file);
                if (!empty($cached_content)) {
                    // Adicionar header indicando cache hit
                    if (!headers_sent()) {
                        header('X-Upgram-Cache: HIT');
                        header('X-Upgram-Cache-Device: ' . ($is_mobile ? 'mobile' : 'desktop'));
                        header('Content-Type: text/html; charset=UTF-8');
                    }
                    echo $cached_content;
                    exit;
                }
            } else {
                // Cache expirado - remover arquivo
                @unlink($cache_file);
            }
        }
        
        // Cache miss - iniciar buffer para capturar output
        // Verificar se não há outro buffer ativo
        if (ob_get_level() === 0) {
            ob_start(array($this, 'save_full_page_cache'));
        }
    }
    
    /**
     * Salvar cache da página completa
     */
    public function save_full_page_cache($buffer) {
        if (empty($buffer)) {
            return $buffer;
        }
        
        // Não cachear se já foi servido do cache
        if (headers_sent() && isset($_SERVER['HTTP_X_UPGRAM_CACHE'])) {
            return $buffer;
        }
        
        $is_mobile = wp_is_mobile() ? 'm' : 'd';
        $request_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
        $cache_key = $is_mobile . '-' . md5($request_uri);
        
        $page_cache_dir = $this->cache_dir . '/pages';
        if (!file_exists($page_cache_dir)) {
            wp_mkdir_p($page_cache_dir);
        }
        
        $cache_file = $page_cache_dir . '/' . $cache_key . '.html';
        
        // Salvar buffer no arquivo
        file_put_contents($cache_file, $buffer);
        
        // Adicionar header indicando cache miss
        if (!headers_sent()) {
            header('X-Upgram-Cache: MISS');
            header('X-Upgram-Cache-Device: ' . ($is_mobile ? 'mobile' : 'desktop'));
        }
        
        return $buffer;
    }
    
    /**
     * Desativar assets no mobile
     */
    public function disable_mobile_assets() {
        if (!wp_is_mobile()) {
            return;
        }
        
        $disable_list = get_option('upgram_optimizer_mobile_disable_assets_list', '');
        if (empty($disable_list)) {
            return;
        }
        
        $assets = array_map('trim', explode("\n", $disable_list));
        
        foreach ($assets as $asset) {
            if (empty($asset)) {
                continue;
            }
            
            // Tentar desativar como handle
            wp_dequeue_style($asset);
            wp_deregister_style($asset);
            wp_dequeue_script($asset);
            wp_deregister_script($asset);
            
            // Se contém padrão de URL, usar filtro de loader tag
            if (strpos($asset, 'http') !== false || strpos($asset, '//') !== false) {
                add_filter('style_loader_tag', function($tag, $handle) use ($asset) {
                    if (strpos($tag, $asset) !== false) {
                        return '';
                    }
                    return $tag;
                }, 10, 2);
                
                add_filter('script_loader_tag', function($tag, $handle) use ($asset) {
                    if (strpos($tag, $asset) !== false) {
                        return '';
                    }
                    return $tag;
                }, 10, 2);
            }
        }
    }
    
    /**
     * Delay JS extra no mobile
     */
    public function delay_mobile_js($tag, $handle, $src) {
        if (!wp_is_mobile()) {
            return $tag;
        }
        
        $delay_handles = get_option('upgram_optimizer_mobile_delay_js_handles', '');
        if (empty($delay_handles)) {
            return $tag;
        }
        
        $handles = array_map('trim', explode("\n", $delay_handles));
        
        if (in_array($handle, $handles)) {
            // Extrair src da tag
            if (preg_match('/src=["\']([^"\']+)["\']/', $tag, $matches)) {
                $script_src = $matches[1];
                return '<script type="text/upgram-mobile-delayed" data-src="' . esc_attr($script_src) . '" data-handle="' . esc_attr($handle) . '"></script>';
            }
        }
        
        return $tag;
    }
    
    /**
     * Injetar loader de Delay JS para mobile
     */
    public function inject_mobile_delay_js_loader() {
        if (!wp_is_mobile()) {
            return;
        }
        
        ?>
        <script>
        (function() {
            'use strict';
            
            var delayedScripts = [];
            var userInteracted = false;
            
            // Coletar scripts marcados para delay no mobile
            document.querySelectorAll('script[type="text/upgram-mobile-delayed"]').forEach(function(script) {
                delayedScripts.push({
                    src: script.getAttribute('data-src'),
                    handle: script.getAttribute('data-handle'),
                    element: script
                });
            });
            
            if (delayedScripts.length === 0) {
                return;
            }
            
            function loadDelayedScripts() {
                if (userInteracted) {
                    return;
                }
                
                userInteracted = true;
                
                delayedScripts.forEach(function(scriptData) {
                    var script = document.createElement('script');
                    script.src = scriptData.src;
                    script.async = true;
                    
                    if (scriptData.element && scriptData.element.parentNode) {
                        scriptData.element.parentNode.replaceChild(script, scriptData.element);
                    } else {
                        document.head.appendChild(script);
                    }
                });
            }
            
            // Escutar eventos de interação
            var events = ['scroll', 'touchstart', 'mousedown', 'keydown', 'click'];
            events.forEach(function(eventName) {
                window.addEventListener(eventName, function() {
                    loadDelayedScripts();
                }, { once: true, passive: true });
            });
            
            // Timeout de segurança (5 segundos no mobile)
            setTimeout(function() {
                if (!userInteracted) {
                    loadDelayedScripts();
                }
            }, 5000);
        })();
        </script>
        <?php
    }
    
    /**
     * Bloquear queries antes do carregamento no mobile
     */
    public function block_mobile_queries_early() {
        if (!wp_is_mobile()) {
            return;
        }
        
        // SEMPRE bloquear no mobile (independente da configuração)
        // Priorizar carregamento da página acima de tudo
        
        // Bloquear queries pesadas em hooks que executam antes do carregamento
        // Remover hooks que fazem queries antes do carregamento
        if (class_exists('Upgram_License_Validation_Trigger')) {
            // Remover validação de licença na página do produto (já bloqueado no próprio arquivo, mas garantir aqui também)
            remove_action('wp', array('Upgram_License_Validation_Trigger', 'maybe_trigger_validation_on_product_page'), 10);
        }
        
        // Bloquear consultas de produtos relacionados no mobile
        add_filter('woocommerce_product_related_posts_query', function($query) {
            // No mobile, retornar query vazia para não executar
            if (wp_is_mobile()) {
                return array(); // Retornar array vazio para não executar query
            }
            return $query;
        }, 999);
        
        // Bloquear outras consultas pesadas que podem estar sendo feitas
        // Adiar todas as validações para depois do carregamento
        add_action('wp_footer', function() {
            // Validações serão feitas via AJAX quando necessário
            // Isso garante que a página carregue primeiro
        }, 999);
        
        // Bloquear consultas de estatísticas, reviews, etc. no carregamento inicial
        // Essas consultas devem ser feitas apenas quando o usuário interagir
    }
    
    /**
     * Inicializar Query Logger
     */
    public function init_query_logger() {
        if (is_admin() || (defined('WP_CLI') && WP_CLI)) {
            return;
        }
        
        // Iniciar contador de tempo
        $this->query_start_time = microtime(true);
        $this->query_count = 0;
        $this->slow_queries = array();
        
        // Hook para capturar queries do WordPress
        add_filter('log_query_custom_data', array($this, 'capture_query_data'), 10, 1);
        
        // Hook para logar tempo total de queries
        add_action('shutdown', array($this, 'log_total_query_time'), 999);
        
        // Se SAVEQUERIES estiver ativo, usar ele
        if (defined('SAVEQUERIES') && SAVEQUERIES) {
            add_action('shutdown', array($this, 'log_saved_queries'), 998);
        } else {
            // Tentar habilitar SAVEQUERIES temporariamente
            if (!defined('SAVEQUERIES')) {
                define('SAVEQUERIES', true);
            }
            add_action('shutdown', array($this, 'log_saved_queries'), 998);
        }
    }
    
    /**
     * Capturar dados de query
     */
    public function capture_query_data($data) {
        return $data;
    }
    
    /**
     * Logar queries salvas pelo WordPress
     */
    public function log_saved_queries() {
        global $wpdb;
        
        if (!isset($wpdb->queries) || empty($wpdb->queries)) {
            return;
        }
        
        $threshold = get_option('upgram_optimizer_query_log_threshold', 100);
        $is_mobile = wp_is_mobile();
        
        foreach ($wpdb->queries as $query_data) {
            if (!is_array($query_data) || count($query_data) < 2) {
                continue;
            }
            
            $query = $query_data[0];
            $query_time = isset($query_data[1]) ? $query_data[1] * 1000 : 0; // converter para ms
            
            $this->query_count++;
            
            // Se query for lenta, adicionar ao log
            if ($query_time > $threshold) {
                $this->slow_queries[] = array(
                    'query' => substr($query, 0, 200), // Primeiros 200 caracteres
                    'time' => round($query_time, 2),
                    'is_mobile' => $is_mobile
                );
            }
        }
    }
    
    /**
     * Logar tempo total de queries
     */
    public function log_total_query_time() {
        if (!isset($this->query_start_time) || $this->query_start_time == 0) {
            return;
        }
        
        $total_time = (microtime(true) - $this->query_start_time) * 1000; // em ms
        $is_mobile = wp_is_mobile();
        
        // Logar apenas se tempo total for significativo ou houver queries lentas
        if ($total_time > 50 || !empty($this->slow_queries)) {
            error_log(sprintf(
                'Upgram Query Logger: Total de %d queries em %.2fms (%s)',
                $this->query_count,
                $total_time,
                $is_mobile ? 'mobile' : 'desktop'
            ));
            
            // Logar queries lentas
            if (!empty($this->slow_queries)) {
                foreach ($this->slow_queries as $slow_query) {
                    error_log(sprintf(
                        'Upgram Query Logger: Query lenta (%.2fms) [%s] - %s',
                        $slow_query['time'],
                        $slow_query['is_mobile'] ? 'mobile' : 'desktop',
                        $slow_query['query']
                    ));
                }
            }
        }
    }
    
    /**
     * Priorizar renderização - Deferir recursos não críticos
     */
    public function prioritize_renderization() {
        global $wp_scripts, $wp_styles;
        
        // Lista de scripts críticos que NÃO devem ser deferidos
        $critical_scripts = array(
            'jquery',
            'jquery-core',
            'jquery-migrate',
            'upgram-script', // Script principal do plugin
        );
        
        // Lista de scripts que devem ser deferidos (não críticos)
        $non_critical_patterns = array(
            'free-likes',
            'instagram-free-followers',
            'instagram-download',
            'free-views',
            'analytics',
            'gtag',
            'facebook',
            'chat',
            'popup',
            'slider',
            'carousel'
        );
        
        // Deferir scripts não críticos
        if (!empty($wp_scripts->queue)) {
            foreach ($wp_scripts->queue as $handle) {
                if (!isset($wp_scripts->registered[$handle])) {
                    continue;
                }
                
                $script = $wp_scripts->registered[$handle];
                
                // Pular scripts críticos
                if (in_array($handle, $critical_scripts)) {
                    continue;
                }
                
                // Verificar se é script não crítico
                $is_non_critical = false;
                foreach ($non_critical_patterns as $pattern) {
                    if (stripos($handle, $pattern) !== false || 
                        (!empty($script->src) && stripos($script->src, $pattern) !== false)) {
                        $is_non_critical = true;
                        break;
                    }
                }
                
                // Se for não crítico e não tiver defer/async, adicionar defer
                if ($is_non_critical && !empty($script->src)) {
                    // Verificar se já tem defer/async
                    $has_defer = isset($script->extra['defer']) || 
                                 (isset($wp_scripts->registered[$handle]->extra['defer']) && $wp_scripts->registered[$handle]->extra['defer']);
                    
                    if (!$has_defer) {
                        $wp_scripts->add_data($handle, 'defer', true);
                    }
                }
            }
        }
        
        // Adicionar filtro para modificar tags de script
        add_filter('script_loader_tag', array($this, 'add_defer_to_non_critical_scripts'), 10, 3);
    }
    
    /**
     * Adicionar defer a scripts não críticos
     */
    public function add_defer_to_non_critical_scripts($tag, $handle, $src) {
        global $wp_scripts;
        
        if (!isset($wp_scripts->registered[$handle])) {
            return $tag;
        }
        
        // Verificar se script deve ter defer
        $defer = $wp_scripts->get_data($handle, 'defer');
        
        if ($defer) {
            // Se já tem defer, não fazer nada
            if (strpos($tag, ' defer') === false && strpos($tag, " defer='defer'") === false) {
                $tag = str_replace('></script>', ' defer></script>', $tag);
                $tag = str_replace("'></script>", "' defer></script>", $tag);
                $tag = str_replace('"></script>', '" defer></script>', $tag);
            }
        }
        
        return $tag;
    }
    
    /**
     * Melhorar atributos de lazy loading
     */
    public function improve_lazy_loading_attributes($attr, $attachment, $size) {
        // Garantir que loading="lazy" está presente
        if (!isset($attr['loading'])) {
            $attr['loading'] = 'lazy';
        }
        
        // Adicionar decoding="async" para melhor performance
        if (!isset($attr['decoding'])) {
            $attr['decoding'] = 'async';
        }
        
        // Adicionar fetchpriority="low" para imagens abaixo do fold
        // (exceto se for a primeira imagem do post)
        if (!isset($attr['fetchpriority'])) {
            // Verificar se é imagem importante (primeira do post)
            static $image_count = 0;
            $image_count++;
            
            if ($image_count > 1) {
                $attr['fetchpriority'] = 'low';
            }
        }
        
        return $attr;
    }
}

