<?php
if (!defined('ABSPATH')) exit;

class VMO_Subscription_Manager {
    
    public function __construct() {
        add_action('wp_ajax_vmo_subscription_checkout', [$this, 'handle_checkout']);
        add_action('admin_init', [$this, 'register_settings']);
        add_action('admin_init', [$this, 'verify_stripe_session'], 1);
    }

    private function get_or_create_installation_id() {
        $id = trim((string) get_option('vmo_installation_id', ''));
        if ($id !== '') {
            return $id;
        }
        if (function_exists('wp_generate_uuid4')) {
            $id = wp_generate_uuid4();
        } else {
            try {
                $id = bin2hex(random_bytes(16));
            } catch (Exception $e) {
                $id = md5(uniqid('', true));
            }
        }
        update_option('vmo_installation_id', $id, false);
        return $id;
    }

    private function local_checkout_entitlement_ready() {
        $user_id = get_current_user_id();
        if ($user_id <= 0) return false;
        $license_key = trim((string) get_option('vmo_license_key', ''));
        if ($license_key === '') {
            $license_key = trim((string) get_user_meta($user_id, 'vmo_license_key', true));
        }
        $installation_id = trim((string) get_option('vmo_installation_id', ''));
        $plan = sanitize_key((string) get_user_meta($user_id, 'vmo_subscription_status', true));
        $payment = sanitize_key((string) get_user_meta($user_id, 'vmo_subscription_payment_status', true));
        $lock = strtolower((string) get_user_meta($user_id, 'vmo_service_lock_status', true));
        $balance = (int) get_user_meta($user_id, 'vmo_token_balance', true);
        $valid_plans = array('tester','starter','pro','elite','enterprise','premium','business','active','paid');
        $payment_ok = in_array($payment, array('paid','active','trialing'), true);
        return $license_key !== '' && $installation_id !== '' && in_array($plan, $valid_plans, true) && $payment_ok && $lock !== 'locked' && $balance > 0;
    }

