<?php
/**
 * M2C QR Code Generator
 * Generates QR codes for Red Envelope payments
 */

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

class M2C_QR_Generator {
    
    /**
     * Generate payment QR code
     */
    public function generate_payment_qr($params) {
        $order_id = $params['order_id'];
        $amount = $params['amount'];
        $token = $params['token'] ?? 'USDC';
        $merchant_wallet = $params['merchant_wallet'];
        $customer_wallet = $params['customer_wallet'] ?? '';
        $expiry_minutes = $params['expiry_minutes'] ?? 10;
        
        // Get order for additional details
        $order = wc_get_order($order_id);
        
        // Generate unique transaction ID
        $transaction_id = $this->generate_transaction_id($order_id);
        
        // Calculate expiry timestamp
        $expires_at = time() + ($expiry_minutes * 60);
        
        // Generate nonce
        $nonce = $this->generate_nonce();
        
        // Get order items for QR payload
        $items = array();
        if ($order) {
            foreach ($order->get_items() as $item) {
                $items[] = array(
                    'name' => $item->get_name(),
                    'qty' => $item->get_quantity(),
                    'total' => $item->get_total(),
                );
            }
        }
        
        // Build payload with seller and purchase information
        $payload = array(
            'v' => 3, // Version 3 - includes seller/purchase info + shipping destination
            'type' => 'payment',
            'order_id' => $order_id,
            'transaction_id' => $transaction_id,
            'merchant_address' => $merchant_wallet,
            'customer_address' => $customer_wallet,
            'amount' => $amount,
            'token' => $token,
            'chain' => 'aqy',
            'expires_at' => $expires_at,
            'nonce' => $nonce,
            'timestamp' => time(),
            'callback_url' => $this->get_callback_url($order_id),
            // Seller information
            'seller' => array(
                'name' => get_bloginfo('name'),
                'url' => get_site_url(),
            ),
            // Purchase information
            'purchase' => array(
                'item_count' => $order ? $order->get_item_count() : 0,
                'items' => $items,
                'currency' => $order ? $order->get_currency() : 'USD',
                'total_fiat' => $order ? $order->get_total() : $amount,
            ),
        );
        
        // v4.2: Add shipping destination for destination-based tax & dealer resolution
        // Ship-to address determines: (1) which tax jurisdiction applies, (2) which regional dealer gets reward
        if ($order) {
            $ship_country = $order->get_shipping_country() ?: $order->get_billing_country();
            $ship_state   = $order->get_shipping_state()   ?: $order->get_billing_state();
            $ship_city    = $order->get_shipping_city()    ?: $order->get_billing_city();
            if ($ship_country) {
                $payload['shipping_destination'] = array(
                    'country' => $ship_country,
                    'state'   => $ship_state,
                    'city'    => $ship_city,
                );
            }
        }
        
        // Generate signature (simplified for demo - use proper signing in production)
        $signature = $this->sign_payload($payload);
        
        // Complete envelope
        $envelope = array(
            'payload' => $payload,
            'sig' => $signature,
            'pubKey' => $this->get_public_key(),
        );
        
        // Save to database
        $this->save_transaction($order_id, $transaction_id, $envelope);
        
        return $envelope;
    }
    
    /**
     * Generate consumer referral QR code
     */
    public function generate_referral_qr($wallet_address, $referral_code) {
        $payload = array(
            'v' => 1,
            'type' => 'referral',
            'referrer_address' => $wallet_address,
            'referral_code' => $referral_code,
            'timestamp' => time(),
            'nonce' => $this->generate_nonce(),
        );
        
        $signature = $this->sign_payload($payload);
        
        return array(
            'payload' => $payload,
            'sig' => $signature,
            'pubKey' => $this->get_public_key(),
        );
    }
    
    /**
     * Generate merchant registration QR code
     */
    public function generate_merchant_qr($wallet_address, $commission_rate) {
        $payload = array(
            'v' => 1,
            'type' => 'merchant',
            'merchant_address' => $wallet_address,
            'commission_rate' => $commission_rate,
            'timestamp' => time(),
            'nonce' => $this->generate_nonce(),
        );
        
        $signature = $this->sign_payload($payload);
        
        return array(
            'payload' => $payload,
            'sig' => $signature,
            'pubKey' => $this->get_public_key(),
        );
    }
    
