<?php
/**
 * Binance WebSocket Chat Handler
 * Sends messages to buyers via Binance WebSocket
 * 
 * Run this as a background process or via cron
 */

// CRITICAL: Suppress ALL output BEFORE anything else (CLI only)
if (php_sapi_name() === 'cli') {
    // Disable all output immediately - MUST be first
    ini_set('display_errors', '0');
    ini_set('log_errors', '1');
    ini_set('output_buffering', '0');
    ini_set('session.auto_start', '0');
    
    // Clean any existing output buffers
    while (ob_get_level() > 0) {
        ob_end_clean();
    }
    
    // Start fresh buffer to catch ANY stray output
    ob_start();
    
    // Prevent any headers from being sent
    if (function_exists('header_remove')) {
        header_remove();
    }
}

// Prevent execution via web browser (CLI only)
// Allow execution if NOT clearly a web request (more permissive check)
$isWebRequest = (
    isset($_SERVER['HTTP_HOST']) ||
    isset($_SERVER['REQUEST_METHOD']) ||
    (isset($_SERVER['SERVER_SOFTWARE']) && php_sapi_name() !== 'cli')
);

if ($isWebRequest && php_sapi_name() !== 'cli') {
    // Only block if it's clearly a web request
    http_response_code(403);
    die('This script can only be run from command line.');
}

// Set base directory for includes
$baseDir = dirname(__DIR__);

// Temporarily disable session auto-start
$originalSessionAutoStart = ini_get('session.auto_start');
ini_set('session.auto_start', '0');

// Load required files with absolute paths
require_once $baseDir . '/includes/config.php';

// Clear any output buffer after loading config (CLI only)
if (php_sapi_name() === 'cli') {
    // Discard any output that was buffered (headers, etc.)
    if (ob_get_level() > 0) {
        ob_end_clean();
    }
    // Start fresh buffer for the rest of the script
    ob_start();
}
require_once $baseDir . '/includes/binance-api.php';
require_once $baseDir . '/includes/binance-settings.php';
require_once $baseDir . '/includes/functions.php';

// Suppress HTML output for CLI
ini_set('display_errors', '0');
ini_set('log_errors', '1');

set_time_limit(300); // 5 minutes for cron execution

error_log("=== Binance WebSocket Chat Handler Started ===");

