<?php

/**
 * CSS Optimization REST API Controller
 *
 * Handles REST API endpoints for CSS optimization features
 *
 * @package ProRank\SEO\Core\RestApi
 * @since   1.0.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Core\RestApi;

use ProRank\SEO\Core\RestApi\BaseController;
use ProRank\SEO\Modules\Performance\CssOptimizeModule;
use ProRank\SEO\Core\Optimization\CSS\CssMinifierService;
use ProRank\SEO\Core\Optimization\CSS\ExternalAssetCacheService;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

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


/**
 * CssOptimizationController class
 */


class CssOptimizationController extends BaseController {
    
    /**
     * CSS Optimize module instance
     *
     * @var CssOptimizeModule|null
     */
    private ?CssOptimizeModule $css_module = null;
    
    /**
     * Constructor
     */
    public function __construct() {
        $this->namespace = 'prorank/v1';
        $this->rest_base = 'performance/css';
    }
    
    /**
     * Register routes
     *
     * @return void
     */
    public function register_routes(): void {
        // Get cache statistics
        register_rest_route($this->namespace, '/' . $this->rest_base . '-cache/stats', [
            [
                'methods' => \WP_REST_Server::READABLE,
                'callback' => [$this, 'get_cache_stats'],
                'permission_callback' => [$this, 'get_items_permissions_check'],
            ],
        ]);
        
        // Clear cache
        register_rest_route($this->namespace, '/' . $this->rest_base . '-cache/clear', [
            [
                'methods' => \WP_REST_Server::CREATABLE,
                'callback' => [$this, 'clear_cache'],
                'permission_callback' => [$this, 'create_item_permissions_check'],
                'args' => [
                    'type' => [
                        'description' => 'Type of cache to clear',
                        'type' => 'string',
                        'default' => 'all',
                        'enum' => ['all', 'minified', 'external'],
                    ],
                ],
            ],
        ]);
        
        // Preview CSS minification
        register_rest_route($this->namespace, '/' . $this->rest_base . '/preview', [
            [
                'methods' => \WP_REST_Server::CREATABLE,
                'callback' => [$this, 'preview_minification'],
                'permission_callback' => [$this, 'get_items_permissions_check'],
                'args' => [
                    'url' => [
                        'description' => 'CSS file URL to preview',
                        'type' => 'string',
                        'required' => true,
                        'validate_callback' => function($param) {
                            return filter_var($param, FILTER_VALIDATE_URL) !== false;
                        },
                    ],
                ],
            ],
        ]);
        
        // Test CSS optimization
        register_rest_route($this->namespace, '/' . $this->rest_base . '-test', [
            [
                'methods' => \WP_REST_Server::CREATABLE,
                'callback' => [$this, 'test_css_optimization'],
                'permission_callback' => [$this, 'create_item_permissions_check'],
            ],
        ]);
        
        // Get excluded files
        register_rest_route($this->namespace, '/' . $this->rest_base . '/excluded-files', [
            [
                'methods' => \WP_REST_Server::READABLE,
                'callback' => [$this, 'get_excluded_files'],
                'permission_callback' => [$this, 'get_items_permissions_check'],
            ],
        ]);
        
        // Test CSS optimization on current page
        register_rest_route($this->namespace, '/' . $this->rest_base . '/test', [
            [
                'methods' => \WP_REST_Server::CREATABLE,
                'callback' => [$this, 'test_optimization'],
                'permission_callback' => [$this, 'create_item_permissions_check'],
                'args' => [
                    'url' => [
                        'description' => 'Page URL to test',
                        'type' => 'string',
                        'required' => true,
                        'validate_callback' => function($param) {
                            return filter_var($param, FILTER_VALIDATE_URL) !== false;
                        },
                    ],
                ],
            ],
        ]);
    }
    
