<?php

declare(strict_types=1);


/**
 * AJAX Handlers for ProRank SEO
 *
 * Handles all AJAX requests from the admin interface
 * Ensures all toggles and settings actually work
 *
 * @package ProRank\Admin
 * @since 3.0.0
 */

namespace ProRank\Admin;

use ProRank\Core\Cache\PageCacheManager;
use ProRank\Modules\Performance\ImageOptimizationModule;

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




class AjaxHandlers {

    /**
     * Initialize AJAX handlers
     */
    public function __construct() {
        // Universal settings handler
        add_action('wp_ajax_prorank_save_setting', [$this, 'handle_save_setting']);

        // Module management
        add_action('wp_ajax_prorank_toggle_module', [$this, 'handle_toggle_module']);

        // Cache management
        add_action('wp_ajax_prorank_cache_control', [$this, 'handle_cache_control']);
        add_action('wp_ajax_prorank_clear_cache', [$this, 'handle_clear_cache']);

        // Database optimization
        add_action('wp_ajax_prorank_optimize_database', [$this, 'handle_optimize_database']);

        // Image optimization
        add_action('wp_ajax_prorank_optimize_images', [$this, 'handle_optimize_images']);
    }

    /**
     * Universal setting save handler
     * Makes sure ALL toggles and settings actually save
     */
    public function handle_save_setting() {
        // Security check
        if (!check_ajax_referer('prorank_nonce', 'nonce', false)) {
            wp_send_json_error(['message' => __('Security check failed', 'prorank-seo')]);
            return;
        }

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Insufficient permissions', 'prorank-seo')]);
            return;
        }

        $setting = filter_input( INPUT_POST, 'setting', FILTER_UNSAFE_RAW );
        $setting = is_string( $setting ) ? sanitize_text_field( $setting ) : '';

        $raw_value = filter_input( INPUT_POST, 'value', FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY );
        if ( null === $raw_value || false === $raw_value ) {
            $raw_value = filter_input( INPUT_POST, 'value', FILTER_UNSAFE_RAW );
        }
        if ( null === $raw_value || false === $raw_value ) {
            $raw_value = '';
        }

        if ( is_array( $raw_value ) ) {
            $value = array_map( 'sanitize_text_field', $raw_value );
        } else {
            $value = sanitize_text_field( (string) $raw_value );
        }

        if (empty($setting)) {
            wp_send_json_error(['message' => __('Setting name required', 'prorank-seo')]);
            return;
        }

        // Handle boolean values
        if ($value === 'true' || $value === 'false') {
            $value = ($value === 'true');
        }

        // Save to database
        $option_name = 'prorank_' . $setting;
        update_option($option_name, $value);

        // Execute feature-specific actions
        $this->execute_feature_action($setting, $value);

