<?php
/**
 * ExploreXR Addon License Validator
 * 
 * Handles all license-related validation for addons
 */

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

class ExploreXR_Addon_License_Validator {
    
    private $addon_manager;
    
    public function __construct($addon_manager) {
        $this->addon_manager = $addon_manager;
    }
    
    /**
     * Initialize license validation hooks
     */
    public function init() {
        // Hook into WordPress plugin activation to validate license before activation
        add_action('activate_plugin', array($this, 'check_addon_activation_on_activate'), 10, 2);
        
        // Validate addon licenses on admin page load (but with grace period for recently activated)
        add_action('admin_init', array($this, 'validate_addon_licenses'), 20);
    }
    
    /**
     * Check if addon can be activated (runs DURING activation)
     * 
     * @param string $plugin_file The plugin file being activated
     * @param bool $network_wide Whether it's network activation
     */
    public function check_addon_activation_on_activate($plugin_file, $network_wide = false) {
        // Get license handler
        $license_handler = $this->get_license_handler_safely();
        
        // Check if this is one of our addons
        $addon_slug = null;
        $addon_data = null;
        foreach ($this->addon_manager->get_registered_addons() as $slug => $addon) {
            if (isset($addon['file']) && plugin_basename($addon['file']) === $plugin_file) {
                $addon_slug = $slug;
                $addon_data = $addon;
                break;
            }
        }
        
        // Not our addon, allow activation
        if ($addon_slug === null) {
            return;
        }
        
        // Set a transient to mark this addon as recently activated (5 second grace period)
        set_transient('explorexr_recently_activated_' . $addon_slug, true, 5);
        
        // Check license handler availability
        if (!$license_handler) {
            // No license handler - block activation
            $this->prevent_addon_activation($plugin_file, $addon_data, 'License system not available. Please check your ExploreXR Premium installation.');
            return;
        }
        
        // CRITICAL: Check if license is active
        if (!$license_handler->is_license_active()) {
            $this->prevent_addon_activation($plugin_file, $addon_data, 'A valid and active ExploreXR license is required. <a href="' . admin_url('admin.php?page=explorexr-license') . '">Activate your license</a> to use add-ons.');
            return;
        }
        
        // Get license tier and limits
        $license_tier = $license_handler->get_license_tier();
        $max_addons = $license_handler->get_max_addons();
        
        // Ultra tier: Allow all addons
        if ($license_tier === 'ultra' || $max_addons === -1) {
            // Automatically add to included addons for Ultra
            $this->ensure_addon_in_selections($license_handler, $addon_slug);
            return; // Allow activation
        }
        
        // Free tier: No addons allowed
        if ($max_addons === 0) {
            $this->prevent_addon_activation($plugin_file, $addon_data, 'Your license does not allow any add-ons. <a href="' . admin_url('admin.php?page=explorexr-license') . '">Upgrade your license</a> to use add-ons.');
            return;
        }
        
        // Count currently active addons (excluding the one being activated)
        $active_addon_count = 0;
        foreach ($this->addon_manager->get_registered_addons() as $slug => $data) {
            if ($slug !== $addon_slug && $this->addon_manager->is_addon_active($slug)) {
                $active_addon_count++;
            }
        }
        
        // Check if we've reached the limit
        if ($active_addon_count >= $max_addons) {
            $tier_name = $license_handler->get_license_tiers()[$license_tier]['name'];
            $this->prevent_addon_activation($plugin_file, $addon_data, sprintf('You have reached the maximum number of add-ons (%d) for your %s license. Please deactivate another add-on or <a href="' . admin_url('admin.php?page=explorexr-license') . '">upgrade your license</a>.', $max_addons, $tier_name));
            return;
        }
        
        // Add to included addons
        $this->ensure_addon_in_selections($license_handler, $addon_slug);
        
        // Activation allowed - addon will remain active
    }
    
    /**
     * Prevent addon activation and show error message
     * 
     * @param string $plugin_file The plugin file
     * @param array $addon_data The addon data
     * @param string $message The error message
     */
    private function prevent_addon_activation($plugin_file, $addon_data, $message) {
        // Deactivate the plugin immediately
        if (!function_exists('deactivate_plugins')) {
            require_once(ABSPATH . 'wp-admin/includes/plugin.php');
        }
        
        deactivate_plugins($plugin_file, true); // Silent deactivation
        
        // Store error message in transient to show on redirect
        $addon_name = isset($addon_data['name']) ? $addon_data['name'] : 'Add-on';
        set_transient('explorexr_addon_activation_error', array(
            'addon_name' => $addon_name,
            'message' => $message
        ), 30);
        
        // Hook into admin notices to show the error
        add_action('admin_notices', array($this, 'show_activation_error_notice'));
        
        // Redirect back to plugins page to show error
        wp_safe_redirect(admin_url('plugins.php'));
        exit;
    }
    
