<?php

/**
 * Browser Cache REST API Endpoint
 *
 * Handles browser cache configuration and testing
 *
 * @package ProRank\SEO\Api\Endpoints
 * @since   1.0.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Api\Endpoints;

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use ProRank\SEO\Modules\Performance\BrowserCacheModule;

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


/**
 * Browser Cache endpoint class
 */


class BrowserCacheEndpoint {
    
    /**
     * Browser cache module instance
     *
     * @var BrowserCacheModule
     */
    private BrowserCacheModule $browser_cache;
    
    /**
     * Constructor
     */
    public function __construct() {
        $this->browser_cache = new BrowserCacheModule();
    }
    
    /**
     * Register routes
     */
    public function register_routes(): void {
        register_rest_route('prorank-seo/v1', '/browser-cache/settings', [
            [
                'methods' => 'GET',
                'callback' => [$this, 'get_settings'],
                'permission_callback' => [$this, 'check_permission'],
            ],
            [
                'methods' => 'POST',
                'callback' => [$this, 'update_settings'],
                'permission_callback' => [$this, 'check_permission'],
                'args' => $this->get_settings_args(),
            ],
        ]);
        
        register_rest_route('prorank-seo/v1', '/browser-cache/test', [
            'methods' => 'POST',
            'callback' => [$this, 'test_configuration'],
            'permission_callback' => [$this, 'check_permission'],
        ]);
        
        register_rest_route('prorank-seo/v1', '/browser-cache/htaccess', [
            'methods' => 'GET',
            'callback' => [$this, 'get_htaccess_status'],
            'permission_callback' => [$this, 'check_permission'],
        ]);
        
        register_rest_route('prorank-seo/v1', '/browser-cache/regenerate', [
            'methods' => 'POST',
            'callback' => [$this, 'regenerate_htaccess'],
            'permission_callback' => [$this, 'check_permission'],
        ]);
    }
    
    /**
     * Check permission
     */
    public function check_permission(): bool {
        return current_user_can('manage_options');
    }
    
    /**
     * Get browser cache settings
     */
    public function get_settings(WP_REST_Request $request): WP_REST_Response {
        $settings = get_option('prorank_browser_cache_settings', []);
        
        // Add default values
        $defaults = [
            'enabled' => false,
            'cache_images' => 31536000, // 1 year
            'cache_css' => 31536000,
            'cache_js' => 31536000,
            'cache_fonts' => 31536000,
            'cache_html' => 3600, // 1 hour
            'cache_xml' => 3600,
            'cache_json' => 3600,
            'cache_pdf' => 2592000, // 30 days
            'cache_media' => 2592000,
            'immutable_images' => true,
            'immutable_css' => true,
            'immutable_js' => true,
            'immutable_fonts' => true,
            'etag_enabled' => false,
            'cors_fonts' => true,
            'security_headers' => true,
            'enable_compression' => true,
        ];
        
        $settings = wp_parse_args($settings, $defaults);
        
        return new WP_REST_Response([
            'success' => true,
            'settings' => $settings,
        ]);
    }
    