    /**
     * Verify QR code signature
     */
    public function verify_qr_signature($envelope) {
        if (!isset($envelope['payload']) || !isset($envelope['sig']) || !isset($envelope['pubKey'])) {
            return false;
        }
        
        // Verify signature (simplified - implement proper Ed25519 verification)
        $expected_sig = $this->sign_payload($envelope['payload']);
        
        return hash_equals($expected_sig, $envelope['sig']);
    }
    
    /**
     * Generate unique transaction ID
     */
    private function generate_transaction_id($order_id) {
        return 'WP-' . $order_id . '-' . time() . '-' . substr(md5(uniqid('', true)), 0, 8);
    }
    
    /**
     * Generate random nonce
     */
    private function generate_nonce() {
        return substr(md5(uniqid('', true)), 0, 16);
    }
    
    /**
     * Sign payload (simplified - use Ed25519 in production)
     */
    private function sign_payload($payload) {
        $canonical = $this->build_canonical_string($payload);
        $secret = $this->get_signing_secret();
        return hash_hmac('sha256', $canonical, $secret);
    }
    
    /**
     * Build canonical string from payload
     */
    private function build_canonical_string($payload) {
        ksort($payload);
        return json_encode($payload, JSON_UNESCAPED_SLASHES);
    }
    
    /**
     * Get signing secret
     */
    private function get_signing_secret() {
        $secret = get_option('m2c_signing_secret');
        if (!$secret) {
            $secret = wp_generate_password(64, true, true);
            update_option('m2c_signing_secret', $secret);
        }
        return $secret;
    }
    
    /**
     * Get public key
     */
    private function get_public_key() {
        $pubkey = get_option('m2c_public_key');
        if (!$pubkey) {
            $pubkey = base64_encode(random_bytes(32));
            update_option('m2c_public_key', $pubkey);
        }
        return $pubkey;
    }
    
    /**
     * Get callback URL for payment notifications
     */
    private function get_callback_url($order_id) {
        return add_query_arg(array(
            'wc-api' => 'm2c_webhook',
            'order_id' => $order_id,
        ), home_url('/'));
    }
    
    /**
     * Save transaction to database
     */
    private function save_transaction($order_id, $transaction_id, $envelope) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'm2c_transactions';
        
        $order = wc_get_order($order_id);
        
        $wpdb->insert(
            $table_name,
            array(
                'order_id' => $order_id,
                'transaction_id' => $transaction_id,
                'wallet_address' => $order->get_meta('_m2c_merchant_wallet'),
                'amount' => $order->get_total(),
                'token' => $order->get_meta('_m2c_payment_token'),
                'status' => 'pending',
                'qr_code_data' => json_encode($envelope),
                'created_at' => current_time('mysql'),
            ),
            array('%d', '%s', '%s', '%f', '%s', '%s', '%s', '%s')
        );
        
        return $wpdb->insert_id;
    }
    
    /**
     * Get transaction by ID
     */
    public function get_transaction($transaction_id) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'm2c_transactions';
        
        return $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM $table_name WHERE transaction_id = %s",
            $transaction_id
        ), ARRAY_A);
    }
    
    /**
     * Update transaction status
     */
    public function update_transaction_status($transaction_id, $status, $data = array()) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'm2c_transactions';
        
        $update_data = array(
            'status' => $status,
            'updated_at' => current_time('mysql'),
        );
        
        if (isset($data['tx_hash'])) {
            $update_data['tx_hash'] = $data['tx_hash'];
        }
        
        if (isset($data['explorer_link'])) {
            $update_data['explorer_link'] = $data['explorer_link'];
        }
        
        if (isset($data['m2c_distribution'])) {
            $update_data['m2c_distribution'] = json_encode($data['m2c_distribution']);
        }
        
        if (isset($data['consumer_aqy'])) {
            $update_data['consumer_aqy'] = $data['consumer_aqy'];
        }
        
        if (isset($data['merchant_commission'])) {
            $update_data['merchant_commission'] = $data['merchant_commission'];
        }
        
        $wpdb->update(
            $table_name,
            $update_data,
            array('transaction_id' => $transaction_id),
            array('%s', '%s', '%s', '%s', '%s', '%f', '%f'),
            array('%s')
        );
    }
}
