<?php
/**
 * ExploreXR Addon Compatibility Checker
 * 
 * Handles version compatibility and dependency checks for addons
 */

// Exit if accessed directly
if (!defined('ABSPATH')) {
    exit;
}

class ExploreXR_Addon_Compatibility_Checker {
    
    private $addon_manager;
    
    public function __construct($addon_manager) {
        $this->addon_manager = $addon_manager;
    }
    
    /**
     * Initialize compatibility checking hooks
     */
    public function init() {
        add_action('admin_init', array($this, 'check_addon_compatibility'));
        add_filter('plugin_action_links', array($this, 'add_addon_links'), 10, 2);
    }
    
    /**
     * Check if addon is compatible with current core version
     */
    public function is_addon_compatible($addon_slug) {
        $registered_addons = $this->addon_manager->get_registered_addons();
        if (!isset($registered_addons[$addon_slug])) {
            return false;
        }
        
        $addon = $registered_addons[$addon_slug];
        $core_version = defined('EXPLOREXR_PREMIUM_VERSION') ? EXPLOREXR_PREMIUM_VERSION : '0.0.0';
        
        // Normalize version strings to ensure consistent comparison
        $core_version = $this->normalize_version($core_version);
        $min_version = $this->normalize_version($addon['min_core_version']);
        $max_version = isset($addon['max_core_version']) && $addon['max_core_version'] 
            ? $this->normalize_version($addon['max_core_version']) 
            : null;
        
        // Debug logging for version compatibility checks
        if (defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Only logs when WP_DEBUG and WP_DEBUG_LOG are both enabled
            error_log("ExploreXR Addon Compatibility Check for '{$addon_slug}':");
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Only logs when WP_DEBUG and WP_DEBUG_LOG are both enabled
            error_log("  Core version: {$core_version} (original: " . (defined('EXPLOREXR_PREMIUM_VERSION') ? EXPLOREXR_PREMIUM_VERSION : '0.0.0') . ")");
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Only logs when WP_DEBUG and WP_DEBUG_LOG are both enabled
            error_log("  Min required: {$min_version} (original: {$addon['min_core_version']})");
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Only logs when WP_DEBUG and WP_DEBUG_LOG are both enabled
            error_log("  Max allowed: " . ($max_version ?? 'none') . " (original: " . ($addon['max_core_version'] ?? 'none') . ")");
        }
        
        // Check minimum version
        $min_check = version_compare($core_version, $min_version, '<');
        if ($min_check) {
            if (defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Only logs when WP_DEBUG and WP_DEBUG_LOG are both enabled
                error_log("  Failed min version check: {$core_version} < {$min_version}");
            }
            return false;
        }
        
        // Check maximum version if specified
        if ($max_version) {
            $max_check = version_compare($core_version, $max_version, '>');
            if ($max_check) {
                if (defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
                    // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Only logs when WP_DEBUG and WP_DEBUG_LOG are both enabled
                    error_log("  Failed max version check: {$core_version} > {$max_version}");
                }
                return false;
            }
        }
        
        if (defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Only logs when WP_DEBUG and WP_DEBUG_LOG are both enabled
            error_log("  Compatibility check passed");
        }
        
        // Check dependencies
        foreach ($addon['dependencies'] as $dependency) {
            if (!$this->is_dependency_met($dependency)) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * Check if a dependency is met
     */
    private function is_dependency_met($dependency) {
        if (is_string($dependency)) {
            // Simple plugin check
            return is_plugin_active($dependency);
        }
        
        if (is_array($dependency)) {
            // Complex dependency check
            $type = $dependency['type'] ?? 'plugin';
            
            switch ($type) {
                case 'plugin':
                    return is_plugin_active($dependency['slug']);
                case 'function':
                    return function_exists($dependency['name']);
                case 'class':
                    return class_exists($dependency['name']);
                case 'constant':
                    return defined($dependency['name']);
                default:
                    return false;
            }
        }
        
        return false;
    }
    
    /**
     * Check addon compatibility on admin pages
     */
    public function check_addon_compatibility() {
        foreach ($this->addon_manager->get_registered_addons() as $slug => $addon) {
            if ($this->addon_manager->is_addon_active($slug) && !$this->is_addon_compatible($slug)) {
                add_action('admin_notices', function() use ($slug, $addon) {
                    $this->show_incompatibility_notice($slug, $addon);
                });
            }
        }
    }
    
    /**
     * Show incompatibility notice
     */
    private function show_incompatibility_notice($slug, $addon) {
        $core_version = defined('EXPLOREXR_PREMIUM_VERSION') ? EXPLOREXR_PREMIUM_VERSION : '0.0.0';
        
        // Determine the specific reason for incompatibility
        $min_version = $addon['min_core_version'];
        $max_version = $addon['max_core_version'] ?? null;
        
        $min_failed = version_compare($core_version, $min_version, '<');
        $max_failed = $max_version && version_compare($core_version, $max_version, '>');
        
        ?>
        <div class="notice notice-error">
            <p>
                <strong><?php echo esc_html($addon['name']); ?></strong> 
                is not compatible with ExploreXR version <?php echo esc_html($core_version); ?>.
                <?php if ($min_failed): ?>
                    This addon requires ExploreXR version <?php echo esc_html($min_version); ?> or higher.
                <?php elseif ($max_failed): ?>
                    This addon is only compatible with ExploreXR versions up to <?php echo esc_html($max_version); ?>. Please update the addon or downgrade ExploreXR.
                <?php elseif ($max_version): ?>
                    Required version range: <?php echo esc_html($min_version); ?> - <?php echo esc_html($max_version); ?>
                <?php else: ?>
                    Required version: <?php echo esc_html($min_version); ?>+
                <?php endif; ?>
            </p>
        </div>
        <?php
    }
    
    /**
     * Add addon management links
     */
    public function add_addon_links($links, $file) {
        foreach ($this->addon_manager->get_registered_addons() as $slug => $addon) {
            if ($addon['file'] === $file) {
                $status = $this->is_addon_compatible($slug) ? 'Compatible' : 'Incompatible';
                $class = $this->is_addon_compatible($slug) ? 'text-success' : 'text-danger';
                $links[] = '<span class="' . esc_attr($class) . '">' . esc_html($status) . '</span>';
                break;
            }
        }
        return $links;
    }
    
    /**
     * Normalize version string for consistent comparison
     */
    private function normalize_version($version) {
        if (empty($version)) {
            return '0.0.0';
        }
        
        // Remove any whitespace
        $version = trim($version);
        
        // Split version into parts
        $parts = explode('.', $version);
        
        // Ensure we have at least 3 parts (major.minor.patch)
        while (count($parts) < 3) {
            $parts[] = '0';
        }
        
        // Take only the first 3 parts for comparison (ignore build numbers)
        $parts = array_slice($parts, 0, 3);
        
        // Ensure all parts are numeric
        $parts = array_map(function($part) {
            return is_numeric($part) ? intval($part) : 0;
        }, $parts);
        
        return implode('.', $parts);
    }
}
