<?php
/**
 * License Management Class
 *
 * @package VMPFence
 * @since 2.0.0
 * @since 2.2.1 Updated text-domain to vmpfence-security
 * @since 2.2.2 Added critical fixes to license validation and deactivation
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

/**
 * VMPFence License Class
 *
 * @since 2.0.0
 */
class VMPFence_License {

    /**
     * License API URL
     *
     * @var string
     */
    private $api_url;

    /**
     * License key
     *
     * @var string
     */
    private $license_key;

    /**
     * License status
     *
     * @var array
     */
    private $license_status;

    /**
     * API Client instance
     *
     * @var VMPFence_API_Client
     */
    private $api_client;

    /**
     * Constructor
     *
     * @since 2.0.0
     */
    public function __construct() {
        // Get dynamic API base URL
        $api_base_url = VMPFence_Endpoint_Config::get_api_base_url();
        $this->api_url = $api_base_url . '/auth/';
        
        $this->license_key = VMPFence_Config::get('license_key', '');
        $this->load_license_status();
        $this->init_hooks();
        
        // Initialize API client
        require_once VMPFENCE_PLUGIN_DIR . 'lib/class-api-client.php';
        $this->api_client = new VMPFence_API_Client();
    }

    /**
     * Initialize hooks
     *
     * @since 2.0.0
     * @return void
     */
    private function init_hooks() {
        // Schedule license check
        if (!wp_next_scheduled('vmpfence_license_check')) {
            wp_schedule_event(time(), 'daily', 'vmpfence_license_check');
        }

        add_action('vmpfence_license_check', array($this, 'scheduled_license_check'));
    }

    /**
     * Load license status from cache or database
     *
     * @since 2.0.0
     * @return void
     */
    private function load_license_status() {
        $this->license_status = get_transient('vmpfence_license_status');
        
        if (false === $this->license_status) {
            $this->license_status = get_option('vmpfence_license_status', array(
                'status' => 'invalid',
                'type' => VMPFence_Constants::LICENSE_FREE,
                'expires' => 0,
                'sites_allowed' => 1,
                'sites_used' => 1,
                'last_check' => 0
            ));
        }
    }

