<?php
/**
 * Complete Site Optimization Service
 * Handles performance, SEO, and optimization for all pages.
 *
 * @package StockGuardianPro
 */

declare(strict_types=1);

namespace StockGuardianPro\LowStock\Services;

use StockGuardianPro\LowStock\Plugin;

\defined('ABSPATH') || exit;

final class OptimizationService implements ServiceInterface
{
    private Plugin $plugin;

    public function __construct(Plugin $plugin)
    {
        $this->plugin = $plugin;
    }

    public function register(): void
    {
        // Performance optimizations
        add_action('init', [$this, 'setup_performance_optimizations']);
        add_action('wp_enqueue_scripts', [$this, 'optimize_scripts'], 99);
        add_action('wp_head', [$this, 'add_preconnect_prefetch'], 1);
        add_action('wp_head', [$this, 'add_resource_hints'], 2);
        add_filter('style_loader_tag', [$this, 'optimize_style_tags'], 10, 4);
        add_filter('script_loader_tag', [$this, 'optimize_script_tags'], 10, 3);
        add_filter('the_content', [$this, 'lazy_load_images'], 99);
        add_filter('wp_get_attachment_image_attributes', [$this, 'add_lazy_loading_attr'], 10, 3);
        
        // Headers optimization
        add_action('send_headers', [$this, 'add_performance_headers']);
        
        // Output optimization
        add_action('template_redirect', [$this, 'start_output_buffering'], 1);
        
        // Database optimizations
        add_action('init', [$this, 'setup_database_optimizations']);
        
        // Remove query strings from static resources
        add_filter('script_loader_src', [$this, 'remove_query_strings'], 15, 1);
        add_filter('style_loader_src', [$this, 'remove_query_strings'], 15, 1);
        
        // Disable emoji scripts (performance)
        add_action('init', [$this, 'disable_emoji_scripts']);
        
        // Optimize database queries
        add_action('pre_get_posts', [$this, 'optimize_queries']);
    }

    public function setup_performance_optimizations(): void
    {
        // Remove unnecessary WordPress features
        remove_action('wp_head', 'wp_generator');
        remove_action('wp_head', 'wlwmanifest_link');
        remove_action('wp_head', 'rsd_link');
        remove_action('wp_head', 'wp_shortlink_wp_head');
        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
        remove_action('wp_head', 'feed_links', 2);
        remove_action('wp_head', 'feed_links_extra', 3);
    }

    public function optimize_scripts(): void
    {
        // Defer non-critical scripts
        add_filter('script_loader_tag', function ($tag, $handle) {
            $defer_scripts = [];
            
            if (in_array($handle, $defer_scripts, true)) {
                $tag = str_replace(' src', ' defer src', $tag);
            }
            
            return $tag;
        }, 10, 2);
    }

    public function add_preconnect_prefetch(): void
    {
        // Preconnect to external domains
        $domains = [
            'https://fonts.googleapis.com',
            'https://fonts.gstatic.com',
        ];

        foreach ($domains as $domain) {
            echo '<link rel="preconnect" href="' . esc_url($domain) . '" crossorigin>' . "\n";
        }

        // DNS prefetch for common resources
        $prefetch_domains = [
            'https://www.google-analytics.com',
            'https://www.googletagmanager.com',
        ];

        foreach ($prefetch_domains as $domain) {
            echo '<link rel="dns-prefetch" href="' . esc_url($domain) . '">' . "\n";
        }
    }

    public function add_resource_hints(): void
    {
        // Add preload for critical resources
        $critical_fonts = [
            'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap',
        ];

        foreach ($critical_fonts as $resource) {
            echo '<link rel="preload" href="' . esc_url($resource) . '" as="style" crossorigin>' . "\n";
        }
    }

    public function optimize_style_tags(string $tag, string $handle, string $href, string $media): string
    {
        // Add media attribute if missing
        if (strpos($tag, 'media=') === false) {
            $tag = str_replace('rel=\'stylesheet\'', 'rel=\'stylesheet\' media=\'all\'', $tag);
        }

        // Add crossorigin for Google Fonts
        if (strpos($href, 'fonts.googleapis.com') !== false || strpos($href, 'fonts.gstatic.com') !== false) {
            $tag = str_replace('>', ' crossorigin>', $tag);
        }

        return $tag;
    }

    public function optimize_script_tags(string $tag, string $handle, string $src): string
    {
        // Add defer to non-critical scripts (except jQuery and essential)
        $critical_scripts = ['jquery', 'jquery-core', 'jquery-migrate', 'wp-embed'];
        
        if (!in_array($handle, $critical_scripts, true)) {
            // Check if already has defer or async
            if (strpos($tag, 'defer') === false && strpos($tag, 'async') === false) {
                $tag = str_replace(' src', ' defer src', $tag);
            }
        }

        return $tag;
    }

    public function lazy_load_images(string $content): string
    {
        // Skip for admin and feeds
        if (is_admin() || is_feed()) {
            return $content;
        }

        // Replace img tags with lazy loading
        $content = preg_replace_callback(
            '/<img([^>]+?)(?:src=["\']([^"\']+)["\'])([^>]*?)>/i',
            function ($matches) {
                $before_src = $matches[1] ?? '';
                $src = $matches[2] ?? '';
                $after_src = $matches[3] ?? '';

                // Skip if already has loading attribute
                if (strpos($before_src . $after_src, 'loading=') !== false) {
                    return $matches[0];
                }

                // Skip if is in critical above-the-fold area (first 3 images)
                static $image_count = 0;
                $image_count++;
                if ($image_count <= 3) {
                    return $matches[0];
                }

                // Add lazy loading
                $new_tag = '<img' . $before_src . 'src="' . esc_url($src) . '"' . $after_src . ' loading="lazy" decoding="async">';
                return $new_tag;
            },
            $content
        );

        return $content;
    }

