<?php
// /v1/main/ride/syriatel/driver/confirm_payment.php
// يعتمد على jwtconnect.php و syriatel_token_handler.php فقط
include_once "../../../jwtconnect.php";
include_once "./syriatel_token_handler.php";

header('Content-Type: application/json; charset=utf-8');

// ================== Helpers (طباعة/لوج) ==================
if (!function_exists('printSuccess')) {
    function printSuccess($data = null, $message = "success") {
        echo json_encode(["status" => "success", "message" => $message, "data" => $data], JSON_UNESCAPED_UNICODE);
        exit;
    }
}
if (!function_exists('printFailure')) {
    function printFailure($message = "failure", $code = null) {
        $resp = ["status" => "failure", "message" => $message];
        if ($code !== null) $resp["code"] = $code;
        echo json_encode($resp, JSON_UNESCAPED_UNICODE);
        exit;
    }
}

define("WALLET_LOG", __DIR__ . "/../logs/payment_verification.log");
function wlog($step, $msg, $data = null) {
    $dir = dirname(WALLET_LOG);
    if (!is_dir($dir)) { @mkdir($dir, 0755, true); }
    $line = "[".date('Y-m-d H:i:s')."] STEP {$step}: {$msg}";
    if ($data !== null) $line .= " | Data: ".json_encode($data, JSON_UNESCAPED_UNICODE);
    file_put_contents(WALLET_LOG, $line.PHP_EOL, FILE_APPEND);
}