    /**
     * Get cache statistics
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function get_cache_stats(WP_REST_Request $request) {
        try {
            $css_module = $this->get_css_module();
            
            if (!$css_module) {
                return new WP_Error(
                    'module_not_found',
                    __('CSS optimization module not found', 'prorank-seo'),
                    ['status' => 404]
                );
            }
            
            $stats = $css_module->get_cache_stats();
            
            return new WP_REST_Response([
                'success' => true,
                'data' => $stats,
            ], 200);
        } catch (\Exception $e) {
            return new WP_Error(
                'cache_stats_error',
                $e->getMessage(),
                ['status' => 500]
            );
        }
    }
    
    /**
     * Clear CSS cache
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function clear_cache(WP_REST_Request $request) {
        try {
            $type = $request->get_param('type');
            $css_module = $this->get_css_module();
            
            if (!$css_module) {
                return new WP_Error(
                    'module_not_found',
                    __('CSS optimization module not found', 'prorank-seo'),
                    ['status' => 404]
                );
            }
            
            // Clear cache based on type
            $css_module->clear_css_cache();
            
            // Get updated stats
            $stats = $css_module->get_cache_stats();
            
            // Log the action
            do_action('prorank_log_action', 'css_cache_cleared', [
                'type' => $type,
                'user_id' => get_current_user_id(),
            ]);
            
            return new WP_REST_Response([
                'success' => true,
                'message' => __('CSS cache cleared successfully', 'prorank-seo'),
                'data' => [
                    'type' => $type,
                    'stats' => $stats,
                ],
            ], 200);
        } catch (\Exception $e) {
            return new WP_Error(
                'cache_clear_error',
                $e->getMessage(),
                ['status' => 500]
            );
        }
    }
    
    /**
     * Preview CSS minification
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function preview_minification(WP_REST_Request $request) {
        try {
            $url = $request->get_param('url');
            
            // Convert URL to file path
            $file_path = $this->url_to_path($url);
            
            if (!$file_path || !file_exists($file_path)) {
                return new WP_Error(
                    'file_not_found',
                    __('CSS file not found', 'prorank-seo'),
                    ['status' => 404]
                );
            }
            
            // Read original content
            $original_content = file_get_contents($file_path);
            if ($original_content === false) {
                return new WP_Error(
                    'file_read_error',
                    __('Could not read CSS file', 'prorank-seo'),
                    ['status' => 500]
                );
            }
            
            // Create minifier service
            $minifier = new CssMinifierService();
            
            // Minify content
            $minified_content = $minifier->minify($original_content, $file_path);
            
            // Calculate statistics
            $original_size = strlen($original_content);
            $minified_size = strlen($minified_content);
            $compression_ratio = round((1 - $minified_size / $original_size) * 100, 2);
            
            return new WP_REST_Response([
                'success' => true,
                'data' => [
                    'original' => [
                        'size' => $original_size,
                        'size_formatted' => size_format($original_size),
                        'preview' => substr($original_content, 0, 500) . '...',
                    ],
                    'minified' => [
                        'size' => $minified_size,
                        'size_formatted' => size_format($minified_size),
                        'preview' => substr($minified_content, 0, 500) . '...',
                    ],
                    'compression_ratio' => $compression_ratio,
                ],
            ], 200);
        } catch (\Exception $e) {
            return new WP_Error(
                'preview_error',
                $e->getMessage(),
                ['status' => 500]
            );
        }
    }
    
    /**
     * Test CSS optimization
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function test_css_optimization(WP_REST_Request $request) {
        try {
            // Get homepage URL
            $test_url = home_url('/');
            
            // Fetch the page
            $response = wp_remote_get($test_url);
            if (is_wp_error($response)) {
                throw new \Exception('Failed to fetch homepage');
            }
            
            $html = wp_remote_retrieve_body($response);
            
            // Extract CSS files from HTML
            preg_match_all('/<link[^>]+href=[\'"]([^\'"]+\.css[^\'"]*)[\'"][^>]*>/i', $html, $css_matches);
            
            $original_size = 0;
            $optimized_size = 0;
            
            foreach ($css_matches[1] as $css_url) {
                // Make URL absolute
                if (strpos($css_url, 'http') !== 0) {
                    $css_url = home_url($css_url);
                }
                
                // Fetch CSS content
                $css_response = wp_remote_get($css_url);
                if (!is_wp_error($css_response)) {
                    $css_content = wp_remote_retrieve_body($css_response);
                    $original_size += strlen($css_content);
                    
                    // Simulate minification
                    $minified = preg_replace('/\s+/', ' ', $css_content);
                    $minified = preg_replace('/\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\//', '', $minified);
                    $optimized_size += strlen($minified);
                }
            }
            
            $savings_percent = $original_size > 0 ? round((1 - $optimized_size / $original_size) * 100, 2) : 0;
            
            return new WP_REST_Response([
                'success' => true,
                'original_size' => size_format($original_size),
                'optimized_size' => size_format($optimized_size),
                'savings_percent' => $savings_percent,
                'report_url' => admin_url('admin.php?page=prorank-performance')
            ], 200);
            
        } catch (\Exception $e) {
            return new WP_Error(
                'test_error',
                $e->getMessage(),
                ['status' => 500]
            );
        }
    }
    
    /**
     * Get excluded CSS files
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function get_excluded_files(WP_REST_Request $request) {
        try {
            // Get all enqueued styles
            global $wp_styles;
            
            if (!$wp_styles) {
                return new WP_REST_Response([
                    'success' => true,
                    'data' => [],
                ], 200);
            }
            
            $styles = [];
            
            foreach ($wp_styles->registered as $handle => $style) {
                if (empty($style->src)) {
                    continue;
                }
                
                $styles[] = [
                    'handle' => $handle,
                    'src' => $style->src,
                    'deps' => $style->deps,
                    'media' => $style->args ?: 'all',
                ];
            }
            
            return new WP_REST_Response([
                'success' => true,
                'data' => $styles,
            ], 200);
        } catch (\Exception $e) {
            return new WP_Error(
                'excluded_files_error',
                $e->getMessage(),
                ['status' => 500]
            );
        }
    }
    
    /**
     * Test CSS optimization on a page
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function test_optimization(WP_REST_Request $request) {
        try {
            $url = $request->get_param('url');
            
            // Fetch the page content
            $response = wp_remote_get($url, [
                'timeout' => 30,
                'user-agent' => 'ProRank SEO CSS Optimization Test',
            ]);
            
            if (is_wp_error($response)) {
                return new WP_Error(
                    'fetch_error',
                    $response->get_error_message(),
                    ['status' => 500]
                );
            }
            
            $html = wp_remote_retrieve_body($response);
            
            // Extract CSS files from HTML
            preg_match_all('/<link[^>]+rel=["\']stylesheet["\'][^>]+href=["\']([^"\']+)["\'][^>]*>/i', $html, $matches);
            
            $css_files = [];
            $total_original_size = 0;
            $total_optimized_size = 0;
            
            foreach ($matches[1] as $css_url) {
                // Skip already minified files
                if (strpos($css_url, '.min.css') !== false) {
                    continue;
                }
                
                // Get file info
                $file_response = wp_remote_head($css_url);
                
                if (!is_wp_error($file_response)) {
                    $headers = wp_remote_retrieve_headers($file_response);
                    $size = isset($headers['content-length']) ? (int) $headers['content-length'] : 0;
                    
                    if ($size > 0) {
                        $total_original_size += $size;
                        
                        // Estimate optimized size (30% reduction average)
                        $optimized_size = (int) ($size * 0.7);
                        $total_optimized_size += $optimized_size;
                        
                        $css_files[] = [
                            'url' => $css_url,
                            'original_size' => $size,
                            'estimated_optimized_size' => $optimized_size,
                            'potential_savings' => $size - $optimized_size,
                        ];
                    }
                }
            }
            
            return new WP_REST_Response([
                'success' => true,
                'data' => [
                    'page_url' => $url,
                    'css_files_count' => count($css_files),
                    'css_files' => $css_files,
                    'total_original_size' => $total_original_size,
                    'total_original_size_formatted' => size_format($total_original_size),
                    'total_optimized_size' => $total_optimized_size,
                    'total_optimized_size_formatted' => size_format($total_optimized_size),
                    'potential_savings' => $total_original_size - $total_optimized_size,
                    'potential_savings_formatted' => size_format($total_original_size - $total_optimized_size),
                    'potential_reduction' => $total_original_size > 0 
                        ? round((1 - $total_optimized_size / $total_original_size) * 100, 2) 
                        : 0,
                ],
            ], 200);
        } catch (\Exception $e) {
            return new WP_Error(
                'test_error',
                $e->getMessage(),
                ['status' => 500]
            );
        }
    }
    
    /**
     * Get CSS module instance
     *
     * @return CssOptimizeModule|null
     */
    private function get_css_module(): ?CssOptimizeModule {
        if ($this->css_module === null) {
            $plugin = \ProRank\SEO\Plugin::get_instance();
            $module_manager = $plugin->get_module_manager();
            
            if ($module_manager) {
                $this->css_module = $module_manager->get_module('css_opt');
            }
        }
        
        return $this->css_module;
    }
    
    /**
     * Convert URL to file path
     *
     * @param string $url URL to convert
     * @return string|null File path or null
     */
    private function url_to_path(string $url): ?string {
        // Remove query string
        $url = strtok($url, '?');
        
        // Get WordPress directories
        $content_url = content_url();
        $content_dir = WP_CONTENT_DIR;
        
        // Check if URL is within content directory
        if (strpos($url, $content_url) === 0) {
            $relative = substr($url, strlen($content_url));
            return $content_dir . $relative;
        }
        
        return null;
    }
}