    /**
     * Update browser cache settings
     */
    public function update_settings(WP_REST_Request $request): WP_REST_Response {
        $settings = $request->get_param('settings');
        
        if (!is_array($settings)) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('Invalid settings format', 'prorank-seo'),
            ], 400);
        }
        
        // Map frontend keys to backend keys
        $mapped_settings = [
            'enabled' => !empty($settings['browser_cache_enabled']),
            'cache_images' => intval($settings['browser_cache_images'] ?? 31536000),
            'cache_css' => intval($settings['browser_cache_css'] ?? 31536000),
            'cache_js' => intval($settings['browser_cache_js'] ?? 31536000),
            'cache_fonts' => intval($settings['browser_cache_fonts'] ?? 31536000),
            'cache_html' => intval($settings['browser_cache_html'] ?? 3600),
            'cache_xml' => intval($settings['browser_cache_xml'] ?? 3600),
            'cache_json' => intval($settings['browser_cache_json'] ?? 3600),
            'cache_pdf' => intval($settings['browser_cache_pdf'] ?? 2592000),
            'cache_media' => intval($settings['browser_cache_media'] ?? 2592000),
            'immutable_images' => !empty($settings['browser_cache_immutable']),
            'immutable_css' => !empty($settings['browser_cache_immutable']),
            'immutable_js' => !empty($settings['browser_cache_immutable']),
            'immutable_fonts' => !empty($settings['browser_cache_immutable']),
            'etag_enabled' => !empty($settings['browser_cache_etag']),
            'cors_fonts' => !empty($settings['browser_cache_cors_fonts']),
            'security_headers' => !empty($settings['browser_cache_security_headers']),
            'enable_compression' => !empty($settings['browser_cache_gzip']) || !empty($settings['browser_cache_brotli']),
        ];
        
        // Save settings
        update_option('prorank_browser_cache_settings', $mapped_settings);
        
        // Update .htaccess
        $htaccess_updated = false;
        if ($mapped_settings['enabled']) {
            $htaccess_updated = $this->browser_cache->update_htaccess();
        } else {
            $htaccess_updated = $this->browser_cache->remove_htaccess_rules();
        }
        
        return new WP_REST_Response([
            'success' => true,
            'message' => __('Browser cache settings updated', 'prorank-seo'),
            'htaccess_updated' => $htaccess_updated,
        ]);
    }
    
    /**
     * Test browser cache configuration
     */
    public function test_configuration(WP_REST_Request $request): WP_REST_Response {
        $results = [];
        $server_software = strtolower((string) ($_SERVER['SERVER_SOFTWARE'] ?? ''));
        $is_nginx = strpos($server_software, 'nginx') !== false;
        $results['server'] = $is_nginx ? 'nginx' : 'apache_or_other';
        
        // Check if .htaccess is writable
        $htaccess_path = prorank_home_file_path('.htaccess');
        $results['htaccess_writable'] = wp_is_writable($htaccess_path) || (!file_exists($htaccess_path) && wp_is_writable(prorank_get_home_path()));
        
        // Check for Apache modules
        if (function_exists('apache_get_modules')) {
            $modules = apache_get_modules();
            $results['mod_expires'] = in_array('mod_expires', $modules);
            $results['mod_headers'] = in_array('mod_headers', $modules);
            $results['mod_deflate'] = in_array('mod_deflate', $modules);
            $results['mod_brotli'] = in_array('mod_brotli', $modules);
        } else {
            // Can't detect modules, assume they might be available
            $results['modules_detection'] = 'unavailable';
        }
        
        // Check if rules are present in .htaccess
        if (file_exists($htaccess_path)) {
            $htaccess_content = file_get_contents($htaccess_path);
            $results['rules_present'] = strpos($htaccess_content, '# BEGIN ProRank SEO Browser Cache') !== false;
        } else {
            $results['rules_present'] = false;
        }
        
        // Test a sample resource with cache headers
        $test_url = plugins_url('assets/images/logo.png', PRORANK_PLUGIN_FILE);
        $response = wp_remote_head($test_url, ['timeout' => 5]);
        
        if (!is_wp_error($response)) {
            $headers = wp_remote_retrieve_headers($response);
            $results['cache_control'] = $headers['cache-control'] ?? 'not set';
            $results['expires'] = $headers['expires'] ?? 'not set';
            $results['etag'] = $headers['etag'] ?? 'not set';
        }
        
        // Generate status message
        $message = '';
        if ($is_nginx) {
            $message .= __('ℹ️ Nginx detected: .htaccess rules do not apply. Use the Nginx config snippet in ProRank settings.', 'prorank-seo') . "\n";
        }
        if ($results['htaccess_writable']) {
            $message .= __('✅ .htaccess is writable', 'prorank-seo') . "\n";
        } else {
            $message .= __('❌ .htaccess is not writable', 'prorank-seo') . "\n";
        }
        
        if ($results['rules_present']) {
            $message .= __('✅ Browser cache rules are present', 'prorank-seo') . "\n";
        } else {
            $message .= __('⚠️ Browser cache rules not found', 'prorank-seo') . "\n";
        }
        
        if (isset($results['mod_expires']) && $results['mod_expires']) {
            $message .= __('✅ mod_expires is enabled', 'prorank-seo') . "\n";
        }
        
        if (isset($results['mod_headers']) && $results['mod_headers']) {
            $message .= __('✅ mod_headers is enabled', 'prorank-seo') . "\n";
        }
        
        return new WP_REST_Response([
            'success' => true,
            'message' => $message,
            'results' => $results,
        ]);
    }
    
    /**
     * Get .htaccess status
     */
    public function get_htaccess_status(WP_REST_Request $request): WP_REST_Response {
        $htaccess_path = prorank_home_file_path('.htaccess');
        
        $status = [
            'exists' => file_exists($htaccess_path),
            'writable' => wp_is_writable($htaccess_path) || (!file_exists($htaccess_path) && wp_is_writable(prorank_get_home_path())),
            'rules_present' => false,
            'content_preview' => '',
        ];
        
        if ($status['exists']) {
            $content = file_get_contents($htaccess_path);
            $status['rules_present'] = strpos($content, '# BEGIN ProRank SEO Browser Cache') !== false;
            
            // Extract ProRank rules for preview
            if ($status['rules_present']) {
                $start = strpos($content, '# BEGIN ProRank SEO Browser Cache');
                $end = strpos($content, '# END ProRank SEO Browser Cache');
                if ($start !== false && $end !== false) {
                    $status['content_preview'] = substr($content, $start, $end - $start + strlen('# END ProRank SEO Browser Cache'));
                }
            }
        }
        
        return new WP_REST_Response([
            'success' => true,
            'status' => $status,
        ]);
    }
    
    /**
     * Regenerate .htaccess rules
     */
    public function regenerate_htaccess(WP_REST_Request $request): WP_REST_Response {
        $success = $this->browser_cache->update_htaccess();
        
        return new WP_REST_Response([
            'success' => $success,
            'message' => $success 
                ? __('Browser cache rules regenerated successfully', 'prorank-seo')
                : __('Failed to regenerate browser cache rules', 'prorank-seo'),
        ]);
    }
    
    /**
     * Get settings args for validation
     */
    private function get_settings_args(): array {
        return [
            'settings' => [
                'required' => true,
                'type' => 'object',
                'properties' => [
                    'browser_cache_enabled' => ['type' => 'boolean'],
                    'browser_cache_images' => ['type' => 'string'],
                    'browser_cache_css' => ['type' => 'string'],
                    'browser_cache_js' => ['type' => 'string'],
                    'browser_cache_fonts' => ['type' => 'string'],
                    'browser_cache_html' => ['type' => 'string'],
                    'browser_cache_media' => ['type' => 'string'],
                    'browser_cache_etag' => ['type' => 'boolean'],
                    'browser_cache_immutable' => ['type' => 'boolean'],
                    'browser_cache_gzip' => ['type' => 'boolean'],
                    'browser_cache_brotli' => ['type' => 'boolean'],
                    'browser_cache_cors_fonts' => ['type' => 'boolean'],
                    'browser_cache_security_headers' => ['type' => 'boolean'],
                ],
            ],
        ];
    }
}