    public function verify_stripe_session() {
        $payment_status = sanitize_key((string)($_GET['payment'] ?? $_GET['vmo_payment'] ?? $_GET['vmo_status'] ?? ''));
        $raw_session_id = $_GET['vmo_cs'] ?? $_GET['session_id'] ?? '';
        if ($raw_session_id === '' || $payment_status !== 'success') {
            return;
        }

        $session_id = sanitize_text_field(wp_unslash($raw_session_id));
        if ($session_id === '' || strtoupper($session_id) === 'CHECKOUT_SESSION_ID') {
            update_user_meta(get_current_user_id(), 'vmo_last_vmo_notice', wp_json_encode(array(
                'type' => 'error',
                'message' => 'Stripe returned without a real checkout session ID. Please retry checkout after updating VMO.',
                'created_at' => current_time('mysql'),
            )));
            return;
        }
        // Do NOT blindly skip an already-seen Stripe session. Previous builds could
        // mark the session processed before the local client had actually saved the
        // license/entitlement, leaving the user in a payment-required loop. Only skip
        // when this install already has a usable local entitlement.
        if (get_transient('vmo_processed_' . $session_id) && $this->local_checkout_entitlement_ready()) {
            return;
        }

        // If the transient exists but the local license is still missing/locked, force
        // recovery by asking Master again. Master verification is idempotent.
        if (get_transient('vmo_processed_' . $session_id) && !$this->local_checkout_entitlement_ready()) {
            delete_transient('vmo_processed_' . $session_id);
        }

        // ── Client mode: verify via master proxy ──
        if (defined('VMO_CLIENT_MODE') && VMO_CLIENT_MODE === true) {
            $verified = $this->verify_stripe_session_via_master($session_id);
            if ($verified && !headers_sent() && !wp_doing_ajax()) {
                wp_safe_redirect(admin_url('admin.php?page=vmo-ai-builder-main&vmo_checkout_activated=1&vmo_payment=success'));
                exit;
            }
            return;
        }

        $secret_key = get_option('vmo_stripe_secret_key');
        if (!$secret_key) return;

        if (!class_exists('\Stripe\Stripe')) {
            if (file_exists(VMO_AI_BUILDER_DIR . 'vendor/autoload.php')) {
                require_once VMO_AI_BUILDER_DIR . 'vendor/autoload.php';
            } else {
                 return; // Cannot verify
            }
        }

        try {
            \Stripe\Stripe::setApiKey($secret_key);
            $session = \Stripe\Checkout\Session::retrieve($session_id);

            if ($session->payment_status === 'paid') {
                $user_id = get_current_user_id();
                if (!$user_id) return;

                // Determine plan from metadata if possible, or line items
                $plan = $session->metadata->plan ?? 'unknown';

                // Update User Status
                if ($plan !== 'unknown') {
                    
                    // Grant tokens based on plan (basic logic)
                    $tokens = 0;
                    $is_pack = in_array($plan, ['phone_m', 'phone_l', 'power_dialer', 'phone_xl'], true);

                    if ($is_pack) {
                        switch ($plan) {
                            case 'phone_m':
                                $tokens = 252000;
                                break;
                            case 'phone_l':
                                $tokens = 630000;
                                break;
                            case 'power_dialer':
                                $tokens = 1417500;
                                break;
                            case 'phone_xl':
                                $tokens = 2000000;
                                break;
                        }
                    } elseif (function_exists('vmo_get_plan_checkout_token_grant')) {
                        $tokens = vmo_get_plan_checkout_token_grant($plan, 0);
                    }

                    // For Packs: Do NOT change subscription status, just add tokens + expiry
                    if ($is_pack) {
                        $expiry = time() + YEAR_IN_SECONDS;
                        update_user_meta($user_id, 'vmo_phone_pack_expiry', $expiry);
                        // Also flag that they own this pack usage right
                        update_user_meta($user_id, 'vmo_has_phone_pack', 'true');
                    } else {
                        // For Main Plans: Update Status
                        update_user_meta($user_id, 'vmo_subscription_status', $plan);
                        update_user_meta($user_id, 'vmo_last_active_subscription_plan', $plan);
                        update_option('vmo_plan', $plan, false);
                        if (function_exists('vmo_queue_plan_signup_bonus')) {
                            vmo_queue_plan_signup_bonus($user_id, $plan);
                        }

                        // Generate license key for master/client authentication
                        if ( function_exists( 'vmo_generate_license_key' ) ) {
                            $license_result = vmo_generate_license_key( $user_id, $plan );
                            if ( is_wp_error( $license_result ) ) {
                                error_log( 'VMO Subscription: License key generation failed — ' . $license_result->get_error_message() );
                            }
                        }
                    }

                    if ($tokens > 0) {
                        $current = (int) get_user_meta($user_id, 'vmo_token_balance', true);
                        update_user_meta($user_id, 'vmo_token_balance', $current + $tokens);
                    }

                    // ✅ STAGE 16: Clear local locks and activate access
                    update_user_meta($user_id, 'vmo_entitlement_status', 'active');
                    update_user_meta($user_id, 'vmo_service_lock_status', 'unlocked');
                    update_user_meta($user_id, 'vmo_subscription_payment_status', 'paid');
                    update_user_meta($user_id, 'vmo_services_suspended', 0);
                    update_user_meta($user_id, 'vmo_service_access_enabled', 1);
                    delete_user_meta($user_id, 'vmo_service_lock_reason');
                    delete_user_meta($user_id, 'vmo_service_lock_context');
                    delete_user_meta($user_id, 'vmo_service_locked_at');

                    if (function_exists('vmo_unlock_user_services')) {
                        vmo_unlock_user_services($user_id, array(
                            'reason' => 'stripe_checkout_verified_on_server',
                            'payment_status' => 'paid',
                            'plan' => $plan,
                            'token_balance' => (int) get_user_meta($user_id, 'vmo_token_balance', true),
                        ));
                    }
                }

                // Mark as processed (expiry 24h)
                set_transient('vmo_processed_' . $session_id, true, DAY_IN_SECONDS);
            }

        } catch (\Exception $e) {
            error_log('VMO Stripe Verification Error: ' . $e->getMessage());
        }
    }