    /**
     * Validate license key
     *
     * @since 2.0.0
     * @param string $key License key
     * @return array Validation result
     */
    public function validate_license($key) {
        if (empty($key)) {
            return array(
                'success' => false,
                'message' => __('License key is required.', 'vmpfence-security'),
                'status' => 'invalid'
            );
        }

        // Use Newton Security API client
        $response = $this->api_client->activate_license($key, home_url());

        if (is_wp_error($response)) {
            // FREE TIER FALLBACK: API unavailable, set to FREE tier so features still work
            // ✅ CRITICAL FIX: Don't clear license_key on API error - preserve existing key
            // This prevents daily cron from clearing FREE user license keys when API is temporarily down
            self::update_license_settings(array(
                'license_type' => VMPFence_Constants::LICENSE_FREE,
                'license_key' => $key, // Preserve the license key
            ));
            
            // Reload license status
            $this->load_license_status();
            
            return array(
                'success' => true, // Important: TRUE so plugin doesn't error
                'message' => __('Running in FREE tier mode. Premium features unavailable. API error: ', 'vmpfence-security') . $response->get_error_message(),
                'status' => 'free_tier_fallback',
                'data' => $this->license_status
            );
        }

        if (!isset($response['success'])) {
            // FREE TIER FALLBACK: Invalid response, fall back to FREE tier
            // ✅ CRITICAL FIX: Don't clear license_key - preserve it
            self::update_license_settings(array(
                'license_type' => VMPFence_Constants::LICENSE_FREE,
                'license_key' => $key, // Preserve the license key
            ));
            
            // Reload license status
            $this->load_license_status();
            
            return array(
                'success' => true, // Plugin continues working
                'message' => __('Running in FREE tier mode. Invalid response from license server.', 'vmpfence-security'),
                'status' => 'free_tier_fallback',
                'data' => $this->license_status
            );
        }

        if ($response['success']) {
            // Clear manual deactivation flag since user is now activating
            VMPFence_Config::delete('license_manually_deactivated');
            
            // ✅ CRITICAL FIX: Use license_key from API response, not input parameter
            // FREE users: API returns actual DB key, not the generated form key
            // PREMIUM users: API returns same key, works either way
            $actual_license_key = isset($response['license_key']) ? $response['license_key'] : $key;
            
            // Use centralized license update function
            self::update_license_settings(array(
                'license_type' => $response['license_type'] ?? VMPFence_Constants::LICENSE_FREE,
                'license_key' => $actual_license_key,
                'expires_at' => $response['expires_at'] ?? null,
                'max_activations' => $response['max_activations'] ?? 1,
            ));
            
            // Reload license status
            $this->load_license_status();

            return array(
                'success' => true,
                'message' => __('License validated successfully.', 'vmpfence-security'),
                'status' => 'valid',
                'data' => $this->license_status
            );
        } else {
            // License validation failed, fall back to FREE tier
            // ✅ CRITICAL FIX: Don't clear license_key - preserve it
            // FREE users need their license_key even when validation temporarily fails
            self::update_license_settings(array(
                'license_type' => VMPFence_Constants::LICENSE_FREE,
                'license_key' => $key, // Preserve the license key
            ));
            
            // Reload license status
            $this->load_license_status();
            
            return array(
                'success' => true, // Plugin continues working in FREE tier
                'message' => __('License validation failed. Running in FREE tier mode. ', 'vmpfence-security') . (isset($response['error']) ? $response['error'] : __('License validation failed.', 'vmpfence-security')),
                'status' => 'free_tier_fallback',
                'data' => $this->license_status
            );
        }
    }

    /**
     * Deactivate license
     *
     * @since 2.0.0
     * @since 2.2.0 Clear premium cache on deactivation
     * @return array Deactivation result
     */
    public function deactivate_license() {
        $key = $this->license_key;

        if (empty($key)) {
            return array(
                'success' => false,
                'message' => __('No license key to deactivate.', 'vmpfence-security')
            );
        }

        // Use Newton Security API client
        $response = $this->api_client->deactivate_license($key, home_url());

        if (is_wp_error($response)) {
            return array(
                'success' => false,
                'message' => $response->get_error_message()
            );
        }

        // CRITICAL: Set manual deactivation flag to prevent auto-reactivation
        // This ensures scheduled checks won't reactivate premium automatically
        VMPFence_Config::set('license_manually_deactivated', true);

        // Clear premium cache immediately
        delete_transient('vmpfence_is_premium');

        // Clear license data
        VMPFence_Config::set('license_key', '');
        VMPFence_Config::set('license_type', VMPFence_Constants::LICENSE_FREE);

        $this->license_status = array(
            'status' => 'deactivated',
            'type' => VMPFence_Constants::LICENSE_FREE,
            'expires' => 0,
            'sites_allowed' => 1,
            'sites_used' => 1,
            'last_check' => time()
        );

        $this->save_license_status();

        return array(
            'success' => true,
            'message' => __('License deactivated successfully.', 'vmpfence-security')
        );
    }

