<?php
/**
 * generate_deposit_address.php
 * 
 * Retrieves the admin-set deposit address for a specific cryptocurrency payment method
 * Gives the user the impression that a unique address is being generated
 * Part of the Ton Sui Mining payment integration
 */

header('Content-Type: application/json');
// Critical: Add cache control headers
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
// Reflect exact Origin for credentialed requests
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (!empty($origin)) {
    header('Access-Control-Allow-Origin: ' . $origin);
} else {
    $scheme = $_SERVER['REQUEST_SCHEME'] ?? 'https';
    $host = $_SERVER['HTTP_HOST'] ?? '';
    if (!empty($host)) {
        header('Access-Control-Allow-Origin: ' . $scheme . '://' . $host);
    }
}
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Credentials: true');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');

// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

// Define TONSUI_LOADED constant to prevent direct access to session_init.php
define('TONSUI_LOADED', true);

// Include centralized session initialization
require_once __DIR__ . '/session_init.php';

// Require user authentication
requireLogin(true);

require_once 'config.php';
require_once 'db.php';

// Helper function to validate payment method
function validatePaymentMethod($method_id, $pdo) {
    $stmt = $pdo->prepare("SELECT * FROM payment_methods WHERE id = ? AND status = 'active'");
    $stmt->execute([$method_id]);
    return $stmt->fetch(PDO::FETCH_ASSOC);
}

// Helper function to get the admin-set deposit address for a payment method
function getAdminDepositAddress($payment_method_id, $pdo) {
    $stmt = $pdo->prepare("
        SELECT * FROM admin_deposit_addresses 
        WHERE payment_method_id = ?
        LIMIT 1
    ");
    $stmt->execute([$payment_method_id]);
    $result = $stmt->fetch(PDO::FETCH_ASSOC);
    return $result ?: null; // return null if not found (no exception)
}

// Validate request method
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'message' => 'Method not allowed']);
    exit;
}

// Get and validate POST data
$json_data = file_get_contents('php://input');
$data = json_decode($json_data, true);

if (!$data || !isset($data['payment_method_id'])) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Missing required fields']);
    exit;
}

$payment_method_id = $data['payment_method_id'];
$amount = isset($data['amount']) ? floatval($data['amount']) : null;

try {
    // Begin transaction
    $pdo->beginTransaction();
    
    // Validate payment method
    $payment_method = validatePaymentMethod($payment_method_id, $pdo);
    
    if (!$payment_method) {
        throw new Exception('Invalid or inactive payment method');
    }
    
    // Try admin-set deposit address first
    $adminAddress = getAdminDepositAddress($payment_method_id, $pdo);
    $deposit_address = null;
    $qr_code = null;
    $admin_address_id = null;
    if ($adminAddress) {
        $deposit_address = $adminAddress['address'] ?? null;
        $qr_code = $adminAddress['qr_code'] ?? null;
        $admin_address_id = $adminAddress['id'] ?? null;
    }

    // Fallback: parse payment method details for an address if no admin record
    if (!$deposit_address) {
        $detailsRaw = $payment_method['details'] ?? null;
        if ($detailsRaw) {
            $details = json_decode($detailsRaw, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($details)) {
                // Common keys where an address might be stored
                $candidates = ['address', 'wallet_address', 'btc_address', 'eth_address', 'usdt_address', 'wallet'];
                foreach ($candidates as $k) {
                    if (!empty($details[$k]) && is_string($details[$k])) { $deposit_address = trim($details[$k]); break; }
                }
            } else {
                // If details was a plain string, use it as address
                if (is_string($detailsRaw) && strlen(trim($detailsRaw)) > 10) {
                    $deposit_address = trim($detailsRaw);
                }
            }
        }
    }

    if (!$deposit_address) {
        throw new Exception('No deposit address has been set for this payment method');
    }
    
    // Log that the user requested this address (for tracking purposes)
    $deposit_id = null;
    if ($admin_address_id) {
        $logStmt = $pdo->prepare("
            INSERT INTO user_address_requests
            (user_id, payment_method_id, admin_address_id, created_at)
            VALUES (?, ?, ?, NOW())
        ");
        $logStmt->execute([isset($_SESSION['user_id']) ? $_SESSION['user_id'] : 0, $payment_method_id, $admin_address_id]);
        $deposit_id = $pdo->lastInsertId();
    }
    
    // Add a small delay to simulate address generation
    usleep(rand(500000, 1500000)); // 0.5-1.5 second delay
    
    // If amount is provided, create a pending deposit transaction
    if ($amount) {
        // Generate reference code
        $reference = 'DEP-' . strtoupper(substr(md5(uniqid()), 0, 8));
        
        // Store details for the transaction
        $details = json_encode([
            'payment_method_id' => $payment_method_id,
            'payment_method_name' => $payment_method['name'],
            'address' => $deposit_address,
            'deposit_address_id' => $deposit_id
        ]);
        
        // Create transaction record
        $transStmt = $pdo->prepare("
            INSERT INTO transactions
            (user_id, type, amount, status, details, reference, created_at)
            VALUES (?, 'deposit', ?, 'pending', ?, ?, NOW())
        ");
        
        $transStmt->execute([
            isset($_SESSION['user_id']) ? $_SESSION['user_id'] : 0,
            $amount,
            $details,
            $reference
        ]);
        
        $transaction_id = $pdo->lastInsertId();
    } else {
        $transaction_id = null;
        $reference = null;
    }
    
    // Commit the transaction
    $pdo->commit();
    
    // Use admin-provided QR code or the address itself
    $qr_content = $qr_code ? $qr_code : $deposit_address;
    
    // Build response
    $response = [
        'success' => true,
        'deposit_info' => [
            'address' => $deposit_address,
            'payment_method' => $payment_method['name'],
            'currency' => $payment_method['currency'],
            'qr_content' => $qr_content
        ]
    ];
    
    // Add transaction info if applicable
    if ($transaction_id) {
        $response['transaction'] = [
            'id' => $transaction_id,
            'reference' => $reference,
            'amount' => $amount,
            'status' => 'pending'
        ];
    }
    
    echo json_encode($response);
    
} catch (Exception $e) {
    // Rollback transaction if in progress
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    
    http_response_code(500);
    echo json_encode([
        'success' => false, 
        'message' => 'Failed to generate deposit address: ' . $e->getMessage()
    ]);
}