        wp_send_json_success([
            'message' => __('Setting saved successfully', 'prorank-seo'),
            'setting' => $setting,
            'value' => $value
        ]);
    }

    /**
     * Handle module toggle
     */
    public function handle_toggle_module() {
        check_ajax_referer('prorank_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Insufficient permissions', 'prorank-seo')]);
            return;
        }

        $module_slug = prorank_get_post_var('module');
        $enabled = filter_var(prorank_get_post_var('enabled'), FILTER_VALIDATE_BOOLEAN);

        if (empty($module_slug)) {
            wp_send_json_error(['message' => __('Module slug required', 'prorank-seo')]);
            return;
        }

        // Get current modules
        $modules = get_option('prorank_modules', []);

        // Update module status
        $modules[$module_slug] = [
            'enabled' => $enabled,
            'updated_at' => current_time('mysql')
        ];

        update_option('prorank_modules', $modules);

        // Activate/deactivate module features
        if ($enabled) {
            $this->activate_module_features($module_slug);
        } else {
            $this->deactivate_module_features($module_slug);
        }

        wp_send_json_success([
            'message' => $enabled
                ? __('Module enabled successfully', 'prorank-seo')
                : __('Module disabled successfully', 'prorank-seo'),
            'module' => $module_slug,
            'enabled' => $enabled
        ]);
    }

    /**
     * Handle cache control
     */
    public function handle_cache_control() {
        check_ajax_referer('prorank_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Insufficient permissions', 'prorank-seo')]);
            return;
        }

        $action = prorank_get_post_var('cache_action');

        switch ($action) {
            case 'enable':
                $this->enable_page_cache();
                wp_send_json_success(['message' => __('Page cache enabled', 'prorank-seo')]);
                break;

            case 'disable':
                $this->disable_page_cache();
                wp_send_json_success(['message' => __('Page cache disabled', 'prorank-seo')]);
                break;

            case 'clear':
                $this->clear_page_cache();
                wp_send_json_success(['message' => __('Cache cleared successfully', 'prorank-seo')]);
                break;

            default:
                wp_send_json_error(['message' => __('Invalid cache action', 'prorank-seo')]);
        }
    }

    /**
     * Handle cache clearing
     */
    public function handle_clear_cache() {
        check_ajax_referer('prorank_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Insufficient permissions', 'prorank-seo')]);
            return;
        }

        $type = prorank_get_post_var('cache_type');
        if ($type === '') {
            $type = 'all';
        }

        try {
            $cleared = [];

            if ($type === 'all' || $type === 'page') {
                $this->clear_page_cache();
                $cleared[] = 'page';
            }

            if ($type === 'all' || $type === 'object') {
                wp_cache_flush();
                $cleared[] = 'object';
            }

            if ($type === 'all' || $type === 'transient') {
                $this->clear_transients();
                $cleared[] = 'transient';
            }

            wp_send_json_success([
                'message' => sprintf(
/* translators: %1$: value */
                    __('Cleared %1$s cache', 'prorank-seo'),
                    implode(', ', $cleared)
                ),
                'cleared' => $cleared
            ]);
        } catch (\Exception $e) {
            wp_send_json_error(['message' => $e->getMessage()]);
        }
    }

    /**
     * Handle database optimization
     */
    public function handle_optimize_database() {
        check_ajax_referer('prorank_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Insufficient permissions', 'prorank-seo')]);
            return;
        }

        global $wpdb;

        try {
            $optimized_tables = [];

            // Get all database tables
            $tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);

            foreach ($tables as $table) {
                $table_name = $table[0];

                // Only optimize WordPress tables
                if (strpos($table_name, $wpdb->prefix) === 0) {
                    $wpdb->query("OPTIMIZE TABLE `$table_name`");
                    $optimized_tables[] = $table_name;
                }
            }

            // Clean up options
            $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '%_transient_%'");

            // Clean up post meta
            $wpdb->query("DELETE pm FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE p.ID IS NULL");

            wp_send_json_success([
                'message' => sprintf(
/* translators: %1$: value */
                    __('Optimized %1$d tables', 'prorank-seo'),
                    count($optimized_tables)
                ),
                'tables' => $optimized_tables
            ]);
        } catch (\Exception $e) {
            wp_send_json_error(['message' => $e->getMessage()]);
        }
    }

    /**
     * Handle image optimization
     */
    public function handle_optimize_images() {
        check_ajax_referer('prorank_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Insufficient permissions', 'prorank-seo')]);
            return;
        }

        $image_id = intval(prorank_get_post_var('image_id'));

        if (!$image_id) {
            wp_send_json_error(['message' => __('Image ID required', 'prorank-seo')]);
            return;
        }

        try {
            $optimizer = new \ProRank\Core\ImageOptimizer();
            $result = $optimizer->optimize($image_id);

            if ($result['success']) {
                wp_send_json_success([
                    'message' => __('Image optimized successfully', 'prorank-seo'),
                    'saved' => $result['saved_bytes'],
                    'percentage' => $result['percentage']
                ]);
            } else {
                wp_send_json_error(['message' => $result['message']]);
            }
        } catch (\Exception $e) {
            wp_send_json_error(['message' => $e->getMessage()]);
        }
    }

    /**
     * Execute feature-specific actions when settings change
     */
    private function execute_feature_action($setting, $value) {
        switch ($setting) {
            case 'page_cache':
            case 'cache_enabled':
                if ($value) {
                    $this->enable_page_cache();
                } else {
                    $this->disable_page_cache();
                }
                break;

            case 'browser_cache_enabled':
                if ($value) {
                    $this->enable_browser_cache();
                } else {
                    $this->disable_browser_cache();
                }
                break;

            case 'gzip_compression':
                if ($value) {
                    $this->enable_gzip_compression();
                } else {
                    $this->disable_gzip_compression();
                }
                break;

            case 'lazy_load_images':
                if ($value) {
                    add_filter('wp_lazy_loading_enabled', '__return_true');
                } else {
                    add_filter('wp_lazy_loading_enabled', '__return_false');
                }
                break;
        }
    }

    /**
     * Enable page caching
     */
    private function enable_page_cache() {
        // Create cache directory if it doesn't exist
        $cache_dir = WP_CONTENT_DIR . '/cache/prorank/';
        if (!file_exists($cache_dir)) {
            wp_mkdir_p($cache_dir);
        }

        // Update .htaccess for caching rules
        $this->update_htaccess_cache_rules(true);

        update_option('prorank_page_cache_enabled', true);
    }

    /**
     * Disable page caching
     */
    private function disable_page_cache() {
        // Clear existing cache
        $this->clear_page_cache();

        // Remove .htaccess rules
        $this->update_htaccess_cache_rules(false);

        update_option('prorank_page_cache_enabled', false);
    }

    /**
     * Clear page cache
     */
    private function clear_page_cache() {
        $cache_dir = WP_CONTENT_DIR . '/cache/prorank/';

        if (file_exists($cache_dir)) {
            $this->delete_directory($cache_dir);
            wp_mkdir_p($cache_dir);
        }
    }

    /**
     * Clear transients
     */
    private function clear_transients() {
        global $wpdb;

        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '%_transient_%'");
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '%_site_transient_%'");
    }

    /**
     * Enable browser caching via .htaccess
     */
    private function enable_browser_cache() {
        $rules = $this->get_browser_cache_rules();
        $this->insert_htaccess_rules($rules, 'ProRank Browser Cache');
    }

    /**
     * Disable browser caching
     */
    private function disable_browser_cache() {
        $this->remove_htaccess_rules('ProRank Browser Cache');
    }

    /**
     * Enable GZIP compression
     */
    private function enable_gzip_compression() {
        $rules = $this->get_gzip_rules();
        $this->insert_htaccess_rules($rules, 'ProRank GZIP');
    }

    /**
     * Disable GZIP compression
     */
    private function disable_gzip_compression() {
        $this->remove_htaccess_rules('ProRank GZIP');
    }

    /**
     * Get browser cache rules for .htaccess
     */
    private function get_browser_cache_rules() {
        return '
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType text/javascript "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
    ExpiresByType application/x-shockwave-flash "access plus 1 month"
    ExpiresByType image/x-icon "access plus 1 year"
    ExpiresDefault "access plus 2 days"
</IfModule>';
    }

    /**
     * Get GZIP compression rules
     */
    private function get_gzip_rules() {
        return '
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
    AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript
    AddOutputFilterByType DEFLATE application/xml application/xhtml+xml application/rss+xml
    AddOutputFilterByType DEFLATE application/font-woff application/font-woff2 application/vnd.ms-fontobject
    AddOutputFilterByType DEFLATE application/x-font-ttf font/opentype image/svg+xml image/x-icon
</IfModule>';
    }

    /**
     * Update .htaccess with cache rules
     */
    private function update_htaccess_cache_rules($enable) {
        if ($enable) {
            $rules = $this->get_browser_cache_rules();
            $this->insert_htaccess_rules($rules, 'ProRank Cache');
        } else {
            $this->remove_htaccess_rules('ProRank Cache');
        }
    }

    /**
     * Insert rules into .htaccess
     */
    private function insert_htaccess_rules($rules, $marker) {
        if (!function_exists('insert_with_markers')) {
            require_once(ABSPATH . 'wp-admin/includes/misc.php');
        }

        $htaccess = prorank_home_file_path('.htaccess');

        if (wp_is_writable($htaccess)) {
            $lines = explode("\n", trim($rules));
            insert_with_markers($htaccess, $marker, $lines);
        }
    }

    /**
     * Remove rules from .htaccess
     */
    private function remove_htaccess_rules($marker) {
        if (!function_exists('insert_with_markers')) {
            require_once(ABSPATH . 'wp-admin/includes/misc.php');
        }

        $htaccess = prorank_home_file_path('.htaccess');

        if (wp_is_writable($htaccess)) {
            insert_with_markers($htaccess, $marker, []);
        }
    }

    /**
     * Activate module features
     */
    private function activate_module_features($module_slug) {
        switch ($module_slug) {
            case 'page-cache':
                $this->enable_page_cache();
                break;

            case 'image-optimization':
                update_option('prorank_image_optimization_enabled', true);
                break;

            case 'database-optimization':
                wp_schedule_event(time(), 'weekly', 'prorank_optimize_database');
                break;

        }
    }

    /**
     * Deactivate module features
     */
    private function deactivate_module_features($module_slug) {
        switch ($module_slug) {
            case 'page-cache':
                $this->disable_page_cache();
                break;

            case 'image-optimization':
                update_option('prorank_image_optimization_enabled', false);
                break;

            case 'database-optimization':
                wp_clear_scheduled_hook('prorank_optimize_database');
                break;

        }
    }

    /**
     * Recursively delete a directory
     */
    private function delete_directory($dir) {
        if (!file_exists($dir)) {
            return;
        }

        $files = array_diff(scandir($dir), ['.', '..']);

        foreach ($files as $file) {
            $path = $dir . '/' . $file;

            if (is_dir($path)) {
                $this->delete_directory($path);
            } else {
                \ProRank\SEO\Core\FilesystemHelper::delete_file($path);
            }
        }

        \ProRank\SEO\Core\FilesystemHelper::delete_dir($dir);
    }
}

// Initialize the AJAX handlers
new AjaxHandlers();