    /**
     * Update all license settings consistently across the plugin
     * 
     * This is the SINGLE source of truth for updating license information
     *
     * @since 2.0.0
     * @since 2.2.0 Clear premium cache on license update
     * @param array $license_data License data from API response
     * @return void
     */
    public static function update_license_settings($license_data) {
        $license_type = $license_data['license_type'] ?? VMPFence_Constants::LICENSE_FREE;
        $license_key = $license_data['license_key'] ?? '';
        
        // Clear premium cache when license changes
        delete_transient('vmpfence_is_premium');
        
        // Update all VMPFence_Config settings
        VMPFence_Config::set('license_type', $license_type);
        // Always update license_key (even if empty, to clear old premium keys)
        VMPFence_Config::set('license_key', $license_key);
        
        // CRITICAL: Set ALL feature-specific license tiers for compatibility
        VMPFence_Config::set('firewall_license_tier', $license_type);
        VMPFence_Config::set('scanner_license_tier', $license_type);
        update_option('vmpfence_scanner_license_tier', $license_type);
        
        // Update vmpfence_license option for compatibility
        $license_option = array(
            'license_type' => $license_type,
        );
        if (!empty($license_key)) {
            $license_option['license_key'] = $license_key;
            $license_option['activated_at'] = current_time('mysql');
        } else {
            // Clear license_key when empty (user downgraded to free)
            $license_option['license_key'] = '';
            $license_option['validated_at'] = current_time('mysql');
        }
        update_option('vmpfence_license', $license_option);
        
        // Update license_status for VMPFence_License class
        update_option('vmpfence_license_status', array(
            'status' => 'valid',
            'type' => $license_type,
            'expires' => isset($license_data['expires_at']) ? strtotime($license_data['expires_at']) : 0,
            'sites_allowed' => $license_data['max_activations'] ?? ($license_type === 'premium' ? 5 : 1),
            'sites_used' => 1,
            'last_check' => time()
        ));
        
        // Clear any cached license data
        delete_transient('vmpfence_license_status');
    }

    /**
     * Check if license is valid
     *
     * @since 2.0.0
     * @return bool
     */
    public function is_valid() {
        return $this->license_status['status'] === 'valid';
    }

    /**
     * Check if license is expired
     *
     * @since 2.0.0
     * @return bool
     */
    public function is_expired() {
        if ($this->license_status['expires'] === 0) {
            return false; // Lifetime license
        }

        return time() > $this->license_status['expires'];
    }

    /**
     * Get license type
     *
     * @since 2.0.0
     * @return string
     */
    public function get_type() {
        return $this->license_status['type'];
    }

    /**
     * Check if license is premium (instance method)
     *
     * @since 2.2.0
     * @return bool
     */
    public function is_premium() {
        return self::is_premium_check();
    }

    /**
     * Get license type (static method for consistency)
     * 
     * This is the SINGLE source of truth for checking license type
     *
     * @since 2.0.0
     * @return string
     */
    public static function get_license_type() {
        // Check all possible locations and return the most authoritative
        $license_type = VMPFence_Config::get('license_type', VMPFence_Constants::LICENSE_FREE);
        
        // Also check vmpfence_license_status as backup
        $license_status = get_option('vmpfence_license_status', array());
        if (!empty($license_status['type'])) {
            // If there's a mismatch, update to match vmpfence_license_status (more authoritative)
            if ($license_status['type'] !== $license_type) {
                VMPFence_Config::set('license_type', $license_status['type']);
                $license_type = $license_status['type'];
            }
        }
        
        return $license_type;
    }

    /**
     * Check if license is premium or higher (static method with caching)
     * Can be called as: VMPFence_License::is_premium_check() or $license->is_premium()
     *
     * @since 2.2.0
     * @return bool
     */
    public static function is_premium_check() {
        // Check cached value first to avoid repeated checks (24 hour cache)
        $cached = get_transient('vmpfence_is_premium');
        if ($cached !== false) {
            return (bool)$cached;
        }
        
        $license_type = self::get_license_type();
        $is_premium = ($license_type === VMPFence_Constants::LICENSE_PREMIUM);
        
        // Cache for 24 hours
        set_transient('vmpfence_is_premium', $is_premium, 24 * HOUR_IN_SECONDS);
        
        return $is_premium;
    }

    /**
     * Get license status
     *
     * @since 2.0.0
     * @return array
     */
    public function get_status() {
        return $this->license_status;
    }