    public function register_settings() {
        // Register Annual Price IDs
        register_setting('vmo_settings_group', 'vmo_price_tester_annual');
        register_setting('vmo_settings_group', 'vmo_price_starter_annual');
        register_setting('vmo_settings_group', 'vmo_price_pro_annual');
        register_setting('vmo_settings_group', 'vmo_price_elite_annual');
        register_setting('vmo_settings_group', 'vmo_price_enterprise_annual');

        // Register QuickLaunch/Vultr Hosted Price IDs.
        register_setting('vmo_settings_group', 'vmo_quicklaunch_price_tester_monthly');
        register_setting('vmo_settings_group', 'vmo_quicklaunch_price_tester_annual');
        register_setting('vmo_settings_group', 'vmo_quicklaunch_price_starter_monthly');
        register_setting('vmo_settings_group', 'vmo_quicklaunch_price_starter_annual');
        register_setting('vmo_settings_group', 'vmo_quicklaunch_price_pro_monthly');
        register_setting('vmo_settings_group', 'vmo_quicklaunch_price_pro_annual');
        register_setting('vmo_settings_group', 'vmo_quicklaunch_price_elite_monthly');
        register_setting('vmo_settings_group', 'vmo_quicklaunch_price_elite_annual');
        register_setting('vmo_settings_group', 'vmo_quicklaunch_price_enterprise_monthly');
        register_setting('vmo_settings_group', 'vmo_quicklaunch_price_enterprise_annual');
        
        // Register Phone Booster Packs
        // register_setting('vmo_settings_group', 'vmo_price_pack_phone_s'); // Removed
        register_setting('vmo_settings_group', 'vmo_price_pack_phone_m');
        register_setting('vmo_settings_group', 'vmo_price_pack_phone_l');
        register_setting('vmo_settings_group', 'vmo_price_pack_power_dialer');
        register_setting('vmo_settings_group', 'vmo_price_pack_phone_xl');
    }

