<?php
namespace WPUltimateSecurity\UltimateSecurity\Support\Helpers;

use WPUltimateSecurity\UltimateSecurity\Config\ConfigLoader;

/**
 * Utility Helper Class
 *
 * Contains helper functions and default option definitions.
 */
class Utils
{
    /**
     * Static cache for options to prevent repeated expensive operations.
     *
     * @var array|null
     */
    private static $options_cache = null;

    /**
     * Static cache for plugins list.
     *
     * @var array|null
     */
    private static $plugins_cache = null;

    /**
     * Static cache for themes list.
     *
     * @var array|null
     */
    private static $themes_cache = null;
    /**
     * Get default plugin options.
     *
     * ============================================================================
     * HOW TO ADD NEW OPTIONS
     * ============================================================================
     *
     * 1. Add your new options to the appropriate section below
     * 2. Bump ULTIMATE_SECURITY_DB_VERSION in ultimate-security.php
     *
     * That's it! New options are automatically merged with existing user settings.
     * User's existing settings are preserved - only missing keys are added.
     *
     * EXAMPLE - Adding a new feature section:
     * ```php
     * 'my_new_feature' => [
     *     'enabled' => '0',
     *     'setting_one' => 'default_value',
     *     'setting_two' => [],
     * ],
     * ```
     *
     * EXAMPLE - Adding options to existing section:
     * ```php
     * 'security' => [
     *     // ... existing options ...
     *     'new_setting' => 'default_value', // Just add here
     * ],
     * ```
     *
     * ============================================================================
     * IMPORTANT NOTES
     * ============================================================================
     *
     * - Use '0' and '1' strings for boolean toggles (WordPress convention)
     * - Use empty arrays [] for list-type settings
     * - All options are stored in a single wp_option: 'ultimate_security_options'
     * - Nested arrays are supported and merged recursively
     *
     * @return array Default options structure
     */
    public static function ultimate_security_get_default_options()
    {
        // Load defaults from modular config files
        $ultimate_security_default_options = ConfigLoader::loadDefaults();

        $ultimate_security_default_options = apply_filters('ultimate_security_default_options_modify', $ultimate_security_default_options);

        return $ultimate_security_default_options;
    }

    /**
     * Update plugin options in the database.
     *
     * Note: Sanitization should be done BEFORE encryption in the controller.
     * This method does NOT re-sanitize as that would break encrypted values.
     *
     * @param array $option The options array to save (already sanitized and encrypted)
     * @return bool True on success
     */
    public static function ultimate_security_update_option($option) {
        $updated = update_option('ultimate_security_options', $option);

        // Clear cache so next get_option call fetches fresh data
        self::clear_options_cache();

        if ($updated) {
            return true;
        }

        $current_options = get_option('ultimate_security_options', []);
        return $current_options === $option;
    }

    /**
     * Get plugin options with defaults merged and API keys decrypted.
     *
     * Note: API key encryption/decryption is handled by ApiKeyCryptoService.
     * This method uses that service to safely decrypt API keys, handling
     * both encrypted and plaintext data gracefully.
     *
     * Performance: Uses static caching to prevent repeated expensive operations
     * (get_plugins, wp_get_themes) within a single request.
     *
     * @param bool $force_refresh Force cache refresh (use after settings update)
     * @return array Complete options array with defaults and decrypted API keys
     */
    public static function ultimate_security_get_option($force_refresh = false)
    {
        // Return cached options if available and not forcing refresh
        if (self::$options_cache !== null && !$force_refresh) {
            return self::$options_cache;
        }

        $ultimate_security_options_database = get_option('ultimate_security_options', []);
        $ultimate_security_options = array_replace_recursive(self::ultimate_security_get_default_options(), $ultimate_security_options_database);

        // Decrypt API keys using centralized service (handles encrypted & plaintext gracefully)
        $ultimate_security_options = ApiKeyCryptoService::decrypt($ultimate_security_options);

        // Ensure expected nested structures exist to avoid PHP warnings when defaults are missing keys
        if (!isset($ultimate_security_options['security']) || !is_array($ultimate_security_options['security'])) {
            $ultimate_security_options['security'] = [];
        }
        if (!isset($ultimate_security_options['security']['updates']) || !is_array($ultimate_security_options['security']['updates'])) {
            $ultimate_security_options['security']['updates'] = [];
        }
        if (!isset($ultimate_security_options['security']['updates']['plugins_functionalities']) || !is_array($ultimate_security_options['security']['updates']['plugins_functionalities'])) {
            $ultimate_security_options['security']['updates']['plugins_functionalities'] = [];
        }
        if (!isset($ultimate_security_options['security']['updates']['themes_functionalities']) || !is_array($ultimate_security_options['security']['updates']['themes_functionalities'])) {
            $ultimate_security_options['security']['updates']['themes_functionalities'] = [];
        }

        // Get plugins with caching
        $all_plugins = self::get_plugins_cached();

        foreach ($all_plugins as $plugin_file => $plugin_data) {
            if (!isset($ultimate_security_options['security']['updates']['plugins_functionalities'][$plugin_file])) {
                $ultimate_security_options['security']['updates']['plugins_functionalities'][$plugin_file] = [
                    'disable_updates' => false,
                    'auto_updates' => true,
                    'translation_updates' => true,
                    'hide' => false,
                ];
            }
        }

        // Get themes with caching
        $all_themes = self::get_themes_cached();
        foreach ($all_themes as $theme_slug => $theme_data) {
            if (!isset($ultimate_security_options['security']['updates']['themes_functionalities'][$theme_slug])) {
                $ultimate_security_options['security']['updates']['themes_functionalities'][$theme_slug] = [
                    'disable_updates' => 0,
                    'auto_updates' => 1,
                    'translation_updates' => 1,
                    'hide' => 0,
                ];
            }
        }

        // Cache the result for subsequent calls in this request
        self::$options_cache = $ultimate_security_options;

        return $ultimate_security_options;
    }

