<?php
/**
 * M2C SSO Integration - Self-Contained Version
 * Works entirely within WordPress using local REST endpoints
 * No external API dependency - all session management is local
 */

if (!defined('ABSPATH')) {
    exit;
}

class M2C_SSO_Integration {
    
    private $option_name = 'm2c_sso_connection';
    private $session_option = 'm2c_sso_pending_sessions';
    
    /**
     * Verify wallet has an active M2C account
     * 
     * @param string $wallet_address The wallet address to verify
     * @return array ['valid' => bool, 'message' => string, 'membership' => array|null]
     */
    private function verify_m2c_account($wallet_address) {
        // Get gateway settings for API endpoint
        $gateway_settings = get_option('woocommerce_red_envelope_settings', array());
        $api_endpoint = !empty($gateway_settings['api_endpoint']) 
            ? rtrim($gateway_settings['api_endpoint'], '/') 
            : 'https://m2c.ab2bc.com/api';
        
        // Call M2C Backend to verify membership
        $url = $api_endpoint . '/bonds/wallet/' . $wallet_address . '/membership';
        
        $response = wp_remote_get($url, array(
            'timeout' => 10,
            'headers' => array(
                'Accept' => 'application/json',
            ),
        ));
        
        if (is_wp_error($response)) {
            // Network error — FAIL CLOSED: do NOT allow unverified wallets
            error_log('[M2C SSO] ERROR: Could not verify M2C membership - ' . $response->get_error_message());
            return array(
                'valid' => false,
                'message' => 'M2C verification service is unreachable. Cannot verify merchant account. Please check your network connection and try again.',
                'membership' => null,
                'verified' => false,
                'error_type' => 'network',
            );
        }
        
        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);
        
        if (!$data || !isset($data['success'])) {
            // Invalid response — FAIL CLOSED: do NOT allow unverified wallets
            error_log('[M2C SSO] ERROR: Invalid M2C membership response for wallet ' . substr($wallet_address, 0, 10) . '...');
            return array(
                'valid' => false,
                'message' => 'M2C verification returned an invalid response. The merchant account cannot be verified at this time.',
                'membership' => null,
                'verified' => false,
                'error_type' => 'invalid_response',
            );
        }
        
        if (!$data['success'] || !$data['isMember']) {
            // Wallet is NOT an M2C member - REJECT connection
            return array(
                'valid' => false,
                'message' => 'This wallet is not registered as an M2C member. Please open your Red Envelope Wallet at re.ab2bc.com, join M2C as a merchant, and complete the approval process.',
                'membership' => null,
                'verified' => true,
            );
        }
        
        // Wallet IS an M2C member - check for KYM (merchant verification)
        $has_kym = !empty($data['hasKYM']) && $data['kymStatus'] === 'approved';
        $membership_level = $data['membershipLevel'] ?? 'basic';
        