    public function handle_checkout() {
        check_ajax_referer('vmo_builder_nonce', 'security');

        $plan = sanitize_text_field($_POST['plan'] ?? '');
        $billing_cycle = sanitize_text_field($_POST['billing_cycle'] ?? 'monthly');
        $user_id = get_current_user_id();
        $user = get_userdata($user_id);

        if (!$user || empty($user->user_email)) {
            wp_send_json_error(['message' => 'User email is missing.']);
        }

        // ── Client mode: create checkout via master proxy ──
        if (defined('VMO_CLIENT_MODE') && VMO_CLIENT_MODE === true) {
            $this->handle_checkout_via_master($plan, $billing_cycle, $user);
            return;
        }

        // Map plan names to product/price option keys
        $plan_map = [
            // NOTE: monthly Price IDs are stored in the historical `vmo_plan_*_product` options
            // (the settings UI labels them as “Monthly Price ID”).
            'tester' => ['monthly_price' => 'vmo_plan_tester_product', 'annual_price' => 'vmo_price_tester_annual'],
            'starter' => ['monthly_price' => 'vmo_plan_starter_product', 'annual_price' => 'vmo_price_starter_annual'],
            'pro' => ['monthly_price' => 'vmo_plan_pro_product', 'annual_price' => 'vmo_price_pro_annual'],
            'elite' => ['monthly_price' => 'vmo_plan_elite_product', 'annual_price' => 'vmo_price_elite_annual'],
            'enterprise' => ['monthly_price' => 'vmo_plan_enterprise_product', 'annual_price' => 'vmo_price_enterprise_annual'],
            
            // Phone Packs (One-time, use monthly_price slot as generic price holder)
            // 'phone_s' => ['monthly_price' => 'vmo_price_pack_phone_s', 'annual_price' => 'vmo_price_pack_phone_s'], // Removed
            'phone_m' => ['monthly_price' => 'vmo_price_pack_phone_m', 'annual_price' => 'vmo_price_pack_phone_m'],
            'phone_l' => ['monthly_price' => 'vmo_price_pack_phone_l', 'annual_price' => 'vmo_price_pack_phone_l'],
            'power_dialer' => ['monthly_price' => 'vmo_price_pack_power_dialer', 'annual_price' => 'vmo_price_pack_power_dialer'],
            'phone_xl'     => ['monthly_price' => 'vmo_price_pack_phone_xl', 'annual_price' => 'vmo_price_pack_phone_xl']
        ];

        if (!isset($plan_map[$plan])) {
            wp_send_json_error(['message' => 'Invalid plan selected.']);
        }

        // Resolve Stripe Price ID
        $price_id = '';
        if ($billing_cycle === 'annual') {
            $price_id = trim((string) get_option($plan_map[$plan]['annual_price']));
        } else {
            // Monthly uses the value stored in `vmo_plan_*_product` (historical name).
            $price_id = trim((string) get_option($plan_map[$plan]['monthly_price']));

            // Back-compat: if someone previously set a dedicated monthly key like `vmo_price_starter`.
            if (!$price_id) {
                $legacy_monthly_key = 'vmo_price_' . $plan;
                $legacy_monthly_val = trim((string) get_option($legacy_monthly_key));
                if (strpos($legacy_monthly_val, 'price_') === 0) {
                    $price_id = $legacy_monthly_val;
                }
            }
        }

        // Enforce Stripe Price IDs for checkout.
        if ($price_id && strpos($price_id, 'price_') !== 0) {
            $price_id = '';
        }

        if (!$price_id) {
            if ($billing_cycle === 'annual') {
                 wp_send_json_error(['message' => 'Annual pricing for this plan is not yet configured.']);
            }
            wp_send_json_error(['message' => 'Plan is not configured. Please contact support.']);
        }

        // Initialize Stripe
        $secret_key = get_option('vmo_stripe_secret_key');
        if (!$secret_key) {
            wp_send_json_error(['message' => 'Payment system not configured.']);
        }

        if (!class_exists('\Stripe\Stripe')) {
            require_once VMO_AI_BUILDER_DIR . 'vendor/autoload.php';
        }

        try {
            \Stripe\Stripe::setApiKey($secret_key);

            // Determine if this is a one-time pack or a subscription
            $is_pack = in_array($plan, ['phone_m', 'phone_l', 'power_dialer', 'phone_xl']);
            $mode = $is_pack ? 'payment' : 'subscription';

            $checkout_args = [
                'payment_method_types' => ['card'],
                'customer_email' => $user->user_email,
                'allow_promotion_codes' => true, // ✅ Allow promo codes at checkout
                'line_items' => [[
                    'price' => $price_id,
                    'quantity' => 1,
                ]],
                'mode' => $mode,
                'success_url' => function_exists('vmo_client_safe_checkout_success_url') ? vmo_client_safe_checkout_success_url('vmo-ai-builder-main') : admin_url('admin.php?page=vmo-ai-builder-main&payment=success&vmo_cs={CHECKOUT_SESSION_ID}'),
                'cancel_url' => admin_url('admin.php?page=vmo-ai-builder-main&payment=cancel'),
                'metadata' => [
                    'user_id' => $user_id,
                    'plan' => $plan,
                    'billing_cycle' => $billing_cycle
                ]
            ];

            $session = \Stripe\Checkout\Session::create($checkout_args);

            wp_send_json_success(['checkout_url' => $session->url]);
        } catch (Exception $e) {
            error_log('VMO Stripe Error: ' . $e->getMessage());
            wp_send_json_error(['message' => 'Payment initialization failed: ' . $e->getMessage()]);
        }
    }