    /**
     * Get all plugins with static caching.
     *
     * @return array
     */
    public static function get_plugins_cached()
    {
        if (self::$plugins_cache !== null) {
            return self::$plugins_cache;
        }

        require_once ABSPATH . 'wp-admin/includes/plugin.php';
        self::$plugins_cache = get_plugins();

        return self::$plugins_cache;
    }

    /**
     * Get all themes with static caching.
     *
     * @return array
     */
    public static function get_themes_cached()
    {
        if (self::$themes_cache !== null) {
            return self::$themes_cache;
        }

        require_once ABSPATH . 'wp-admin/includes/theme.php';
        self::$themes_cache = wp_get_themes();

        return self::$themes_cache;
    }

    /**
     * Clear the options cache.
     *
     * Call this after updating settings to ensure fresh data.
     */
    public static function clear_options_cache()
    {
        self::$options_cache = null;
    }

    /**
     * Clear all caches.
     *
     * Call this when plugins or themes are installed/uninstalled.
     */
    public static function clear_all_caches()
    {
        self::$options_cache = null;
        self::$plugins_cache = null;
        self::$themes_cache = null;
    }
    public static function parse_user_agent($user_agent)
    {
        $result = [
            'browser' => __('Unknown', 'ultimate-security'),
            'version' => '',
            'platform' => __('Unknown', 'ultimate-security'),
            'device' => __('Desktop', 'ultimate-security'),
        ];

        if (stripos($user_agent, 'mobile') !== false) {
            $result['device'] = __('Mobile', 'ultimate-security');
        } elseif (stripos($user_agent, 'tablet') !== false) {
            $result['device'] = __('Tablet', 'ultimate-security');
        }

        if (preg_match('/(windows|linux|macintosh|android|ios)/i', $user_agent, $matches)) {
            $result['platform'] = ucfirst(strtolower($matches[1]));
        }

        if (preg_match('/(firefox|chrome|safari|opera|msie|edge|trident)[\/\s]?(\d+)/i', $user_agent, $matches)) {
            $result['browser'] = ucfirst(strtolower($matches[1]));
            $result['version'] = $matches[2] ?? '';
        }

        return $result;
    }

    /**
     * Get all tables starting with ultimate_security_ prefix
     */
    public static function ultimate_security_get_tables()
    {
        global $wpdb;
        $table_prefix = $wpdb->prefix . 'ultimate_security_';
        $all_tables = $wpdb->get_col($wpdb->prepare("SHOW TABLES LIKE %s", "{$table_prefix}%"));
        // Remove table prefix from table names
        $table_names = $all_tables;
        $table_names = array_map(function ($table) use ($table_prefix) {
            return str_replace($table_prefix, '', $table);
        }, $table_names);
        return $table_names;
    }

    public  static function ultimate_security_generate_random_string($length)
    {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[random_int(0, $charactersLength - 1)];
        }
        return $randomString;
    }
}