try {
    $settings = new BinanceP2PSettings($pdo);
    
    // Get Binance API credentials
    $apiKey = $settings->getBinanceApiKey();
    $secretKey = $settings->getBinanceSecretKey();
    
    if (empty($apiKey) || empty($secretKey)) {
        error_log("ERROR: Binance API credentials not configured!");
        exit(1);
    }
    
    $binance = new BinanceP2PAPI($apiKey, $secretKey);
    
    // Get chat credentials
    $credentials = $binance->getChatCredentials();
    
    if (isset($credentials['error'])) {
        error_log("ERROR getting chat credentials: " . $credentials['error']);
        
        // Clean output buffer before exit
        if (php_sapi_name() === 'cli' && ob_get_level() > 0) {
            ob_end_clean();
        }
        
        exit(1);
    }
    
    $wssUrl = $credentials['data']['chatWssUrl'] ?? null;
    $listenKey = $credentials['data']['listenKey'] ?? null;
    $listenToken = $credentials['data']['listenToken'] ?? null;
    
    // Log credentials structure for debugging (without exposing full token)
    error_log("Chat credentials received - WSS URL: " . ($wssUrl ? "present" : "missing"));
    error_log("ListenKey: " . ($listenKey ? substr($listenKey, 0, 20) . "..." : "missing"));
    error_log("ListenToken: " . ($listenToken ? substr($listenToken, 0, 20) . "..." : "missing"));
    error_log("Full credentials structure: " . json_encode(array_keys($credentials['data'] ?? [])));
    
    if (empty($wssUrl) || empty($listenKey) || empty($listenToken)) {
        error_log("ERROR: Invalid chat credentials");
        error_log("Full credentials response: " . json_encode($credentials));
        
        // Clean output buffer before exit
        if (php_sapi_name() === 'cli' && ob_get_level() > 0) {
            ob_end_clean();
        }
        
        exit(1);
    }
    
    // According to Binance docs, the token should be used as-is (with TOKEN prefix if present)
    // The URL format is: wss://im.binance.com:443/chat/<listenKey>?token=<listenToken>&clientType=web
    error_log("Using token as-is from Binance API (length: " . strlen($listenToken) . ")");
    
    // Get pending messages from database
    // Check for orders with BUYER_PAYED status that need messages sent
    $stmt = $pdo->prepare("
        SELECT order_no, fiat_amount, fiat_currency, order_status
        FROM binance_p2p_orders 
        WHERE order_status = 'BUYER_PAYED'
        AND chat_messages_sent = 0
        AND (last_message_sent_at IS NULL OR last_message_sent_at < DATE_SUB(NOW(), INTERVAL 1 MINUTE))
        ORDER BY updated_at DESC
        LIMIT 10
    ");
    $stmt->execute();
    $ordersToMessage = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    if (empty($ordersToMessage)) {
        error_log("No pending messages to send");
        
        // Clean output buffer before exit
        if (php_sapi_name() === 'cli' && ob_get_level() > 0) {
            ob_end_clean();
        }
        
        exit(0);
    }
    
    error_log("Found " . count($ordersToMessage) . " orders to send messages for");
    
    // Load WebSocket client
    require_once $baseDir . '/includes/websocket-client.php';
    
    // Connect to WebSocket
    try {
        // Pass token as-is (Binance docs show token should include TOKEN prefix in URL)
        $wsClient = new BinanceWebSocketClient($wssUrl, $listenKey, $listenToken);
        
        // Try to connect (with timeout)
        $connected = false;
        $maxRetries = 3;
        $retryCount = 0;
        
        while ($retryCount < $maxRetries && !$connected) {
            try {
                // Set a timeout for connection attempt
                set_time_limit(30);
                $wsClient->connect();
                $connected = $wsClient->isConnected();
                
                if ($connected) {
                    error_log("WebSocket connected successfully");
                    break;
                }
            } catch (Exception $e) {
                $retryCount++;
                error_log("WebSocket connection attempt $retryCount failed: " . $e->getMessage());
                if ($retryCount < $maxRetries) {
                    sleep(2); // Wait before retry
                }
            }
        }
        
        if (!$connected) {
            error_log("ERROR: Could not establish WebSocket connection after $maxRetries attempts");
            // Mark messages as queued for next run
            foreach ($ordersToMessage as $order) {
                $stmt = $pdo->prepare("
                    UPDATE binance_p2p_orders 
                    SET last_message_sent_at = NULL,
                        updated_at = NOW()
                    WHERE order_no = ?
                ");
                $stmt->execute([$order['order_no']]);
            }
            
            if (php_sapi_name() === 'cli' && ob_get_level() > 0) {
                ob_end_clean();
            }
            exit(1);
        }
        
        // Send messages for each order
        foreach ($ordersToMessage as $order) {
            $orderNo = $order['order_no'];
            $amount = $order['fiat_amount'];
            $currency = $order['fiat_currency'];
            
            // Prepare messages (English and Spanish)
            $englishMessage = "✅ PAYMENT PROCESSED - ZATAM AUTOPAY BOT\n\n" .
                "Payment has been sent via onrampr.co (USDC → EUR).\n\n" .
                "⏱ Processing time: Up to 15 minutes to appear in your bank account\n\n" .
                "NEXT STEPS:\n\n" .
                "Check your bank account for the funds\n" .
                "Release the USDT/USDC once received\n" .
                "Do NOT release based on this message alone\n\n" .
                "⚠️ REMINDER:\n\n" .
                "I am an automated system\n" .
                "I cannot read chat responses\n" .
                "Only release after confirming funds in your account\n\n" .
                "⭐ Positive feedback appreciated after completion";
            
            $spanishMessage = "✅ PAGO PROCESADO - ZATAM AUTOPAY BOT\n\n" .
                "El pago ha sido enviado a través de onrampr.co (USDC → EUR).\n\n" .
                "⏱ Tiempo de procesamiento: Hasta 15 minutos para aparecer en su cuenta bancaria\n\n" .
                "PRÓXIMOS PASOS:\n\n" .
                "Verifique su cuenta bancaria por los fondos\n" .
                "Libere el USDT/USDC una vez recibido\n" .
                "NO libere solo basándose en este mensaje\n\n" .
                "⚠️ RECORDATORIO:\n\n" .
                "Soy un sistema automatizado\n" .
                "No puedo leer respuestas en el chat\n" .
                "Libere solo después de confirmar fondos en su cuenta\n\n" .
                "⭐ Comentarios positivos apreciados después de completar";
            
            // Send English message first
            $sentEnglish = $wsClient->sendMessage($orderNo, $englishMessage);
            
            if ($sentEnglish) {
                error_log("English message sent successfully for order $orderNo");
                
                // Wait 2 seconds before sending Spanish message
                sleep(2);
                
                // Send Spanish message
                $sentSpanish = $wsClient->sendMessage($orderNo, $spanishMessage);
                
                if ($sentSpanish) {
                    error_log("Spanish message sent successfully for order $orderNo");
                    
                    // Update last message sent time and mark as sent
                    $stmt = $pdo->prepare("
                        UPDATE binance_p2p_orders 
                        SET last_message_sent_at = NOW(),
                            chat_messages_sent = 1,
                            updated_at = NOW()
                        WHERE order_no = ?
                    ");
                    $stmt->execute([$orderNo]);
                } else {
                    error_log("Failed to send Spanish message for order $orderNo (will retry next run)");
                    // Don't mark as sent if Spanish message failed
                }
            } else {
                error_log("Failed to send English message for order $orderNo (will retry next run)");
            }
        }
        
        // Close connection
        $wsClient->close();
        
    } catch (Exception $e) {
        error_log("FATAL ERROR in WebSocket chat: " . $e->getMessage());
        error_log("Stack trace: " . $e->getTraceAsString());
        
        // Mark messages for retry
        foreach ($ordersToMessage as $order) {
            $stmt = $pdo->prepare("
                UPDATE binance_p2p_orders 
                SET last_message_sent_at = NULL,
                    updated_at = NOW()
                WHERE order_no = ?
            ");
            $stmt->execute([$order['order_no']]);
        }
    }
    
    error_log("=== Binance WebSocket Chat Handler Completed ===");
    
    // Clean output buffer before exit
    if (php_sapi_name() === 'cli' && ob_get_level() > 0) {
        ob_end_clean();
    }
    
} catch (Exception $e) {
    error_log("FATAL ERROR in WebSocket chat handler: " . $e->getMessage());
    error_log("Stack trace: " . $e->getTraceAsString());
    
    // Clean output buffer before exit
    if (php_sapi_name() === 'cli' && ob_get_level() > 0) {
        ob_end_clean();
    }
    
    exit(1);
}

/**
 * Note: Full WebSocket implementation requires:
 * 1. WebSocket client library (e.g., Ratchet, ReactPHP WebSocket)
 * 2. Persistent connection handling
 * 3. Message queuing system
 * 4. Reconnection logic
 * 
 * For production, consider:
 * - Using a message queue (Redis, RabbitMQ)
 * - Running WebSocket client as a daemon/service
 * - Implementing proper error handling and reconnection
 */