        return array(
            'valid' => true,
            'message' => $has_kym 
                ? 'M2C Merchant verified (' . $membership_level . ')' 
                : 'M2C Member verified (consider KYM verification for enhanced features)',
            'membership' => array(
                'userId' => $data['userId'] ?? null,
                'username' => $data['username'] ?? null,
                'hasKYC' => $data['hasKYC'] ?? false,
                'hasKYM' => $has_kym,
                'hasKYG' => $data['hasKYG'] ?? false,
                'membershipLevel' => $membership_level,
            ),
            'verified' => true,
        );
    }
    
    public function __construct() {
        // Add admin menu
        add_action('admin_menu', array($this, 'add_admin_menu'), 20);
        
        // Enqueue admin scripts
        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
        
        // Register AJAX handlers
        add_action('wp_ajax_m2c_sso_init', array($this, 'ajax_sso_init'));
        add_action('wp_ajax_m2c_sso_status', array($this, 'ajax_sso_status'));
        add_action('wp_ajax_m2c_sso_disconnect', array($this, 'ajax_sso_disconnect'));
        
        // Register REST API endpoints for wallet app
        add_action('rest_api_init', array($this, 'register_rest_endpoints'));
    }
    
    /**
     * Register REST endpoints for wallet app interaction
     */
    public function register_rest_endpoints() {
        // Endpoint for wallet app to scan and confirm
        register_rest_route('m2c/v1', '/sso/scan', array(
            'methods' => 'POST',
            'callback' => array($this, 'rest_sso_scan'),
            'permission_callback' => '__return_true'
        ));
        
        // Endpoint for wallet app to confirm connection
        register_rest_route('m2c/v1', '/sso/confirm', array(
            'methods' => 'POST',
            'callback' => array($this, 'rest_sso_confirm'),
            'permission_callback' => '__return_true'
        ));
        
        // Payment webhook endpoint (requires signature)
        register_rest_route('m2c/v1', '/payment-webhook', array(
            'methods' => 'POST',
            'callback' => array($this, 'handle_payment_webhook'),
            'permission_callback' => array($this, 'verify_webhook_signature')
        ));
        
        // Public payment notification endpoint (verifies tx on-chain, no signature needed)
        register_rest_route('m2c/v1', '/payment-notify', array(
            'methods' => 'POST',
            'callback' => array($this, 'handle_payment_notify'),
            'permission_callback' => '__return_true'
        ));

        // Payment status polling endpoint (used by checkout page instead of admin-ajax.php)
        // This avoids Cloudflare blocking AJAX requests for non-logged-in users
        register_rest_route('m2c/v1', '/payment-status', array(
            'methods' => 'GET',
            'callback' => array($this, 'rest_payment_status'),
            'permission_callback' => '__return_true',
            'args' => array(
                'order_id' => array('required' => true, 'type' => 'integer'),
                'order_key' => array('required' => true, 'type' => 'string'),
            )
        ));
    }

    /**
     * REST: Check payment status for an order (polling endpoint)
     * Used by checkout overlay JS instead of admin-ajax.php to avoid Cloudflare blocks
     */
    public function rest_payment_status($request) {
        // CRITICAL: Prevent Cloudflare/browser caching — this is a real-time polling endpoint
        nocache_headers();
        header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0');
        header('Pragma: no-cache');
        header('Expires: 0');
        header('CDN-Cache-Control: no-store');
        header('Cloudflare-CDN-Cache-Control: no-store');

        $order_id = absint($request->get_param('order_id'));
        $order_key = sanitize_text_field($request->get_param('order_key'));

        if (!$order_id || !$order_key) {
            return new WP_Error('invalid_request', 'Order ID and key required', array('status' => 400));
        }

        $order = wc_get_order($order_id);
        if (!$order || $order->get_order_key() !== $order_key) {
            return new WP_Error('not_found', 'Order not found', array('status' => 404));
        }

        $payment_status = $order->get_meta('_mre_payment_status');
        $order_status = $order->get_status();
        $tx_hash = $order->get_meta('_m2c_transaction_hash');

        $is_completed = ($payment_status === 'completed' || in_array($order_status, array('processing', 'completed')));

        error_log('[RE REST Poll] Order #' . $order_id . ' | status=' . $order_status . ' | meta=' . $payment_status . ' | completed=' . ($is_completed ? 'yes' : 'no'));

        return rest_ensure_response(array(
            'success' => true,
            'data' => array(
                'status' => $is_completed ? 'completed' : 'pending',
                'transaction_hash' => $tx_hash ?: null,
                'order_status' => $order_status,
            )
        ));
    }
    
    /**
     * REST: Handle QR scan from wallet app
     */
    public function rest_sso_scan($request) {
        $params = $request->get_json_params();
        $session_id = sanitize_text_field($params['sessionId'] ?? '');
        $wallet_address = sanitize_text_field($params['walletAddress'] ?? '');
        
        if (empty($session_id) || empty($wallet_address)) {
            return new WP_Error('invalid_request', 'Session ID and wallet address required', array('status' => 400));
        }
        
        // Get pending sessions
        $sessions = get_option($this->session_option, array());
        
        if (!isset($sessions[$session_id])) {
            return new WP_Error('session_not_found', 'Session not found or expired', array('status' => 404));
        }
        
        $session = $sessions[$session_id];
        
        // Check expiration
        if (time() > $session['expires_at']) {
            unset($sessions[$session_id]);
            update_option($this->session_option, $sessions);
            return new WP_Error('session_expired', 'Session has expired', array('status' => 400));
        }
        
        // Verify wallet has an active M2C account
        $verification = $this->verify_m2c_account($wallet_address);
        
        if (!$verification['valid']) {
            // Wallet does not have an active M2C account - reject connection
            return new WP_Error(
                'm2c_not_member',
                $verification['message'],
                array(
                    'status' => 403,
                    'requiresM2C' => true,
                    'registrationUrl' => 'https://re.ab2bc.com',
                    'helpText' => 'Please open your Red Envelope Wallet at re.ab2bc.com, join M2C as a merchant, and complete the approval process before connecting to merchant stores.'
                )
            );
        }
        
        // Update session with wallet info and verification status
        $sessions[$session_id]['wallet_address'] = $wallet_address;
        $sessions[$session_id]['email'] = sanitize_email($params['email'] ?? '');
        $sessions[$session_id]['user_id'] = sanitize_text_field($params['userId'] ?? $wallet_address);
        $sessions[$session_id]['status'] = 'scanned';
        $sessions[$session_id]['scanned_at'] = time();
        $sessions[$session_id]['m2c_verification'] = $verification;
        
        update_option($this->session_option, $sessions);
        
        return rest_ensure_response(array(
            'success' => true,
            'data' => array(
                'status' => 'scanned',
                'siteName' => get_bloginfo('name'),
                'siteUrl' => home_url(),
                'message' => 'Confirm to connect your wallet to this store',
                'm2cVerified' => $verification['verified'] ?? false,
                'm2cMembership' => $verification['membership'] ?? null,
                'verificationMessage' => $verification['message'] ?? null,
            )
        ));
    }
    
    /**
     * REST: Confirm connection from wallet app
     */
    public function rest_sso_confirm($request) {
        $params = $request->get_json_params();
        $session_id = sanitize_text_field($params['sessionId'] ?? '');
        $wallet_address = sanitize_text_field($params['walletAddress'] ?? '');
        $approve = isset($params['approve']) ? (bool)$params['approve'] : true;
        
        if (empty($session_id) || empty($wallet_address)) {
            return new WP_Error('invalid_request', 'Session ID and wallet address required', array('status' => 400));
        }
        
        // Get pending sessions
        $sessions = get_option($this->session_option, array());
        
        if (!isset($sessions[$session_id])) {
            return new WP_Error('session_not_found', 'Session not found', array('status' => 404));
        }
        
        $session = $sessions[$session_id];
        
        // Verify wallet matches
        if ($session['wallet_address'] !== $wallet_address) {
            return new WP_Error('wallet_mismatch', 'Wallet address does not match', array('status' => 403));
        }
        
        if (!$approve) {
            unset($sessions[$session_id]);
            update_option($this->session_option, $sessions);
            return rest_ensure_response(array(
                'success' => true,
                'data' => array('status' => 'cancelled')
            ));
        }
        
        // Generate credentials
        $merchant_id = 'MRC' . strtoupper(base_convert(time(), 10, 36)) . strtoupper(bin2hex(random_bytes(4)));
        $api_key = 're_live_' . bin2hex(random_bytes(16));
        $webhook_secret = 'whsec_' . bin2hex(random_bytes(16));
        
        // Save connection
        $connection = array(
            'merchant_id' => $merchant_id,
            'wallet_address' => $wallet_address,
            'email' => $session['email'] ?? '',
            'api_key' => $api_key,
            'webhook_secret' => $webhook_secret,
            'connected_at' => current_time('mysql')
        );
        
        update_option($this->option_name, $connection);
        
        // Update gateway settings with wallet
        $gateway_settings = get_option('woocommerce_red_envelope_settings', array());
        $gateway_settings['merchant_wallet'] = $wallet_address;
        update_option('woocommerce_red_envelope_settings', $gateway_settings);
        
        // Mark session as completed
        $sessions[$session_id]['status'] = 'completed';
        $sessions[$session_id]['completed_at'] = time();
        update_option($this->session_option, $sessions);
        
        return rest_ensure_response(array(
            'success' => true,
            'data' => array(
                'status' => 'completed',
                'merchantId' => $merchant_id,
                'webhookUrl' => rest_url('m2c/v1/payment-webhook'),
                'webhookSecret' => $webhook_secret,
                'siteUrl' => home_url(),
                'siteName' => get_bloginfo('name'),
                'message' => 'Successfully connected to ' . get_bloginfo('name')
            )
        ));
    }
    
    /**
     * Verify webhook signature
     */
    public function verify_webhook_signature($request) {
        $connection = get_option($this->option_name);
        
        if (!$connection || empty($connection['webhook_secret'])) {
            return true;
        }
        
        $signature = $request->get_header('X-Webhook-Signature');
        $timestamp = $request->get_header('X-Webhook-Timestamp');
        
        if (!$signature || !$timestamp) {
            return false;
        }
        
        if (abs(time() - intval($timestamp)) > 300) {
            return false;
        }
        
        $body = $request->get_body();
        $expected = hash_hmac('sha256', $body . $timestamp, $connection['webhook_secret']);
        
        return hash_equals($expected, $signature);
    }
    
    /**
     * Handle payment webhook
     */
    public function handle_payment_webhook($request) {
        $data = $request->get_json_params();
        
        if (empty($data['orderId'])) {
            return new WP_Error('invalid_data', 'Order ID required', array('status' => 400));
        }
        
        $order = wc_get_order($data['orderId']);
        
        if (!$order) {
            return new WP_Error('order_not_found', 'Order not found', array('status' => 404));
        }
        
        if ($order->get_payment_method() !== 'red_envelope') {
            return new WP_Error('invalid_payment_method', 'Invalid payment method', array('status' => 400));
        }
        
        if (!empty($data['transactionHash'])) {
            $order->update_meta_data('_m2c_transaction_hash', sanitize_text_field($data['transactionHash']));
        }
        
        if (!empty($data['payerWallet'])) {
            $order->update_meta_data('_m2c_payer_wallet', sanitize_text_field($data['payerWallet']));
        }
        
        $order->payment_complete($data['transactionHash'] ?? '');
        $order->add_order_note(sprintf(
            __('AB2BC payment confirmed. TX: %s', 'ab2bc-red-envelope'),
            $data['transactionHash'] ?? 'N/A'
        ));
        $order->save();
        
        return rest_ensure_response(array(
            'success' => true,
            'message' => 'Payment confirmed'
        ));
    }
    
    /**
     * Handle public payment notification (no signature required)
     * This is called directly from the wallet app after payment
     * For production, you may want to verify the transaction on-chain
     */
    public function handle_payment_notify($request) {
        $data = $request->get_json_params();
        
        error_log('[M2C Payment Notify] Received: ' . json_encode($data));
        
        if (empty($data['orderId'])) {
            return new WP_Error('invalid_data', 'Order ID required', array('status' => 400));
        }
        
        // Auto-detect test mode based on RPC endpoint
        $gateway_settings = get_option('woocommerce_red_envelope_settings', array());
        $rpc_endpoint = isset($gateway_settings['rpc_endpoint']) ? $gateway_settings['rpc_endpoint'] : 'https://rpc.aqy.ab2bc.com';
        $test_mode = $this->is_test_mode_endpoint($rpc_endpoint);
        
        error_log('[M2C Payment Notify] RPC: ' . $rpc_endpoint . ', Test Mode: ' . ($test_mode ? 'YES' : 'NO'));
        
        // In production mode, webhook notifications are not allowed - must verify on-chain
        if (!$test_mode) {
            // Verify the transaction on blockchain
            if (empty($data['transactionHash'])) {
                return new WP_Error('tx_required', 'Transaction hash required for production mode', array('status' => 400));
            }
            
            // Skip fake test transactions
            if (strpos($data['transactionHash'], 'stablecoin_') === 0 || strpos($data['transactionHash'], 'test_') === 0) {
                error_log('[M2C Payment Notify] Rejected test transaction in production mode: ' . $data['transactionHash']);
                return new WP_Error('invalid_tx', 'Test transactions not accepted in production mode', array('status' => 400));
            }
            
            // Verify transaction on blockchain
            $rpc_endpoint = isset($gateway_settings['rpc_endpoint']) ? $gateway_settings['rpc_endpoint'] : 'https://rpc.aqy.ab2bc.com';
            $merchant_wallet = isset($gateway_settings['merchant_wallet']) ? $gateway_settings['merchant_wallet'] : '';
            
            $verification = $this->verify_blockchain_transaction(
                $data['transactionHash'],
                $merchant_wallet,
                floatval($data['amount'] ?? 0),
                $rpc_endpoint
            );
            
            if (!$verification['valid']) {
                error_log('[M2C Payment Notify] Blockchain verification failed: ' . $verification['error']);
                return new WP_Error('verification_failed', $verification['error'], array('status' => 400));
            }
            
            error_log('[M2C Payment Notify] Blockchain verification passed for tx: ' . $data['transactionHash']);
        } else {
            error_log('[M2C Payment Notify] Test mode - accepting webhook without blockchain verification');
        }
        
        // Try to find order by order number
        $order_id = wc_get_order_id_by_order_key($data['orderKey'] ?? '');
        if (!$order_id) {
            // Try direct order ID/number lookup
            $order = wc_get_order($data['orderId']);
            if (!$order) {
                // Search by order number in recent PENDING orders only (prevents matching wrong order)
                foreach (wc_get_orders(array('limit' => 50, 'status' => array('pending', 'on-hold'), 'orderby' => 'date', 'order' => 'DESC')) as $recent_order) {
                    if ($recent_order->get_order_number() == $data['orderId']) {
                        $order = $recent_order;
                        break;
                    }
                }
            }
        } else {
            $order = wc_get_order($order_id);
        }
        
        if (!$order) {
            error_log('[M2C Payment Notify] Order not found: ' . $data['orderId']);
            return new WP_Error('order_not_found', 'Order not found', array('status' => 404));
        }
        
        // Check payment method
        if ($order->get_payment_method() !== 'red_envelope') {
            error_log('[M2C Payment Notify] Wrong payment method: ' . $order->get_payment_method());
            return new WP_Error('invalid_payment_method', 'Invalid payment method', array('status' => 400));
        }
        
        // Check if already paid
        if ($order->is_paid()) {
            return rest_ensure_response(array(
                'success' => true,
                'message' => 'Order already paid'
            ));
        }
        
        // Verify order is in pending status (not already processing/on-hold/cancelled)
        $order_status = $order->get_status();
        if (!in_array($order_status, array('pending', 'on-hold'))) {
            error_log('[M2C Payment Notify] Order #' . $order->get_id() . ' has unexpected status: ' . $order_status . ' — rejecting payment');
            return new WP_Error('invalid_order_status', 'Order is not awaiting payment (status: ' . $order_status . ')', array('status' => 400));
        }
        
        // Verify payment amount matches order total (5% tolerance for rounding/fees)
        if (!empty($data['amount'])) {
            $paid_amount = floatval($data['amount']);
            $order_total = floatval($order->get_total());
            if ($order_total > 0 && $paid_amount > 0) {
                $diff_pct = abs($paid_amount - $order_total) / $order_total * 100;
                if ($diff_pct > 5) {
                    error_log(sprintf(
                        '[M2C Payment Notify] Amount mismatch for order #%d: paid=%.2f, expected=%.2f (%.1f%% diff) — rejecting',
                        $order->get_id(), $paid_amount, $order_total, $diff_pct
                    ));
                    return new WP_Error('amount_mismatch',
                        sprintf('Payment amount %.2f does not match order total %.2f', $paid_amount, $order_total),
                        array('status' => 400)
                    );
                }
                error_log(sprintf('[M2C Payment Notify] Amount verified: paid=%.2f, expected=%.2f (%.1f%% diff)', $paid_amount, $order_total, $diff_pct));
            }
        }
        
        // Store transaction details
        if (!empty($data['transactionHash'])) {
            $order->update_meta_data('_m2c_transaction_hash', sanitize_text_field($data['transactionHash']));
        }
        
        if (!empty($data['payerWallet'])) {
            $order->update_meta_data('_m2c_payer_wallet', sanitize_text_field($data['payerWallet']));
        }
        
        if (!empty($data['amount'])) {
            $order->update_meta_data('_m2c_payment_amount', sanitize_text_field($data['amount']));
        }
        
        if (!empty($data['chain'])) {
            $order->update_meta_data('_m2c_payment_chain', sanitize_text_field($data['chain']));
        }
        
        // Apply shipping address from M2C KYC profile if provided
        if (!empty($data['shipping']) && is_array($data['shipping'])) {
            $shipping = $data['shipping'];
            $order->set_shipping_first_name(sanitize_text_field($shipping['first_name'] ?? ''));
            $order->set_shipping_last_name(sanitize_text_field($shipping['last_name'] ?? ''));
            $order->set_shipping_address_1(sanitize_text_field($shipping['address_1'] ?? ''));
            $order->set_shipping_city(sanitize_text_field($shipping['city'] ?? ''));
            $order->set_shipping_state(sanitize_text_field($shipping['state'] ?? ''));
            $order->set_shipping_postcode(sanitize_text_field($shipping['postcode'] ?? ''));
            $order->set_shipping_country(sanitize_text_field($shipping['country'] ?? ''));
            if (!empty($shipping['phone'])) {
                $order->set_shipping_phone(sanitize_text_field($shipping['phone']));
            }
            $order->add_order_note(__('Shipping address provided from M2C KYC profile.', 'ab2bc-red-envelope'));
            error_log('[M2C Payment Notify] Shipping address applied to order: ' . $order->get_id());
        }
        
        // Mark payment complete and explicitly set meta (needed for polling detection)
        $order->update_meta_data('_mre_payment_status', 'completed');
        $order->update_meta_data('_mre_payment_timestamp', time());
        $order->payment_complete($data['transactionHash'] ?? '');
        $order->add_order_note(sprintf(
            __('AB2BC payment received via wallet notification. TX: %s, Payer: %s, Amount: %s %s', 'ab2bc-red-envelope'),
            $data['transactionHash'] ?? 'N/A',
            $data['payerWallet'] ?? 'N/A',
            $data['amount'] ?? 'N/A',
            $data['currency'] ?? 'USDC'
        ));
        $order->save();
        
        error_log('[M2C Payment Notify] Payment confirmed for order: ' . $order->get_id());
        
        return rest_ensure_response(array(
            'success' => true,
            'message' => 'Payment confirmed',
            'orderId' => $order->get_id()
        ));
    }
    
    /**
     * Determine if test mode is enabled
     * Checks explicit setting first, then auto-detects based on RPC endpoint
     * 
     * @param string $rpc_endpoint The RPC endpoint URL (for auto-detection)
     * @return bool True if test mode, false for production
     */
    private function is_test_mode_endpoint($rpc_endpoint) {
        // Get gateway settings
        $gateway_settings = get_option('woocommerce_red_envelope_settings', array());
        $test_mode_setting = isset($gateway_settings['test_mode']) ? $gateway_settings['test_mode'] : 'auto';
        
        // Check explicit test_mode setting first
        if ($test_mode_setting === 'yes') {
            return true; // Force test mode
        }
        if ($test_mode_setting === 'no') {
            return false; // Force production mode
        }
        
        // Auto-detect based on RPC endpoint
        $url = strtolower($rpc_endpoint);
        
        // Check for local IP patterns
        if (preg_match('/192\.168\.\d+\.\d+/', $url)) return true;
        if (preg_match('/10\.\d+\.\d+\.\d+/', $url)) return true;
        if (preg_match('/172\.(1[6-9]|2\d|3[01])\.\d+\.\d+/', $url)) return true;
        
        // Check for localhost patterns
        if (strpos($url, 'localhost') !== false) return true;
        if (strpos($url, '127.0.0.1') !== false) return true;
        if (strpos($url, '0.0.0.0') !== false) return true;
        
        // Check for devnet/testnet keywords
        if (strpos($url, 'devnet') !== false) return true;
        if (strpos($url, 'testnet') !== false) return true;
        if (strpos($url, 'local') !== false) return true;
        
        // Default: production mode
        return false;
    }
    
    /**
     * Verify a transaction on the blockchain
     * 
     * @param string $tx_hash Transaction hash/digest
     * @param string $expected_recipient Expected recipient wallet address
     * @param float $expected_amount Expected payment amount
     * @param string $rpc_endpoint Blockchain RPC endpoint
     * @return array ['valid' => bool, 'error' => string|null]
     */
    private function verify_blockchain_transaction($tx_hash, $expected_recipient, $expected_amount, $rpc_endpoint) {
        try {
            // Query the blockchain for transaction details
            $response = wp_remote_post($rpc_endpoint, array(
                'headers' => array('Content-Type' => 'application/json'),
                'body' => json_encode(array(
                    'jsonrpc' => '2.0',
                    'id' => 1,
                    'method' => 'sui_getTransactionBlock',
                    'params' => array(
                        $tx_hash,
                        array(
                            'showInput' => true,
                            'showEffects' => true,
                            'showBalanceChanges' => true,
                        )
                    )
                )),
                'timeout' => 30
            ));
            
            if (is_wp_error($response)) {
                return array('valid' => false, 'error' => 'RPC request failed: ' . $response->get_error_message());
            }
            
            $body = json_decode(wp_remote_retrieve_body($response), true);
            
            if (isset($body['error'])) {
                return array('valid' => false, 'error' => 'RPC error: ' . ($body['error']['message'] ?? 'Unknown error'));
            }
            
            if (!isset($body['result'])) {
                return array('valid' => false, 'error' => 'Transaction not found on blockchain');
            }
            
            $tx = $body['result'];
            
            // Check transaction was successful
            if (!isset($tx['effects']['status']['status']) || $tx['effects']['status']['status'] !== 'success') {
                return array('valid' => false, 'error' => 'Transaction was not successful');
            }
            
            // Check balance changes for USDC payment to merchant
            $balance_changes = $tx['balanceChanges'] ?? array();
            $found_payment = false;
            
            foreach ($balance_changes as $change) {
                // Look for USDC transfer to merchant wallet
                $owner = $change['owner']['AddressOwner'] ?? '';
                $coin_type = $change['coinType'] ?? '';
                $amount = abs(floatval($change['amount'] ?? 0));
                
                // Check if this is a stablecoin (USDC or USDL2) credit to the merchant
                // Both use regulated_coin::REGULATED_COIN type from different package IDs
                $is_stablecoin = (strpos($coin_type, 'regulated_coin') !== false || 
                                  strpos($coin_type, 'REGULATED_COIN') !== false ||
                                  strpos($coin_type, 'usdc') !== false || 
                                  strpos($coin_type, 'USDC') !== false);
                
                if (strtolower($owner) === strtolower($expected_recipient) && 
                    floatval($change['amount']) > 0 && $is_stablecoin) {
                    
                    // All regulated_coin on AQY chain uses 9 decimals (both USDC and USDL2
                    // are the same on-chain token minted from M2C_PACKAGE_ID)
                    $decimals = 9;
                    $token_amount = $amount / pow(10, $decimals);
                    
                    error_log('[M2C Verify] Found stablecoin credit: ' . $token_amount . ' (decimals: ' . $decimals . ', type: ' . substr($coin_type, 0, 40) . '...)');
                    
                    // Allow 1% tolerance for fees
                    if ($token_amount >= $expected_amount * 0.99) {
                        $found_payment = true;
                        break;
                    }
                }
            }
            
            if (!$found_payment) {
                return array('valid' => false, 'error' => 'Payment to merchant wallet not found in transaction');
            }
            
            return array('valid' => true, 'error' => null);
            
        } catch (Exception $e) {
            return array('valid' => false, 'error' => 'Verification error: ' . $e->getMessage());
        }
    }
    
    /**
     * Add admin menu
     */
    public function add_admin_menu() {
        add_submenu_page(
            'woocommerce',
            __('M2C SSO Setup', 'ab2bc-red-envelope'),
            __('AB2BC Wallet Connection', 'ab2bc-red-envelope'),
            'manage_woocommerce',
            'm2c-sso-setup',
            array($this, 'render_sso_page')
        );
    }
    
    /**
     * Enqueue admin scripts
     */
    public function enqueue_admin_scripts($hook) {
        if (strpos($hook, 'm2c-sso-setup') === false) {
            return;
        }
        
        wp_enqueue_style(
            'm2c-sso-admin',
            MRE_PLUGIN_URL . 'assets/css/sso-admin.css',
            array(),
            MRE_VERSION
        );
        
        wp_enqueue_script(
            'm2c-sso-admin',
            MRE_PLUGIN_URL . 'assets/js/sso-admin.js',
            array('jquery'),
            MRE_VERSION,
            true
        );
        
        wp_localize_script('m2c-sso-admin', 'm2cSSO', array(
            'ajaxUrl' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('m2c_sso_nonce'),
            'restUrl' => rest_url('m2c/v1/'),
            'i18n' => array(
                'connecting' => __('Connecting...', 'ab2bc-red-envelope'),
                'scanQR' => __('Scan with Red Envelope App', 'ab2bc-red-envelope'),
                'waitingConfirm' => __('Waiting for confirmation...', 'ab2bc-red-envelope'),
                'connected' => __('Connected!', 'ab2bc-red-envelope'),
                'error' => __('Connection failed', 'ab2bc-red-envelope'),
                'expired' => __('Session expired, please try again', 'ab2bc-red-envelope')
            )
        ));
    }
    
    /**
     * Render SSO page
     */
    public function render_sso_page() {
        $connection = get_option($this->option_name);
        $is_connected = !empty($connection) && !empty($connection['wallet_address']);
        ?>
        <div class="wrap m2c-sso-wrap">
            <h1><?php _e('AB2BC Wallet Connection', 'ab2bc-red-envelope'); ?></h1>
            
            <div class="m2c-sso-container">
                <?php if ($is_connected): ?>
                    <div class="m2c-sso-connected">
                        <div class="m2c-sso-status-badge connected">
                            <span class="dashicons dashicons-yes-alt"></span>
                            <?php _e('Connected', 'ab2bc-red-envelope'); ?>
                        </div>
                        
                        <div class="m2c-sso-info-cards">
                            <div class="m2c-sso-card">
                                <h3><?php _e('Wallet Address', 'ab2bc-red-envelope'); ?></h3>
                                <code class="wallet-address"><?php echo esc_html($connection['wallet_address']); ?></code>
                            </div>
                            
                            <div class="m2c-sso-card">
                                <h3><?php _e('Merchant ID', 'ab2bc-red-envelope'); ?></h3>
                                <code><?php echo esc_html($connection['merchant_id'] ?? 'N/A'); ?></code>
                            </div>
                            
                            <div class="m2c-sso-card">
                                <h3><?php _e('Connected Since', 'ab2bc-red-envelope'); ?></h3>
                                <span><?php echo esc_html($connection['connected_at'] ?? 'N/A'); ?></span>
                            </div>
                        </div>
                        
                        <div class="m2c-sso-actions">
                            <button type="button" id="m2c-disconnect" class="button button-link-delete">
                                <span class="dashicons dashicons-dismiss"></span>
                                <?php _e('Disconnect', 'ab2bc-red-envelope'); ?>
                            </button>
                        </div>
                    </div>
                    
                <?php else: ?>
                    <div class="m2c-sso-disconnected">
                        <div class="m2c-sso-intro">
                            <h2><?php _e('Connect Your Red Envelope Wallet', 'ab2bc-red-envelope'); ?></h2>
                            <p><?php _e('Scan the QR code with your Red Envelope Wallet app to connect your store and start receiving USDC payments.', 'ab2bc-red-envelope'); ?></p>
                        </div>
                        
                        <div class="m2c-sso-qr-section">
                            <button type="button" id="m2c-generate-qr" class="button button-primary button-hero">
                                <span class="dashicons dashicons-smartphone"></span>
                                <?php _e('Generate QR Code to Connect', 'ab2bc-red-envelope'); ?>
                            </button>
                            
                            <div id="m2c-qr-container" style="display: none;">
                                <div id="m2c-qr-code"></div>
                                <p class="m2c-qr-instructions"><?php _e('Scan this QR code with your Red Envelope Wallet app', 'ab2bc-red-envelope'); ?></p>
                                <div id="m2c-qr-status" class="m2c-qr-status"></div>
                                <div id="m2c-qr-timer"></div>
                            </div>
                        </div>
                        
                        <div id="m2c-sso-message" class="m2c-sso-message" style="display: none;"></div>
                    </div>
                <?php endif; ?>
                
                <div class="m2c-sso-how-it-works">
                    <h3><?php _e('How M2C SSO Works', 'ab2bc-red-envelope'); ?></h3>
                    <div class="m2c-steps">
                        <div class="m2c-step">
                            <span class="step-number">1</span>
                            <span class="dashicons dashicons-admin-users"></span>
                            <h4><?php _e('Connect Wallet', 'ab2bc-red-envelope'); ?></h4>
                            <p><?php _e('Scan QR code with your Red Envelope Wallet to link your receiving wallet.', 'ab2bc-red-envelope'); ?></p>
                        </div>
                        <div class="m2c-step">
                            <span class="step-number">2</span>
                            <span class="dashicons dashicons-cart"></span>
                            <h4><?php _e('Customer Orders', 'ab2bc-red-envelope'); ?></h4>
                            <p><?php _e('Customers select Red Envelope Payment and get a payment QR code.', 'ab2bc-red-envelope'); ?></p>
                        </div>
                        <div class="m2c-step">
                            <span class="step-number">3</span>
                            <span class="dashicons dashicons-yes-alt"></span>
                            <h4><?php _e('Auto Confirmation', 'ab2bc-red-envelope'); ?></h4>
                            <p><?php _e('Orders automatically complete when payment is confirmed on-chain.', 'ab2bc-red-envelope'); ?></p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <?php
    }
    
    /**
     * AJAX: Initialize SSO session (local - no external API)
     */
    public function ajax_sso_init() {
        check_ajax_referer('m2c_sso_nonce', 'nonce');
        
        if (!current_user_can('manage_woocommerce')) {
            wp_send_json_error(array('message' => 'Unauthorized'));
            return;
        }
        
        // Generate session ID
        $session_id = 'sso_' . base_convert(time(), 10, 36) . '_' . bin2hex(random_bytes(8));
        $expires_at = time() + 600; // 10 minutes
        
        // Store session locally
        $sessions = get_option($this->session_option, array());
        
        // Clean expired sessions
        $sessions = array_filter($sessions, function($s) {
            return isset($s['expires_at']) && $s['expires_at'] > time();
        });
        
        $sessions[$session_id] = array(
            'status' => 'pending',
            'created_at' => time(),
            'expires_at' => $expires_at,
            'admin_user' => get_current_user_id()
        );
        
        update_option($this->session_option, $sessions);
        
        // Generate QR data using shorthand format the Red Envelope app expects
        // Format: { a: "sso_login", v: "1.0", sid: sessionId, site: siteUrl, name: siteName, t: timestamp, scan: scanEndpoint, confirm: confirmEndpoint }
        $qr_data = json_encode(array(
            'a' => 'sso_login',
            'v' => '1.0',
            'sid' => $session_id,
            'name' => get_bloginfo('name'),
            'site' => home_url(),
            't' => time(),
            'scan' => rest_url('m2c/v1/sso/scan'),
            'confirm' => rest_url('m2c/v1/sso/confirm')
        ));
        
        $qr_code_url = 'https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=' . urlencode($qr_data);
        
        wp_send_json_success(array(
            'sessionId' => $session_id,
            'qrData' => $qr_data,
            'qrCodeUrl' => $qr_code_url,
            'expiresAt' => date('c', $expires_at)
        ));
    }
    
    /**
     * AJAX: Check SSO status (local)
     */
    public function ajax_sso_status() {
        check_ajax_referer('m2c_sso_nonce', 'nonce');
        
        if (!current_user_can('manage_woocommerce')) {
            wp_send_json_error(array('message' => 'Unauthorized'));
            return;
        }
        
        $session_id = sanitize_text_field($_POST['session_id'] ?? '');
        
        if (empty($session_id)) {
            wp_send_json_error(array('message' => 'No session ID'));
            return;
        }
        
        $sessions = get_option($this->session_option, array());
        
        if (!isset($sessions[$session_id])) {
            wp_send_json_error(array('message' => 'Session not found'));
            return;
        }
        
        $session = $sessions[$session_id];
        
        // Check expiration
        if (time() > $session['expires_at']) {
            unset($sessions[$session_id]);
            update_option($this->session_option, $sessions);
            wp_send_json_success(array('status' => 'expired'));
            return;
        }
        
        $response = array(
            'status' => $session['status'],
            'expiresAt' => date('c', $session['expires_at'])
        );
        
        if ($session['status'] === 'scanned' || $session['status'] === 'completed') {
            $response['wallet'] = array(
                'address' => $session['wallet_address'] ?? null,
                'email' => $session['email'] ?? null
            );
        }
        
        if ($session['status'] === 'completed') {
            $connection = get_option($this->option_name);
            if ($connection) {
                $response['connection'] = $connection;
            }
        }
        
        wp_send_json_success($response);
    }
    
    /**
     * AJAX: Disconnect
     */
    public function ajax_sso_disconnect() {
        check_ajax_referer('m2c_sso_nonce', 'nonce');
        
        if (!current_user_can('manage_woocommerce')) {
            wp_send_json_error(array('message' => 'Unauthorized'));
            return;
        }
        
        delete_option($this->option_name);
        
        $gateway_settings = get_option('woocommerce_red_envelope_settings', array());
        if (isset($gateway_settings['merchant_wallet'])) {
            $gateway_settings['merchant_wallet'] = '';
            update_option('woocommerce_red_envelope_settings', $gateway_settings);
        }
        
        wp_send_json_success(array('message' => 'Disconnected'));
    }
}

// Initialize
if (!isset($GLOBALS['m2c_sso_integration'])) {
    $GLOBALS['m2c_sso_integration'] = new M2C_SSO_Integration();
}