    public function add_lazy_loading_attr(array $attr, \WP_Post $attachment, string|array $size): array
    {
        // Add lazy loading to attachment images
        static $attachment_count = 0;
        $attachment_count++;
        
        if ($attachment_count > 3) {
            $attr['loading'] = 'lazy';
            $attr['decoding'] = 'async';
        }

        return $attr;
    }

    public function add_performance_headers(): void
    {
        // Add cache control headers
        if (!headers_sent()) {
            // Browser caching (1 year for static assets)
            if (is_admin() || wp_doing_ajax() || wp_doing_cron()) {
                return;
            }

            // Cache control for HTML
            header('Cache-Control: public, max-age=3600, must-revalidate');
            
            // X-Content-Type-Options
            header('X-Content-Type-Options: nosniff');
            
            // X-Frame-Options
            header('X-Frame-Options: SAMEORIGIN');
            
            // Referrer Policy
            header('Referrer-Policy: strict-origin-when-cross-origin');
            
            // Permissions Policy
            header('Permissions-Policy: geolocation=(), microphone=(), camera=()');
        }
    }

    public function start_output_buffering(): void
    {
        if (is_admin() || wp_doing_ajax() || wp_doing_cron() || (defined('DOING_CRON') && DOING_CRON)) {
            return;
        }

        // Only buffer if not already buffering
        if (ob_get_level() === 0) {
            ob_start([$this, 'optimize_output']);
        }
    }

    public function optimize_output(string $buffer): string
    {
        // Only optimize HTML output (not JSON, XML, etc.)
        if (stripos($buffer, '<!DOCTYPE') === false && stripos($buffer, '<html') === false) {
            return $buffer;
        }

        // Preserve critical sections first
        $preserved = [];
        $placeholders = [];
        
        // Preserve script, style, pre, code, textarea content
        $buffer = preg_replace_callback(
            '/<(script|style|pre|code|textarea)[^>]*>(.*?)<\/\1>/is',
            function ($matches) use (&$preserved, &$placeholders) {
                $placeholder = '<!--PRESERVED_' . count($preserved) . '-->';
                $preserved[] = $matches[0];
                $placeholders[] = $placeholder;
                return $placeholder;
            },
            $buffer
        );

        // Remove HTML comments (except conditional comments and preserved)
        $buffer = preg_replace('/<!--(?!\s*(?:\[if [^\]]+]|<!|>|PRESERVED_))(?:(?!-->).)*-->/s', '', $buffer);
        
        // Remove whitespace between tags
        $buffer = preg_replace('/>\s+</', '><', $buffer);
        
        // Remove extra whitespace and newlines (but keep single spaces)
        $buffer = preg_replace('/[ \t]+/', ' ', $buffer);
        $buffer = preg_replace('/\n\s*\n/', "\n", $buffer);
        
        // Restore preserved content
        foreach ($placeholders as $index => $placeholder) {
            if (isset($preserved[$index])) {
                $buffer = str_replace($placeholder, $preserved[$index], $buffer);
            }
        }

        // Minify inline CSS (basic)
        $buffer = preg_replace_callback(
            '/<style[^>]*>(.*?)<\/style>/is',
            function ($matches) {
                $css = $matches[1];
                // Remove comments
                $css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
                // Remove whitespace
                $css = preg_replace('/\s+/', ' ', $css);
                $css = str_replace([' {', '{ ', ' }', '} ', ' :', ': ', ' ;', '; ', ' ,', ', '], ['{', '{', '}', '}', ':', ':', ';', ';', ',', ','], $css);
                $css = trim($css);
                return '<style>' . $css . '</style>';
            },
            $buffer
        );

        // Minify inline JavaScript (basic - careful with syntax)
        $buffer = preg_replace_callback(
            '/<script[^>]*>(.*?)<\/script>/is',
            function ($matches) {
                $js = $matches[1];
                // Only minify if not external script
                if (strpos($matches[0], 'src=') !== false) {
                    return $matches[0];
                }
                // Remove single-line comments (careful!)
                $js = preg_replace('/\/\/.*$/m', '', $js);
                // Remove multi-line comments
                $js = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $js);
                // Remove extra whitespace
                $js = preg_replace('/\s+/', ' ', $js);
                $js = trim($js);
                return '<script>' . $js . '</script>';
            },
            $buffer
        );
        
        return $buffer;
    }

    public function setup_database_optimizations(): void
    {
        // Use transients for expensive queries
        // This is handled individually in services that need caching
    }

    public function remove_query_strings(string $src): string
    {
        if (strpos($src, '?ver=') !== false) {
            $src = remove_query_arg('ver', $src);
        }
        
        // Keep version as filename parameter (better for caching)
        return $src;
    }

    public function disable_emoji_scripts(): void
    {
        // Remove emoji scripts (performance improvement)
        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');
        
        // Remove from TinyMCE
        add_filter('tiny_mce_plugins', function ($plugins) {
            if (is_array($plugins)) {
                return array_diff($plugins, ['wpemoji']);
            }
            return $plugins;
        });
    }

    public function optimize_queries(\WP_Query $query): void
    {
        // Optimize main queries
        if (!is_admin() && $query->is_main_query()) {
            // Limit revisions in queries
            if ($query->is_single() || $query->is_page()) {
                $query->set('no_found_rows', true);
                $query->set('update_post_meta_cache', false);
                $query->set('update_post_term_cache', false);
            }
        }
    }
}