    /**
     * Show addon activation error notice
     */
    public function show_activation_error_notice() {
        $error_data = get_transient('explorexr_addon_activation_error');
        if ($error_data) {
            delete_transient('explorexr_addon_activation_error');
            ?>
            <div class="notice notice-error is-dismissible">
                <p>
                    <strong><?php echo esc_html($error_data['addon_name']); ?> could not be activated.</strong><br>
                    <?php echo wp_kses_post($error_data['message']); ?>
                </p>
            </div>
            <?php
        }
    }
    
    /**
     * Ensure addon is in the license selections
     * 
     * @param object $license_handler The license handler instance
     * @param string $addon_slug The addon slug
     */
    private function ensure_addon_in_selections($license_handler, $addon_slug) {
        $included_addons = $license_handler->get_selected_addons();
        
        if (!in_array($addon_slug, $included_addons)) {
            $included_addons[] = $addon_slug;
            $license_handler->select_addons($included_addons);
        }
    }
    
    /**
     * Validate that all active addons have proper license authorization
     * This runs on admin_init to ensure no addons remain active without authorization
     * Respects grace period for recently activated addons
     */
    public function validate_addon_licenses() {
        // Get license handler
        $license_handler = $this->get_license_handler_safely();

        // BUG-04 fix: ExploreXR_License_Handler::check_addon_activation() runs at admin_init
        // priority 10 (before this method at priority 20). If it already deactivated some
        // addons and showed notices, skip those slugs here to avoid duplicate notices.
        $already_deactivated = get_transient('explorexr_handler_deactivated_slugs');
        if (!is_array($already_deactivated)) {
            $already_deactivated = array();
        }

        // Track addons to deactivate
        $addons_to_deactivate = array();

        foreach ($this->addon_manager->get_registered_addons() as $slug => $addon) {
            // Debug addon requires no license — never deactivate it here.
            if ($slug === 'debug') {
                continue;
            }

            // Skip addons already handled by the priority-10 enforcement layer.
            if (in_array($slug, $already_deactivated, true)) {
                continue;
            }

            // Skip if addon is not currently active
            if (!$this->addon_manager->is_addon_active($slug)) {
                continue;
            }
            
            // CRITICAL: Skip recently activated addons to prevent race conditions
            // This gives the activation process time to complete before validation runs
            if (get_transient('explorexr_recently_activated_' . $slug)) {
                continue;
            }
            
            $should_deactivate = false;
            $reason = '';
            
            // Check if license handler is available
            if (!$license_handler) {
                $should_deactivate = true;
                $reason = 'license_system_unavailable';
            }
            // CRITICAL: Check if license is active - NO ADDONS WITHOUT ACTIVE LICENSE
            elseif (!$license_handler->is_license_active()) {
                $should_deactivate = true;
                $reason = 'no_active_license';
            }
            // Validate addon against license limits
            else {
                $license_tier = $license_handler->get_license_tier();
                $max_addons = $license_handler->get_max_addons();
                $selected_addons = $license_handler->get_selected_addons();
                
                // Ultra tier: All addons allowed
                if ($license_tier === 'ultra' || $max_addons === -1) {
                    $should_deactivate = false;
                }
                // Free tier: No addons allowed
                elseif ($max_addons === 0) {
                    $should_deactivate = true;
                    $reason = 'free_tier_no_addons';
                }
                // Check if addon is in selected addons list
                elseif (!in_array($slug, $selected_addons)) {
                    $should_deactivate = true;
                    $reason = 'not_in_selections';
                }
                // Verify total active count doesn't exceed license limit
                else {
                    $active_count = 0;
                    foreach ($this->addon_manager->get_registered_addons() as $check_slug => $check_data) {
                        if ($this->addon_manager->is_addon_active($check_slug)) {
                            $active_count++;
                        }
                    }
                    
                    if ($active_count > $max_addons) {
                        // This addon is active but we're over the limit
                        // Only deactivate if it's not in the first N selected addons
                        $allowed_addons = array_slice($selected_addons, 0, $max_addons);
                        if (!in_array($slug, $allowed_addons)) {
                            $should_deactivate = true;
                            $reason = 'exceeds_license_limit';
                        }
                    }
                }
            }
            
            if ($should_deactivate) {
                $addons_to_deactivate[] = array(
                    'slug' => $slug,
                    'addon' => $addon,
                    'reason' => $reason
                );
            }
        }
        
        // Deactivate unauthorized addons
        foreach ($addons_to_deactivate as $addon_info) {
            $this->deactivate_unlicensed_addon($addon_info);
        }
    }
    
