<?php

/**
 * Import/Export REST API Controller
 *
 * @package ProRank\SEO\Core\RestApi
 * @since   0.1.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Core\RestApi;

use ProRank\SEO\Core\Config\Settings;
use ProRank\SEO\Core\ModuleManager;
use ProRank\SEO\Core\LicenseManager;
use WP_REST_Controller;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

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


/**
 * Class ImportExportController
 * 
 * Handles REST API endpoints for import/export functionality
 */


class ImportExportController extends WP_REST_Controller {
    /**
     * Namespace
     *
     * @var string
     */
    protected $namespace = 'prorank-seo/v1';

    /**
     * Rest base
     *
     * @var string
     */
    protected $rest_base = 'import-export';

    /**
     * Module manager instance
     *
     * @var ModuleManager
     */
    private ModuleManager $module_manager;

    /**
     * License manager instance
     *
     * @var LicenseManager
     */
    private LicenseManager $license_manager;

    /**
     * Constructor
     *
     * @param ModuleManager  $module_manager  Module manager instance
     * @param LicenseManager $license_manager License manager instance
     */
    public function __construct(ModuleManager $module_manager, LicenseManager $license_manager) {
        $this->module_manager = $module_manager;
        $this->license_manager = $license_manager;
    }

    /**
     * Register routes
     *
     * @return void
     */
    public function register_routes(): void {
        // Export settings
        register_rest_route($this->namespace, '/' . $this->rest_base . '/export', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'export_settings'],
                'permission_callback' => [$this, 'export_permissions_check'],
                'args'                => [
                    'type' => [
                        'description' => __('Type of data to export', 'prorank-seo'),
                        'type'        => 'string',
                        'enum'        => ['all', 'settings', 'modules', 'redirects', 'meta'],
                        'default'     => 'all',
                    ],
                ],
            ],
        ]);

        // Import settings
        register_rest_route($this->namespace, '/' . $this->rest_base . '/import', [
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'import_settings'],
                'permission_callback' => [$this, 'import_permissions_check'],
                'args'                => [
                    'data' => [
                        'description' => __('JSON data to import', 'prorank-seo'),
                        'type'        => 'string',
                        'required'    => true,
                        'validate_callback' => [$this, 'validate_import_data'],
                    ],
                    'type' => [
                        'description' => __('Type of data to import', 'prorank-seo'),
                        'type'        => 'string',
                        'enum'        => ['all', 'settings', 'modules', 'redirects', 'meta'],
                        'default'     => 'all',
                    ],
                ],
            ],
        ]);

        // Reset settings
        register_rest_route($this->namespace, '/' . $this->rest_base . '/reset', [
            [
                'methods'             => WP_REST_Server::DELETABLE,
                'callback'            => [$this, 'reset_settings'],
                'permission_callback' => [$this, 'reset_permissions_check'],
                'args'                => [
                    'confirm' => [
                        'description' => __('Confirmation flag', 'prorank-seo'),
                        'type'        => 'boolean',
                        'required'    => true,
                    ],
                ],
            ],
        ]);

        // Import from competitor plugins
        register_rest_route($this->namespace, '/' . $this->rest_base . '/competitor', [
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'import_from_competitor'],
                'permission_callback' => [$this, 'import_permissions_check'],
                'args'                => [
                    'source' => [
                        'description' => __('Competitor plugin to import from', 'prorank-seo'),
                        'type'        => 'string',
                        'enum'        => ['yoast', 'rankmath', 'aioseo', 'seopress'],
                        'required'    => true,
                    ],
                    'types' => [
                        'description' => __('Types of data to import', 'prorank-seo'),
                        'type'        => 'array',
                        'items'       => [
                            'type' => 'string',
                            'enum' => ['meta', 'settings', 'redirects', 'schema', 'locations'],
                        ],
                        'default'     => ['meta', 'settings', 'redirects', 'schema', 'locations'],
                    ],
                ],
            ],
        ]);

        // Backward compatibility route used by older onboarding builds.
        register_rest_route($this->namespace, '/import/competitor', [
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'import_from_competitor'],
                'permission_callback' => [$this, 'import_permissions_check'],
                'args'                => [
                    'source' => [
                        'description' => __('Competitor plugin to import from', 'prorank-seo'),
                        'type'        => 'string',
                        'enum'        => ['yoast', 'rankmath', 'aioseo', 'seopress'],
                        'required'    => true,
                    ],
                    'types' => [
                        'description' => __('Types of data to import', 'prorank-seo'),
                        'type'        => 'array',
                        'items'       => [
                            'type' => 'string',
                            'enum' => ['meta', 'settings', 'redirects', 'schema', 'locations'],
                        ],
                        'default'     => ['meta', 'settings', 'redirects', 'schema', 'locations'],
                    ],
                ],
            ],
        ]);

        // Migration Center: detect available competitors and data counts
        register_rest_route($this->namespace, '/' . $this->rest_base . '/migration-status', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_migration_status'],
                'permission_callback' => [$this, 'import_permissions_check'],
            ],
        ]);
    }

    /**
     * Migration Center: return status of all competitor importers.
     */
    public function get_migration_status(WP_REST_Request $request): WP_REST_Response {
        $competitors = [
            'yoast' => [
                'name'  => 'Yoast SEO',
                'slug'  => 'yoast',
                'icon'  => 'yoast',
                'types' => ['meta', 'settings', 'redirects', 'schema', 'locations'],
            ],
            'aioseo' => [
                'name'  => 'All in One SEO',
                'slug'  => 'aioseo',
                'icon'  => 'aioseo',
                'types' => ['meta', 'settings', 'redirects', 'schema'],
            ],
            'rankmath' => [
                'name'  => 'Rank Math',
                'slug'  => 'rankmath',
                'icon'  => 'rankmath',
                'types' => ['meta', 'settings', 'redirects', 'schema', 'locations'],
            ],
            'seopress' => [
                'name'  => 'SEOPress',
                'slug'  => 'seopress',
                'icon'  => 'seopress',
                'types' => ['meta', 'settings', 'redirects'],
            ],
        ];

        $results = [];

        foreach ($competitors as $key => $info) {
            $importer = $this->get_competitor_importer($key, ['meta']);
            $available = $importer ? $importer->is_available() : false;
            $post_count = 0;

            if ($available) {
                $post_count = $this->count_competitor_posts($key);
            }

            $results[] = [
                'name'       => $info['name'],
                'slug'       => $info['slug'],
                'icon'       => $info['icon'],
                'available'  => $available,
                'post_count' => $post_count,
                'types'      => $info['types'],
            ];
        }

        return rest_ensure_response([
            'success' => true,
            'data'    => ['competitors' => $results],
        ]);
    }

    /**
     * Count posts with competitor SEO data in postmeta.
     */
    private function count_competitor_posts(string $source): int {
        global $wpdb;

        $patterns = [
            'yoast'    => '_yoast_wpseo_title',
            'aioseo'   => '_aioseo_title',
            'rankmath'  => 'rank_math_title',
            'seopress' => '_seopress_titles_title',
        ];

        $meta_key = $patterns[$source] ?? '';
        if ($meta_key === '') {
            return 0;
        }

        return (int) $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(DISTINCT post_id) FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value != ''",
                $meta_key
            )
        );
    }

    /**
     * Export settings
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
     */
    public function export_settings($request) {
        // Sanitize input
        $type = sanitize_key($request->get_param('type'));

        // Create base export data
        $export_data = [
            'plugin' => 'ProRank SEO',
            'version' => PRORANK_SEO_VERSION,
            'site_url' => get_site_url(),
            'export_date' => current_time('c'),
            'export_type' => $type,
            'wordpress_version' => get_bloginfo('version'),
            'php_version' => PHP_VERSION,
        ];

        try {
            // Add data based on export type
            switch ($type) {
                case 'all':
                    $export_data['settings'] = $this->export_all_settings();
                    $export_data['modules'] = $this->export_module_states();
                    $export_data['redirects'] = $this->export_redirects();
                    $export_data['meta'] = $this->export_meta_data();
                    $export_data['stats'] = [
                        'total_settings' => count($export_data['settings']),
                        'total_modules' => count($export_data['modules']),
                        'total_redirects' => count($export_data['redirects']),
                        'total_meta' => count($export_data['meta']),
                    ];
                    break;
                    
                case 'settings':
                    $export_data['settings'] = $this->export_all_settings();
                    $export_data['stats'] = ['total_settings' => count($export_data['settings'])];
                    break;
                    
                case 'modules':
                    $export_data['modules'] = $this->export_module_states();
                    $export_data['stats'] = ['total_modules' => count($export_data['modules'])];
                    break;
                    
                case 'redirects':
                    $export_data['redirects'] = $this->export_redirects();
                    $export_data['stats'] = ['total_redirects' => count($export_data['redirects'])];
                    break;
                    
                case 'meta':
                    $export_data['meta'] = $this->export_meta_data();
                    $export_data['stats'] = ['total_meta' => count($export_data['meta'])];
                    break;
            }

            // Encode and compress if large
            $json_data = json_encode($export_data, JSON_PRETTY_PRINT);
            if (strlen($json_data) > 1024 * 1024) { // If larger than 1MB
                prorank_log('ProRank SEO: Large export data (' . strlen($json_data) . ' bytes)');
            }

            return new WP_REST_Response([
                'success' => true,
                'data' => base64_encode($json_data),
                'filename' => $this->generate_export_filename($type),
                'size' => strlen($json_data),
            ], 200);

        } catch (\Throwable $e) {
            prorank_log('ProRank SEO Export Error: ' . $e->getMessage());
            return new WP_Error(
                'export_failed',
/* translators: %1$: value */
                sprintf(__('Export failed: %1$s', 'prorank-seo'), $e->getMessage()),
                ['status' => 500]
            );
        }
    }

    /**
     * Import settings
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
     */
    public function import_settings($request) {
        // Sanitize inputs
        $encoded_data = sanitize_text_field($request->get_param('data'));
        $type = sanitize_key($request->get_param('type'));

        try {
            // Decode the data
            $json_data = base64_decode($encoded_data);
            if ($json_data === false) {
                throw new \Exception(__('Invalid data format', 'prorank-seo'));
            }

            $import_data = json_decode($json_data, true);
            if (json_last_error() !== JSON_ERROR_NONE) {
                throw new \Exception(__('Invalid JSON data', 'prorank-seo'));
            }

            // Validate version compatibility
            if (!$this->is_version_compatible($import_data['version'] ?? '')) {
                throw new \Exception(__('Incompatible version', 'prorank-seo'));
            }

            $results = [];

            switch ($type) {
                case 'all':
                    if (isset($import_data['settings'])) {
                        $results['settings'] = $this->import_all_settings($import_data['settings']);
                    }
                    if (isset($import_data['modules'])) {
                        $results['modules'] = $this->import_module_states($import_data['modules']);
                    }
                    if (isset($import_data['redirects'])) {
                        $results['redirects'] = $this->import_redirects($import_data['redirects']);
                    }
                    if (isset($import_data['meta'])) {
                        $results['meta'] = $this->import_meta_data($import_data['meta']);
                    }
                    break;
                    
                case 'settings':
                    if (isset($import_data['settings'])) {
                        $results['settings'] = $this->import_all_settings($import_data['settings']);
                    }
                    break;
                    
                case 'modules':
                    if (isset($import_data['modules'])) {
                        $results['modules'] = $this->import_module_states($import_data['modules']);
                    }
                    break;
                    
                case 'redirects':
                    if (isset($import_data['redirects'])) {
                        $results['redirects'] = $this->import_redirects($import_data['redirects']);
                    }
                    break;
                    
                case 'meta':
                    if (isset($import_data['meta'])) {
                        $results['meta'] = $this->import_meta_data($import_data['meta']);
                    }
                    break;
            }

            return new WP_REST_Response([
                'success' => true,
                'message' => __('Import completed successfully', 'prorank-seo'),
                'results' => $results,
            ], 200);

        } catch (\Throwable $e) {
            return new WP_Error(
                'import_failed',
/* translators: %1$: value */
                sprintf(__('Import failed: %1$s', 'prorank-seo'), $e->getMessage()),
                ['status' => 400]
            );
        }
    }

    /**
     * Reset settings
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
     */
    public function reset_settings($request) {
        // Sanitize input
        $confirm = (bool) $request->get_param('confirm');

        if (!$confirm) {
            return new WP_Error(
                'confirmation_required',
                __('Please confirm the reset action', 'prorank-seo'),
                ['status' => 400]
            );
        }

        try {
            // Delete all ProRank SEO options
            $this->delete_all_options();
            
            // Reset module states
            $this->reset_module_states();

            // Remove redirect rules and custom SEO meta so the reset matches
            // the destructive action described by the admin UI.
            $this->delete_redirect_rules();
            $this->delete_meta_data();
            
            // Clear transients
            $this->clear_transients();

            return new WP_REST_Response([
                'success' => true,
                'message' => __('All settings have been reset to defaults', 'prorank-seo'),
            ], 200);

        } catch (\Throwable $e) {
            return new WP_Error(
                'reset_failed',
/* translators: %1$: value */
                sprintf(__('Reset failed: %1$s', 'prorank-seo'), $e->getMessage()),
                ['status' => 500]
            );
        }
    }

    /**
     * Export all settings
     *
     * @return array
     */
    private function export_all_settings(): array {
        global $wpdb;
        
        $settings = [];
        
        // Get all ProRank SEO options
        $options = $wpdb->get_results(
            "SELECT option_name, option_value 
             FROM {$wpdb->options} 
             WHERE option_name LIKE 'prorank_seo_%' 
             AND option_name NOT LIKE '%_transient_%'"
        );
        
        foreach ($options as $option) {
            $settings[$option->option_name] = maybe_unserialize($option->option_value);
        }

        // Include unified settings option used by ModuleManager and newer controllers.
        $settings['prorank_settings'] = get_option('prorank_settings', []);
        
        return $settings;
    }

    /**
     * Export module states
     *
     * @return array
     */
    private function export_module_states(): array {
        $modules = $this->module_manager->get_modules();
        $states = [];
        
        foreach ($modules as $slug => $module) {
            $states[$slug] = [
                'enabled' => $this->module_manager->is_module_enabled((string) $slug),
                'settings' => Settings::get("modules.$slug", []),
            ];
        }
        
        return $states;
    }

    /**
     * Export redirects
     *
     * @return array
     */
    private function export_redirects(): array {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'prorank_redirects';
        
        // Check if table exists
        if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") !== $table_name) {
            return [];
        }
        
        $redirects = $wpdb->get_results(
            "SELECT * FROM $table_name ORDER BY id ASC",
            ARRAY_A
        );
        
        return $redirects ?: [];
    }

    /**
     * Export meta data
     *
     * @return array
     */
    private function export_meta_data(): array {
        global $wpdb;
        
        $meta_data = $wpdb->get_results(
            "SELECT post_id, meta_key, meta_value 
             FROM {$wpdb->postmeta} 
             WHERE meta_key LIKE '_prorank_seo_%'",
            ARRAY_A
        );
        
        return $meta_data ?: [];
    }

    /**
     * Import all settings
     *
     * @param array $settings Settings to import
     * @return array Import results
     */
    private function import_all_settings(array $settings): array {
        $imported = 0;
        $failed = 0;
        
        foreach ($settings as $option_name => $option_value) {
            // Keep the import surface narrow: legacy prorank_seo_* options plus
            // the unified runtime option exported by current builds.
            $is_prorank_legacy_option = strpos($option_name, 'prorank_seo_') === 0;
            $is_prorank_unified_option = $option_name === 'prorank_settings';

            if (!$is_prorank_legacy_option && !$is_prorank_unified_option) {
                continue;
            }

            $current_value = get_option($option_name, null);
            if ($current_value === $option_value) {
                $imported++;
                continue;
            }

            if (update_option($option_name, $option_value)) {
                $imported++;
            } else {
                $failed++;
            }
        }
        
        return [
            'imported' => $imported,
            'failed' => $failed,
        ];
    }

    /**
     * Import module states
     *
     * @param array $states Module states to import
     * @return array Import results
     */
    private function import_module_states(array $states): array {
        $imported = 0;
        $failed = 0;
        
        foreach ($states as $slug => $state) {
            try {
                $module_slug = $this->resolve_module_slug((string) $slug);
                if ($module_slug === null) {
                    $failed++;
                    continue;
                }

                // Update module enabled state
                if (isset($state['enabled'])) {
                    if ((bool) $state['enabled']) {
                        $this->module_manager->activate_module($module_slug);
                    } else {
                        $this->module_manager->deactivate_module($module_slug);
                    }
                }
                
                // Update module settings
                if (isset($state['settings']) && is_array($state['settings'])) {
                    Settings::set("modules.$module_slug", $state['settings']);
                }
                
                $imported++;
            } catch (\Throwable $e) {
                $failed++;
            }
        }
        
        return [
            'imported' => $imported,
            'failed' => $failed,
        ];
    }

    /**
     * Import redirects
     *
     * @param array $redirects Redirects to import
     * @return array Import results
     */
    private function import_redirects(array $redirects): array {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'prorank_redirects';
        $imported = 0;
        $failed = 0;
        
        // Check if table exists
        if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") !== $table_name) {
            return [
                'imported' => 0,
                'failed' => count($redirects),
                'error' => __('Redirects table does not exist', 'prorank-seo'),
            ];
        }
        
        foreach ($redirects as $redirect) {
            // Remove ID to allow auto-increment
            unset($redirect['id']);

            // Sanitize redirect data to prevent SQL injection
            $sanitized_redirect = $this->sanitize_redirect_data($redirect);

            if (empty($sanitized_redirect['source_url'])) {
                $failed++;
                continue;
            }

            // Check if redirect already exists
            $exists = $wpdb->get_var($wpdb->prepare(
                "SELECT id FROM $table_name WHERE source_url = %s",
                $sanitized_redirect['source_url']
            ));

            if (!$exists) {
                $result = $wpdb->insert($table_name, $sanitized_redirect);
                if ($result !== false) {
                    $imported++;
                } else {
                    $failed++;
                }
            } else {
                // Update existing redirect
                $result = $wpdb->update(
                    $table_name,
                    $sanitized_redirect,
                    ['source_url' => $sanitized_redirect['source_url']]
                );
                if ($result !== false) {
                    $imported++;
                } else {
                    $failed++;
                }
            }
        }
        
        return [
            'imported' => $imported,
            'failed' => $failed,
        ];
    }

    /**
     * Sanitize redirect data to prevent SQL injection
     *
     * @param array $redirect Raw redirect data
     * @return array Sanitized redirect data
     */
    private function sanitize_redirect_data(array $redirect): array {
        $sanitized = [];

        // Source URL - required
        if (isset($redirect['source_url'])) {
            $sanitized['source_url'] = sanitize_text_field(wp_unslash($redirect['source_url']));
        }

        // Target URL - required
        if (isset($redirect['target_url'])) {
            $sanitized['target_url'] = esc_url_raw(wp_unslash($redirect['target_url']));
        }

        // Redirect type - must be valid HTTP redirect code
        if (isset($redirect['redirect_type'])) {
            $valid_types = [301, 302, 307, 308, 410, 451];
            $type = intval($redirect['redirect_type']);
            $sanitized['redirect_type'] = in_array($type, $valid_types, true) ? $type : 301;
        }

        // Status - active or inactive
        if (isset($redirect['status'])) {
            $sanitized['status'] = in_array($redirect['status'], ['active', 'inactive'], true)
                ? $redirect['status']
                : 'active';
        }

        // Is regex flag
        if (isset($redirect['is_regex'])) {
            $sanitized['is_regex'] = (bool) $redirect['is_regex'] ? 1 : 0;
        }

        // Case insensitive flag
        if (isset($redirect['case_insensitive'])) {
            $sanitized['case_insensitive'] = (bool) $redirect['case_insensitive'] ? 1 : 0;
        }

        // Hit count - integer
        if (isset($redirect['hit_count'])) {
            $sanitized['hit_count'] = absint($redirect['hit_count']);
        }

        // Created timestamp
        if (isset($redirect['created_at'])) {
            $sanitized['created_at'] = sanitize_text_field($redirect['created_at']);
        }

        // Updated timestamp
        if (isset($redirect['updated_at'])) {
            $sanitized['updated_at'] = sanitize_text_field($redirect['updated_at']);
        }

        return $sanitized;
    }

    /**
     * Import meta data
     *
     * @param array $meta_data Meta data to import
     * @return array Import results
     */
    private function import_meta_data(array $meta_data): array {
        $imported = 0;
        $failed = 0;
        
        foreach ($meta_data as $meta) {
            if (!isset($meta['post_id'], $meta['meta_key'], $meta['meta_value'])) {
                $failed++;
                continue;
            }
            
            // Check if post exists
            if (!get_post($meta['post_id'])) {
                $failed++;
                continue;
            }

            $current_value = get_post_meta($meta['post_id'], $meta['meta_key'], true);
            if ($current_value === $meta['meta_value']) {
                $imported++;
                continue;
            }

            if (update_post_meta($meta['post_id'], $meta['meta_key'], $meta['meta_value'])) {
                $imported++;
            } else {
                $failed++;
            }
        }
        
        return [
            'imported' => $imported,
            'failed' => $failed,
        ];
    }

    /**
     * Delete all ProRank SEO options
     *
     * @return void
     */
    private function delete_all_options(): void {
        global $wpdb;

        $option_names = $wpdb->get_col(
            "SELECT option_name
             FROM {$wpdb->options}
             WHERE option_name LIKE 'prorank_seo_%'
             AND option_name NOT LIKE '%_transient_%'"
        );

        foreach ($option_names as $option_name) {
            if (is_string($option_name) && $option_name !== '') {
                delete_option($option_name);
            }
        }

        // Stored as a non-prefixed unified option.
        delete_option('prorank_settings');
    }

    /**
     * Clear ProRank SEO transients
     *
     * @return void
     */
    private function clear_transients(): void {
        global $wpdb;

        $transient_names = $wpdb->get_col(
            "SELECT option_name
             FROM {$wpdb->options}
             WHERE option_name LIKE '_transient_prorank_%'
             OR option_name LIKE '_transient_timeout_prorank_%'"
        );

        foreach ($transient_names as $transient_name) {
            if (is_string($transient_name) && $transient_name !== '') {
                delete_option($transient_name);
            }
        }
    }

    /**
     * Delete stored redirect rules from the canonical redirects table.
     *
     * @return void
     */
    private function delete_redirect_rules(): void {
        global $wpdb;

        $table_name = $wpdb->prefix . 'prorank_redirects';
        if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") !== $table_name) {
            return;
        }

        $wpdb->query("TRUNCATE TABLE $table_name");
    }

    /**
     * Delete custom ProRank post meta.
     *
     * @return void
     */
    private function delete_meta_data(): void {
        global $wpdb;

        $wpdb->query(
            "DELETE FROM {$wpdb->postmeta}
             WHERE meta_key LIKE '_prorank_seo_%'"
        );
    }

    /**
     * Check version compatibility
     *
     * @param string $version Version to check
     * @return bool
     */
    private function is_version_compatible(string $version): bool {
        if (empty($version)) {
            return false;
        }
        
        // Allow imports from same major version
        $current_major = explode('.', PRORANK_SEO_VERSION)[0];
        $import_major = explode('.', $version)[0];
        
        return $current_major === $import_major;
    }

    /**
     * Generate export filename
     *
     * @param string $type Export type
     * @return string
     */
    private function generate_export_filename(string $type): string {
        $site_name = sanitize_title(get_bloginfo('name'));
        $date = wp_date('Y-m-d-His');
        
        return sprintf('prorank-seo-%s-%s-%s.json', $site_name, $type, $date);
    }

    /**
     * Validate import data
     *
     * @param string $value Data to validate
     * @return bool
     */
    public function validate_import_data($value): bool {
        // Check if it's a valid base64 string
        if (!is_string($value) || !preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $value)) {
            return false;
        }
        
        // Try to decode
        $decoded = base64_decode($value, true);
        if ($decoded === false) {
            return false;
        }
        
        // Check if it's valid JSON
        json_decode($decoded);
        return json_last_error() === JSON_ERROR_NONE;
    }

    /**
     * Check if a given request has access to export
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return true|WP_Error True if the request has access, WP_Error object otherwise.
     */
    public function export_permissions_check($request) {
        return current_user_can('manage_options');
    }

    /**
     * Check if a given request has access to import
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return true|WP_Error True if the request has access, WP_Error object otherwise.
     */
    public function import_permissions_check($request) {
        return current_user_can('manage_options');
    }

    /**
     * Check if a given request has access to reset
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return true|WP_Error True if the request has access, WP_Error object otherwise.
     */
    public function reset_permissions_check($request) {
        return current_user_can('manage_options');
    }

    /**
     * Import from competitor plugin
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
     */
    public function import_from_competitor($request) {
        // Sanitize inputs
        $source = sanitize_key($request->get_param('source'));
        $types = array_map('sanitize_key', (array) $request->get_param('types'));

        try {
            // Get the appropriate importer
            $importer = $this->get_competitor_importer($source, $types);
            
            if (!$importer) {
                return new WP_Error(
                    'invalid_source',
/* translators: %1$: value */
                    sprintf(__('Invalid import source: %1$s', 'prorank-seo'), $source),
                    ['status' => 400]
                );
            }

            // Check if competitor plugin data is available
            if (!$importer->is_available()) {
                return new WP_Error(
                    'source_not_available',
/* translators: %1$: value */
                    sprintf(__('No data found for %1$s', 'prorank-seo'), $source),
                    ['status' => 404]
                );
            }

            // Run the import
            $result = $importer->import();

            if ($result['success']) {
                return new WP_REST_Response([
                    'success' => true,
                    'message' => $result['message'],
                    'stats' => $result['stats'],
                ], 200);
            } else {
                return new WP_Error(
                    'import_failed',
                    $result['message'],
                    ['status' => 500, 'stats' => $result['stats']]
                );
            }

        } catch (\Throwable $e) {
            prorank_log('ProRank SEO Competitor Import Error: ' . $e->getMessage());
            return new WP_Error(
                'import_exception',
/* translators: %1$: value */
                sprintf(__('Import failed: %1$s', 'prorank-seo'), $e->getMessage()),
                ['status' => 500]
            );
        }
    }

    /**
     * Get competitor importer instance
     *
     * @param string $source Import source
     * @param array  $types  Import types
     * @return object|null Importer instance or null
     */
    private function get_competitor_importer(string $source, array $types) {
        $importers = [
            'yoast' => 'YoastImporter',
            'rankmath' => 'RankMathImporter',
            'aioseo' => 'AIOSEOImporter',
            'seopress' => 'SEOPressImporter',
        ];

        if (!isset($importers[$source])) {
            return null;
        }

        $importer_name = $importers[$source];
        $class = '\\ProRank\\SEO\\Core\\Importers\\' . $importer_name;

        // Load the importer class if not already loaded
        if (!class_exists($class)) {
            $plugin_dir = defined('PRORANK_SEO_PLUGIN_DIR')
                ? PRORANK_SEO_PLUGIN_DIR
                : (defined('PRORANK_PLUGIN_DIR') ? PRORANK_PLUGIN_DIR : '');
            if ($plugin_dir === '') {
                prorank_log('[ProRank SEO] Plugin directory constant is not defined');
                return null;
            }

            $importer_dir = $plugin_dir . 'includes/Core/Importers/';
            $base_file = $importer_dir . 'BaseImporter.php';
            $importer_file = $importer_dir . $importer_name . '.php';

            // Check if files exist
            if (!file_exists($base_file)) {
                prorank_log('[ProRank SEO] BaseImporter.php not found');
                return null;
            }

            if (!file_exists($importer_file)) {
                prorank_log('[ProRank SEO] Importer file not found: ' . $importer_name . '.php');
                return null;
            }

            // Load base importer first
            require_once $base_file;
            require_once $importer_file;
        }

        // Verify class exists after loading
        if (!class_exists($class)) {
            prorank_log('[ProRank SEO] Importer class not found after loading: ' . $class);
            return null;
        }

        return new $class($types);
    }

    /**
     * Resolve a module slug using ModuleManager aliases/id fallback.
     *
     * @param string $slug
     * @return string|null
     */
    private function resolve_module_slug(string $slug): ?string {
        if ($this->module_manager->has_module($slug)) {
            return $slug;
        }

        foreach ($this->module_manager->get_modules() as $module_id => $module) {
            if (is_object($module) && method_exists($module, 'get_slug') && $module->get_slug() === $slug) {
                return (string) $module_id;
            }
        }

        return null;
    }

    /**
     * Reset module enablement and module group toggles to defaults.
     *
     * @return void
     */
    private function reset_module_states(): void {
        delete_option('prorank_seo_module_groups');

        $settings = get_option('prorank_settings', []);
        if (!is_array($settings)) {
            return;
        }

        if (isset($settings['active_modules'])) {
            unset($settings['active_modules']);
            update_option('prorank_settings', $settings);
        }
    }
}