    /**
     * Get expiration date
     *
     * @since 2.0.0
     * @return int
     */
    public function get_expiration() {
        return $this->license_status['expires'];
    }

    /**
     * Get sites allowed
     *
     * @since 2.0.0
     * @return int
     */
    public function get_sites_allowed() {
        return $this->license_status['sites_allowed'];
    }

    /**
     * Get sites used
     *
     * @since 2.0.0
     * @return int
     */
    public function get_sites_used() {
        return $this->license_status['sites_used'];
    }

    /**
     * Check if feature is available
     *
     * @since 2.0.0
     * @param string $feature Feature name
     * @return bool
     */
    public function has_feature($feature) {
        $license_type = $this->get_type();

        // Define features by license type
        $features = array(
            VMPFence_Constants::LICENSE_FREE => array(
                'basic_waf',
                'basic_scanner',
                'login_security',
                'basic_blocking',
                'basic_traffic'
            ),
            VMPFence_Constants::LICENSE_PREMIUM => array(
                'basic_waf',
                'basic_scanner',
                'login_security',
                'basic_blocking',
                'basic_traffic',
                'advanced_waf',
                'advanced_scanner',
                'country_blocking',
                'real_time_updates',
                'premium_support'
            ),
            VMPFence_Constants::LICENSE_CARE => array(
                'basic_waf',
                'basic_scanner',
                'login_security',
                'basic_blocking',
                'basic_traffic',
                'advanced_waf',
                'advanced_scanner',
                'country_blocking',
                'real_time_updates',
                'premium_support',
                'central_management',
                'site_cleaning',
                'priority_support'
            ),
            VMPFence_Constants::LICENSE_RESPONSE => array(
                'basic_waf',
                'basic_scanner',
                'login_security',
                'basic_blocking',
                'basic_traffic',
                'advanced_waf',
                'advanced_scanner',
                'country_blocking',
                'real_time_updates',
                'premium_support',
                'central_management',
                'site_cleaning',
                'priority_support',
                'emergency_response',
                'custom_rules',
                'api_access'
            )
        );

        if (!isset($features[$license_type])) {
            return false;
        }

        return in_array($feature, $features[$license_type]);
    }

    /**
     * Get feature gate message
     *
     * @since 2.0.0
     * @param string $feature Feature name
     * @return string
     */
    public function get_feature_gate_message($feature) {
        $messages = array(
            'advanced_waf' => __('Advanced WAF features require a Premium license or higher.', 'vmpfence-security'),
            'country_blocking' => __('Country blocking requires a Premium license or higher.', 'vmpfence-security'),
            'real_time_updates' => __('Real-time threat intelligence updates require a Premium license or higher.', 'vmpfence-security'),
            'central_management' => __('Central management features require a Care license or higher.', 'vmpfence-security'),
            'site_cleaning' => __('Automated site cleaning requires a Care license or higher.', 'vmpfence-security'),
            'emergency_response' => __('Emergency response service requires a Response license.', 'vmpfence-security'),
            'api_access' => __('API access requires a Response license.', 'vmpfence-security')
        );

        return $messages[$feature] ?? __('This feature requires a higher license tier.', 'vmpfence-security');
    }

    /**
     * Scheduled license check
     *
     * @since 2.0.0
     * @return void
     */
    public function scheduled_license_check() {
        // CRITICAL: Don't auto-reactivate if user manually deactivated
        $manually_deactivated = VMPFence_Config::get('license_manually_deactivated', false);
        if ($manually_deactivated) {
            // User manually deactivated - skip automatic reactivation
            return;
        }
        
        if (empty($this->license_key)) {
            return;
        }

        $this->validate_license($this->license_key);
    }

    /**
     * Get license renewal URL
     *
     * @since 2.0.0
     * @return string
     */
    public function get_renewal_url() {
        return 'https://vmpfence.com/renew/?key=' . urlencode($this->license_key);
    }