    /**
     * Client-mode: Create Stripe Checkout Session via master proxy.
     * The master holds the real Stripe key and Price IDs.
     */
    private function handle_checkout_via_master($plan, $billing_cycle, $user) {
        $proxy_base = defined('VMO_MASTER_PROXY_URL')
            ? preg_replace('#/proxy$#', '', VMO_MASTER_PROXY_URL)
            : rtrim(get_option('vmo_master_proxy_url', 'https://getvmo.com/wp-json/vmo-builder/v1/proxy'), '/proxy');

        $installation_id = $this->get_or_create_installation_id();

        $response = wp_remote_post($proxy_base . '/stripe-checkout/create', array(
            'headers' => array(
                'Content-Type'       => 'application/json',
                'X-VMO-Installation' => $installation_id,
                'X-VMO-License'      => get_option('vmo_license_key', ''),
                'X-VMO-Plan'         => get_user_meta(get_current_user_id(), 'vmo_subscription_status', true),
            ),
            'body'    => wp_json_encode(array(
                'plan'           => $plan,
                'billing_cycle'  => $billing_cycle,
                'customer_email' => $user->user_email,
                'success_url'    => function_exists('vmo_client_safe_checkout_success_url') ? vmo_client_safe_checkout_success_url('vmo-ai-builder-main') : admin_url('admin.php?page=vmo-ai-builder-main&payment=success&vmo_cs={CHECKOUT_SESSION_ID}'),
                'cancel_url'     => function_exists('vmo_client_safe_checkout_cancel_url') ? vmo_client_safe_checkout_cancel_url('vmo-ai-builder-main') : admin_url('admin.php?page=vmo-ai-builder-main&payment=cancel'),
                // Promo codes are entered in Stripe Checkout, not duplicated locally.
                'promo_code'     => '',
                'affiliate_ref'  => sanitize_text_field($_POST['affiliate_ref'] ?? $_GET['affiliate_ref'] ?? $_GET['ref'] ?? ''),
                'client_channel' => defined('VMO_CLIENT_DISTRIBUTION_CHANNEL') ? VMO_CLIENT_DISTRIBUTION_CHANNEL : get_option('vmo_client_distribution_channel', ''),
                'client_environment' => defined('VMO_CLIENT_ENVIRONMENT') ? VMO_CLIENT_ENVIRONMENT : get_option('vmo_client_environment', ''),
                'client_site_url' => home_url('/'),
                'client_installation_id' => $installation_id,
                'source'         => 'client_my_plan',
            )),
            'timeout' => 30,
        ));

        if (is_wp_error($response)) {
            wp_send_json_error(array('message' => 'Could not connect to payment server. Please try again.'));
            return;
        }

        $status = wp_remote_retrieve_response_code($response);
        $result = json_decode(wp_remote_retrieve_body($response), true);

        $checkout_url = '';
        if (is_array($result)) {
            $checkout_url = (string) ($result['checkout_url'] ?? $result['url'] ?? $result['data']['checkout_url'] ?? $result['data']['url'] ?? '');
        }

        if ($status >= 200 && $status < 300 && $checkout_url !== '') {
            wp_send_json_success(array('checkout_url' => esc_url_raw($checkout_url)));
        } else {
            $msg = is_array($result)
                ? ($result['message'] ?? $result['data']['message'] ?? $result['code'] ?? 'Payment initialization failed.')
                : 'Payment initialization failed.';
            wp_send_json_error(array(
                'message' => $msg,
                'http_code' => $status,
                'stage' => 'client_to_master_checkout',
            ));
        }
    }