    /**
     * Deactivate an unlicensed addon with improved error handling
     * 
     * @param array $addon_info Array containing slug, addon data, and reason code
     */
    private function deactivate_unlicensed_addon($addon_info) {
        $slug = $addon_info['slug'];
        $addon = $addon_info['addon'];
        $reason = $addon_info['reason'];
        
        if (!isset($addon['file'])) {
            return;
        }
        
        try {
            // Ensure deactivate_plugins function is available
            if (!function_exists('deactivate_plugins')) {
                require_once(ABSPATH . 'wp-admin/includes/plugin.php');
            }
            
            // Deactivate the plugin silently
            deactivate_plugins($addon['file'], true, false);
            
            // Remove from addon options
            $options_manager = $this->addon_manager->get_options_manager();
            if ($options_manager) {
                try {
                    $options_manager->ensure_addon_options_inactive($slug);
                } catch (Exception $e) {
                    // Silently fail - options cleanup is not critical
                }
            }
            
            // Show appropriate admin notice based on reason
            add_action('admin_notices', function() use ($addon, $reason) {
                $addon_name = esc_html($addon['name']);
                $license_url = admin_url('admin.php?page=explorexr-license');
                
                switch ($reason) {
                    case 'no_active_license':
                        $message = sprintf(
                            '<strong>%s has been deactivated.</strong> A valid and active ExploreXR license is required to use add-ons. <a href="%s">Activate your license</a> to use add-ons.',
                            $addon_name,
                            $license_url
                        );
                        break;
                        
                    case 'free_tier_no_addons':
                        $message = sprintf(
                            '<strong>%s has been deactivated.</strong> Your current license does not allow any add-ons. <a href="%s">Upgrade your license</a> to use add-ons.',
                            $addon_name,
                            $license_url
                        );
                        break;
                        
                    case 'exceeds_license_limit':
                        $message = sprintf(
                            '<strong>%s has been deactivated.</strong> You have exceeded your license add-on limit. <a href="%s">Manage your add-ons</a> or upgrade your license.',
                            $addon_name,
                            $license_url
                        );
                        break;
                        
                    case 'not_in_selections':
                        $message = sprintf(
                            '<strong>%s has been deactivated.</strong> This add-on is not selected in your license configuration. <a href="%s">Manage your add-ons</a>.',
                            $addon_name,
                            $license_url
                        );
                        break;
                        
                    case 'license_system_unavailable':
                        $message = sprintf(
                            '<strong>%s has been deactivated.</strong> License validation system is unavailable. Please check your ExploreXR Premium installation.',
                            $addon_name
                        );
                        break;
                        
                    default:
                        $message = sprintf(
                            '<strong>%s has been deactivated.</strong> This add-on is not authorized for your current license. <a href="%s">Check your license</a> for details.',
                            $addon_name,
                            $license_url
                        );
                }
                
                ?>
                <div class="notice notice-error is-dismissible">
                    <p><?php echo wp_kses_post($message); ?></p>
                </div>
                <?php
            });
            
        } catch (Exception $e) {
            // Show notice if deactivation failed
            add_action('admin_notices', function() use ($addon) {
                ?>
                <div class="notice notice-warning is-dismissible">
                    <p>
                        <strong><?php echo esc_html($addon['name']); ?> could not be automatically deactivated.</strong> 
                        Please manually deactivate this add-on as it's not authorized for your current license.
                    </p>
                </div>
                <?php
            });
        }
    }
    
    /**
     * Safely get license handler instance with proper error handling
     * 
     * @return ExploreXR_License_Handler|null
     */
    private function get_license_handler_safely() {
        try {
            // Check if class exists
            if (!class_exists('ExploreXR_License_Handler')) {
                return null;
            }
            
            // Use singleton instance
            return ExploreXR_License_Handler::instance();
            
        } catch (Error $e) {
            return null;
        } catch (Exception $e) {
            return null;
        }
    }
}