    /**
     * Get upgrade URL
     *
     * @since 2.0.0
     * @param string $to_type Target license type
     * @return string
     */
    public function get_upgrade_url($to_type = '') {
        $url = 'https://vmpfence.com/upgrade/';
        
        if (!empty($this->license_key)) {
            $url .= '?key=' . urlencode($this->license_key);
        }

        if (!empty($to_type)) {
            $url .= '&to=' . urlencode($to_type);
        }

        return $url;
    }

    /**
     * Save license status
     *
     * @since 2.0.0
     * @return void
     */
    private function save_license_status() {
        update_option('vmpfence_license_status', $this->license_status);
        set_transient('vmpfence_license_status', $this->license_status, 86400); // Cache for 24 hours
    }

    /**
     * Get license info for display
     *
     * @since 2.0.0
     * @return array
     */
    public function get_license_info() {
        $info = array(
            'key' => $this->license_key,
            'status' => $this->license_status['status'],
            'type' => $this->license_status['type'],
            'type_name' => $this->get_license_type_name($this->license_status['type']),
            'expires' => $this->license_status['expires'],
            'expires_formatted' => '',
            'sites_allowed' => $this->license_status['sites_allowed'],
            'sites_used' => $this->license_status['sites_used'],
            'last_check' => $this->license_status['last_check'],
            'last_check_formatted' => '',
            'is_valid' => $this->is_valid(),
            'is_expired' => $this->is_expired(),
            'days_until_expiry' => 0
        );

        // Format expiration date
        if ($info['expires'] > 0) {
            $info['expires_formatted'] = date_i18n(get_option('date_format'), $info['expires']);
            $info['days_until_expiry'] = max(0, ceil(($info['expires'] - time()) / 86400));
        } else {
            $info['expires_formatted'] = __('Never', 'vmpfence-security');
        }

        // Format last check date
        if ($info['last_check'] > 0) {
            $info['last_check_formatted'] = date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $info['last_check']);
        }

        return $info;
    }

    /**
     * Get license type name
     *
     * @since 2.0.0
     * @param string $type License type
     * @return string
     */
    private function get_license_type_name($type) {
        $names = array(
            VMPFence_Constants::LICENSE_FREE => __('Free', 'vmpfence-security'),
            VMPFence_Constants::LICENSE_PREMIUM => __('Premium', 'vmpfence-security'),
            VMPFence_Constants::LICENSE_CARE => __('Care', 'vmpfence-security'),
            VMPFence_Constants::LICENSE_RESPONSE => __('Response', 'vmpfence-security')
        );

        return $names[$type] ?? __('Unknown', 'vmpfence-security');
    }

    /**
     * Generate trial license
     *
     * @since 2.0.0
     * @param string $email Email address
     * @return array
     */
    public function generate_trial($email) {
        if (!is_email($email)) {
            return array(
                'success' => false,
                'message' => __('Valid email address is required.', 'vmpfence-security')
            );
        }

        // Trial generation will be implemented when API endpoint is ready
        // For now, return a message to contact support
        return array(
            'success' => false,
            'message' => __('Trial licenses are not yet available. Please contact support for a trial key.', 'vmpfence-security')
        );
    }

    /**
     * Check license limitations
     *
     * @since 2.0.0
     * @param string $feature Feature to check
     * @return bool
     */
    public function check_limitations($feature) {
        if (!$this->is_valid()) {
            return false;
        }

        // Check feature-specific limitations
        switch ($feature) {
            case 'scan_frequency':
                // Free: Once per day, Premium+: Any frequency
                if ($this->get_type() === VMPFence_Constants::LICENSE_FREE) {
                    $last_scan = get_option('vmpfence_last_scan_time', 0);
                    return (time() - $last_scan) >= 86400; // 24 hours
                }
                return true;

            case 'sites_limit':
                return $this->license_status['sites_used'] < $this->license_status['sites_allowed'];

            default:
                return $this->has_feature($feature);
        }
    }
}