    /**
     * Client-mode: Verify Stripe Checkout Session via master proxy.
     * Master verifies, updates its records, and returns the result.
     * Client updates local user meta accordingly.
     */
    private function verify_stripe_session_via_master($session_id) {
        $proxy_base = defined('VMO_MASTER_PROXY_URL')
            ? preg_replace('#/proxy$#', '', VMO_MASTER_PROXY_URL)
            : rtrim(get_option('vmo_master_proxy_url', 'https://getvmo.com/wp-json/vmo-builder/v1/proxy'), '/proxy');

        $installation_id = $this->get_or_create_installation_id();

        $response = wp_remote_post($proxy_base . '/stripe-checkout/verify', array(
            'headers' => array(
                'Content-Type'       => 'application/json',
                'X-VMO-Installation' => $installation_id,
                'X-VMO-License'      => get_option('vmo_license_key', ''),
                'X-VMO-Plan'         => get_user_meta(get_current_user_id(), 'vmo_subscription_status', true),
            ),
            'body'    => wp_json_encode(array('session_id' => $session_id)),
            'timeout' => 30,
        ));

        if (is_wp_error($response)) {
            error_log('VMO Client Stripe Verify Error: ' . $response->get_error_message());
            return false;
        }

        $http_code = (int) wp_remote_retrieve_response_code($response);
        $raw_body = (string) wp_remote_retrieve_body($response);
        $result = json_decode($raw_body, true);
        if (is_array($result) && isset($result['data']) && is_array($result['data']) && !isset($result['plan'])) {
            $result = array_merge($result['data'], array('success' => !empty($result['success']) || !empty($result['data']['success'])));
        }

        update_option('vmo_last_checkout_verify_http_code', $http_code, false);
        update_option('vmo_last_checkout_verify_response_preview', substr($raw_body, 0, 3000), false);
        update_option('vmo_last_checkout_verify_at', current_time('mysql'), false);

        if (empty($result['success'])) {
            update_user_meta(get_current_user_id(), 'vmo_last_vmo_notice', wp_json_encode(array(
                'type' => 'error',
                'message' => is_array($result) && !empty($result['message']) ? sanitize_text_field((string)$result['message']) : 'VMO could not verify this Stripe checkout session.',
                'http_code' => $http_code,
                'created_at' => current_time('mysql'),
            )));
            return false;
        }

        // Update local user records based on master's verification
        $user_id = get_current_user_id();
        if (!$user_id) return false;

        if (!empty($result['installation_id'])) {
            update_option('vmo_installation_id', sanitize_text_field((string)$result['installation_id']), false);
        } elseif (!empty($installation_id)) {
            update_option('vmo_installation_id', sanitize_text_field((string)$installation_id), false);
        }
        if (!empty($result['license_key'])) {
            update_option('vmo_license_key', sanitize_text_field((string)$result['license_key']), false);
            update_user_meta($user_id, 'vmo_license_key', sanitize_text_field((string)$result['license_key']));
        }

        $plan = !empty($result['plan']) && $result['plan'] !== 'unknown' ? sanitize_key((string)$result['plan']) : 'tester';
        $is_pack = !empty($result['is_pack']);
        if (!$is_pack) {
            update_user_meta($user_id, 'vmo_subscription_status', $plan);
            update_user_meta($user_id, 'vmo_last_active_subscription_plan', $plan);
            update_option('vmo_plan', $plan, false);
        } else {
            update_user_meta($user_id, 'vmo_phone_pack_expiry', time() + YEAR_IN_SECONDS);
            update_user_meta($user_id, 'vmo_has_phone_pack', 'true');
        }

        $current_balance = (int) get_user_meta($user_id, 'vmo_token_balance', true);
        $remote_balance = isset($result['token_balance']) ? (int) $result['token_balance'] : 0;
        $tokens_added = isset($result['tokens_added']) ? (int) $result['tokens_added'] : 0;
        $credits_granted = (int)($result['credits_granted'] ?? 0);
        $plan_grant = 0;
        if (!$is_pack && function_exists('vmo_get_plan_checkout_token_grant')) {
            $plan_grant = (int) vmo_get_plan_checkout_token_grant($plan, 0);
        }
        $new_balance = max($current_balance, $remote_balance, $tokens_added > 0 ? $current_balance + $tokens_added : 0, $credits_granted, $plan_grant, 1);
        update_user_meta($user_id, 'vmo_token_balance', $new_balance);
        update_user_meta($user_id, 'vmo_quicklaunch_available_tokens', $new_balance);

        // Any Stripe-verified success, including 100% discounted Checkout where
        // Stripe reports no_payment_required, must activate the local client.
        update_user_meta($user_id, 'vmo_entitlement_status', 'active');
        update_user_meta($user_id, 'vmo_service_lock_status', 'unlocked');
        update_user_meta($user_id, 'vmo_subscription_payment_status', 'paid');
        update_user_meta($user_id, 'vmo_last_verified_checkout_session', sanitize_text_field((string)$session_id));
        update_user_meta($user_id, 'vmo_last_verified_checkout_at', current_time('mysql'));
        set_transient('vmo_recent_checkout_success_' . $user_id, array('session_id'=>sanitize_text_field((string)$session_id), 'token_balance'=>$new_balance, 'plan'=>$plan), 6 * HOUR_IN_SECONDS);
        update_user_meta($user_id, 'vmo_services_suspended', 0);
        update_user_meta($user_id, 'vmo_service_access_enabled', 1);
        delete_user_meta($user_id, 'vmo_service_lock_reason');
        delete_user_meta($user_id, 'vmo_service_lock_context');
        delete_user_meta($user_id, 'vmo_service_locked_at');
        if (function_exists('vmo_unlock_user_services')) {
            vmo_unlock_user_services($user_id, array(
                'reason' => 'stripe_checkout_verified_on_client',
                'payment_status' => 'paid',
                'plan' => $plan,
                'token_balance' => $new_balance,
            ));
        }
        if (!empty($result['payment_status'])) {
            update_user_meta($user_id, 'vmo_last_checkout_payment_status', sanitize_key((string)$result['payment_status']));
        }

        if ($credits_granted > 0) {
            update_user_meta($user_id, 'vmo_discount_credit_cap_total', $credits_granted);
            update_user_meta($user_id, 'vmo_discount_credit_used', 0);
        }
        if (!empty($result['monthly_credit_cap'])) {
            update_user_meta($user_id, 'vmo_discount_monthly_credit_cap', (int)$result['monthly_credit_cap']);
            update_user_meta($user_id, 'vmo_discount_credit_period_start', current_time('mysql'));
            update_user_meta($user_id, 'vmo_discount_credit_period_end', gmdate('Y-m-d H:i:s', time() + 30 * DAY_IN_SECONDS));
        }
        if (!empty($result['credit_cap_period'])) {
            update_user_meta($user_id, 'vmo_discount_credit_cap_period', sanitize_key((string)$result['credit_cap_period']));
        }
        if (!empty($result['discount_code'])) {
            update_user_meta($user_id, 'vmo_active_discount_code', sanitize_text_field((string)$result['discount_code']));
        }
        $duration_days = (int)($result['duration_days'] ?? $result['trial_days'] ?? $result['access_days'] ?? 0);
        if ($duration_days <= 0 && !empty($result['discount_code'])) { $duration_days = 30; }
        if ($duration_days > 0) {
            $expires_ts = time() + ($duration_days * DAY_IN_SECONDS);
            update_user_meta($user_id, 'vmo_discount_access_expires_at', $expires_ts);
            update_user_meta($user_id, 'vmo_service_access_expires_at', $expires_ts);
            update_user_meta($user_id, 'vmo_subscription_renewal_date', gmdate('Y-m-d H:i:s', $expires_ts));
            update_user_meta($user_id, 'vmo_admin_reward_access_active', '1');
            update_user_meta($user_id, 'vmo_admin_reward_access_expires_at', $expires_ts);
        }
        update_user_meta($user_id, 'vmo_last_vmo_notice', wp_json_encode(array(
            'type'=>'success',
            'message'=>!empty($result['discount_code']) ? 'Your VMO discount checkout completed successfully. Your VMO credits/access were updated.' : 'Your VMO checkout completed successfully. Your VMO credits/access were activated.',
            'discount_code'=>!empty($result['discount_code']) ? sanitize_text_field((string)$result['discount_code']) : '',
            'credits_granted'=>$credits_granted,
            'payment_status'=>sanitize_key((string)($result['payment_status'] ?? '')),
            'created_at'=>current_time('mysql'),
        )));

        // Send VMO's own checkout/access confirmation email once per Stripe session.
        $email_once_key = 'vmo_checkout_email_sent_' . md5($session_id);
        if (!get_transient($email_once_key)) {
            $user = wp_get_current_user();
            $credit_for_notice = max((int) $credits_granted, (int) $new_balance);
            if ($user && !empty($user->user_email)) {
                $subject = 'Your VMO access and credits are active';
                $body = "Great news — your VMO checkout is complete.\n\n"
                    . "Workspace: " . home_url('/') . "\n"
                    . "Plan: " . strtoupper($plan) . "\n"
                    . "Credits available: " . number_format_i18n($credit_for_notice) . "\n";
                if (!empty($result['discount_code'])) {
                    $body .= "Discount / campaign code: " . sanitize_text_field((string)$result['discount_code']) . "\n";
                }
                if (!empty($result['payment_status'])) {
                    $body .= "Stripe status: " . sanitize_key((string)$result['payment_status']) . "\n";
                }
                $body .= "\nOpen VMO and click the red Business Wizard button if you have not completed your consultation yet. That consultation is what lets Jarvis build the right website, tools, documents, phone/email setup, and launch plan for your business.\n\nThank you,\nVMO";
                wp_mail($user->user_email, $subject, $body);
            }
            set_transient($email_once_key, 1, 7 * DAY_IN_SECONDS);
        }

        // Mark as processed locally too
        set_transient('vmo_processed_' . $session_id, true, DAY_IN_SECONDS);
        return true;
    }
}