// ================== منطق التوكن/المعرف ==================
function generateToken(PDO $con, string $driverId, float $amount): ?string {
    // secretKey يُفترض قادم من connect/env
    global $secretKey;
    $data = $driverId.$amount.time().($secretKey ?? 'default_secret');
    $hash = hash('sha256', $data);
    $rand = bin2hex(random_bytes(16));
    $token = substr($hash.$rand, 0, 64);

    $stmt = $con->prepare("INSERT INTO payment_tokens (token, driverID, dateCreated, amount) 
                           VALUES (:t, :d, NOW(), :a)");
    $stmt->execute([':t'=>$token, ':d'=>$driverId, ':a'=>$amount]);
    return $stmt->rowCount() ? $token : null;
}

function generatePaymentID(PDO $con, string $driverId, float $amount, string $method): ?string {
    $stmt = $con->prepare("INSERT INTO paymentsDriverPoints (amount, payment_method, driverID) 
                           VALUES (:a, :m, :d)");
    $stmt->execute([':a'=>$amount, ':m'=>$method, ':d'=>$driverId]);
    return $stmt->rowCount() ? $con->lastInsertId() : null;
}

// ================== منطق إنهاء الدفع (مضمَّن) ==================
function finalizeWalletPaymentInline(PDO $con, string $orderRef): void {
    // نقفل الصف لمنع السباقات
    $stmt = $con->prepare("SELECT * FROM paymentsLogSyriaDriver 
                           WHERE order_ref = :r LIMIT 1 FOR UPDATE");
    $stmt->execute([':r'=>$orderRef]);
    $payment = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$payment) {
        wlog("FINALIZE", "Payment row not found", ['orderRef'=>$orderRef]);
        throw new RuntimeException("Payment not found.");
    }

    // نتأكد من نجاح مزود الدفع
    if ((int)$payment['status'] !== 1) {
        wlog("FINALIZE", "Payment not completed yet", ['orderRef'=>$orderRef, 'status'=>$payment['status']]);
        throw new RuntimeException("Payment not completed.");
    }

    // حارس التكرار: إذا تمّت معالجة المحفظة سابقاً لا نكرر
    if (!empty($payment['processed_wallet']) && (int)$payment['processed_wallet'] === 1) {
        wlog("FINALIZE", "Already processed_wallet=1, skip.", ['orderRef'=>$orderRef]);
        return; // لا نرمي استثناء؛ العملية سبق احتسابها
    }

    $driverId       = $payment['user_id']; // This is now correctly handled as a string
    $originalAmount = (float)$payment['amount'];
    $paymentMethod  = $payment['payment_method'] ?: 'ecash';

    // البونص
    $bonusAmount = match ((int)$originalAmount) {
        100  => 100.0,
        200  => 210.0,
        400  => 450.0,
        1000 => 1100.0,
        default => $originalAmount,
    };

    // تنفيذ ككل داخل معاملة
    $con->beginTransaction();
    try {
        // توليد التوكنات/المعرف
        $tokenDriver = generateToken($con, $driverId, $bonusAmount);
        if (!$tokenDriver) throw new RuntimeException("Failed to generate driver token");

        $tokenSiro  = generateToken($con, $driverId, $originalAmount);
        if (!$tokenSiro) throw new RuntimeException("Failed to generate siro token");

        $paymentID   = generatePaymentID($con, $driverId, $bonusAmount, $paymentMethod);
        if (!$paymentID) throw new RuntimeException("Failed to create payment ID");

        // driverWallet
        $q = $con->prepare("INSERT INTO driverWallet (driverID, paymentID, amount, paymentMethod) 
                           VALUES (:d, :r, :a, :m)");
        $q->execute([
            ':d'=>$driverId, ':a'=>$bonusAmount,
            ':m'=>$paymentMethod, ':r'=>$orderRef
        ]);
        if ($q->rowCount() === 0) throw new RuntimeException("Insert driverWallet failed");

        // وسم التوكن كمستخدم
        $con->prepare("UPDATE payment_tokens SET isUsed = 1 WHERE token = :t")->execute([':t'=>$tokenDriver]);

        // siroWallet
        $q2 = $con->prepare("INSERT INTO siroWallet (driverId, passengerId, amount, paymentMethod, token, createdAt)
                             VALUES (:d, :p, :a, :m, :t, CURRENT_TIMESTAMP)");
        $q2->execute([
            ':d'=>$driverId, ':p'=>'driver', ':a'=>$originalAmount,
            ':m'=>$paymentMethod, ':t'=>$tokenSiro
        ]);
        if ($q2->rowCount() === 0) throw new RuntimeException("Insert siroWallet failed");

        $con->prepare("UPDATE payment_tokens SET isUsed = 1 WHERE token = :t")->execute([':t'=>$tokenSiro]);

        // تأشير السجل كمنتهٍ للمحفظة
        $con->prepare("UPDATE paymentsLogSyriaDriver 
                       SET processed_wallet = 1, updated_at = NOW()
                       WHERE order_ref = :r")->execute([':r'=>$orderRef]);

        $con->commit();
        wlog("FINALIZE", "Wallets updated successfully", ['orderRef'=>$orderRef, 'driverId'=>$driverId]);
    } catch (Throwable $e) {
        $con->rollBack();
        wlog("FINALIZE", "Exception: ".$e->getMessage(), ['orderRef'=>$orderRef]);
        throw $e;
    }
}

// ================== مدخل تأكيد الدفع ==================
$transactionID = filterRequest('transactionID');
$otp           = filterRequest('otp');

error_log("Syriatel Confirm: Request for transaction {$transactionID}");

if (!$transactionID || !$otp) {
    printFailure("Missing transaction ID or OTP.");
}

// بيئة
$baseUrl        = rtrim((string)getenv('SYRIATEL_API_BASE_URL'), '/');
$merchantMSISDN = (string)getenv('SYRIATEL_MERCHANT_MSISDN');
if ($baseUrl === '' || $merchantMSISDN === '') {
    error_log("Syriatel Confirm: Missing SYRIATEL envs");
    printFailure("Server configuration error.");
}

try {
    // 1) Auth token
    $token = function_exists('GetSerialToken') ? GetSerialToken() : getSyriatelToken();
    if (!$token) { printFailure("Could not authenticate with the payment provider."); }

    // 2) Call provider
    $body = [
        "OTP"            => $otp,
        "merchantMSISDN" => $merchantMSISDN,
        "transactionID"  => $transactionID,
        "token"          => $token
    ];
    $url = "{$baseUrl}/ePaymentExternalModule/paymentConfirmation";
    $ch  = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode($body, JSON_UNESCAPED_UNICODE),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => [
            "Content-Type: application/json",
            "Accept: application/json",
            "User-Agent: Mozilla/5.0",
        ],
        CURLOPT_CONNECTTIMEOUT => 8,
        CURLOPT_TIMEOUT        => 40,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
    ]);
    $response = curl_exec($ch);
    $errno    = curl_errno($ch);
    $httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    error_log("Syriatel Confirm: HTTP {$httpCode} - ".substr((string)$response, 0, 300));

    if ($errno)                     { printFailure("Payment gateway communication error.", $errno); }
    if ($httpCode !== 200 || !$response) { printFailure("Payment gateway communication error (HTTP {$httpCode})."); }

    $responseData = json_decode($response, true);
    if (!is_array($responseData)) { printFailure("Invalid provider response."); }

    $ok = (isset($responseData['errorDesc']) && $responseData['errorDesc'] === "Success");

    if ($ok) {
        // نحدّث حالة الدفع، ونُتم المحفظة بشكل آمن داخل نفس الطلب
        $con->prepare("UPDATE paymentsLogSyriaDriver 
                       SET status = 1, updated_at = NOW() 
                       WHERE order_ref = :r")->execute([':r'=>$transactionID]);

        // إنهاء المحفظة (داخلية)
        $walletOk = true; $walletMsg = null;
        try {
            finalizeWalletPaymentInline($con, $transactionID);
        } catch (Throwable $ex) {
            $walletOk = false; $walletMsg = $ex->getMessage();
        }

        $payload = [
            'message'       => 'Payment confirmed.',
            'transactionID' => $transactionID,
            'provider'      => $responseData
        ];
        if (!$walletOk && $walletMsg) {
            $payload['walletNotice'] = "Payment successful, but wallet update failed: ".$walletMsg;
        }

        printSuccess($payload);
    }

    $errorMessage = $responseData['errorDesc'] ?? 'Unknown provider error';
    printFailure($errorMessage);

} catch (Throwable $e) {
    error_log("Syriatel Confirm: Exception - ".$e->getMessage());
    printFailure("An unexpected server error occurred.");
}