<?php
include 'config.php';
header('Content-Type: application/json');

$token = $_POST['token'] ?? '';
$receiver_uid = $_POST['uid'] ?? '';
$amount = floatval($_POST['amount'] ?? 0);
$type = $_POST['type'] ?? 'balance'; // balance অথবা winning

// ---- Input type strictly enforce (array injection ঠেকাতে) ----
if (!is_string($token) || !is_string($receiver_uid)) {
    echo json_encode(["status" => "error", "message" => "Invalid input type"]);
    exit;
}

if (!$token || !$receiver_uid || $amount <= 0) {
    echo json_encode([
        "status" => "error",
        "message" => "Invalid input"
    ]);
    exit;
}

// শুধুমাত্র balance বা winning allow
if (!in_array($type, ['balance', 'winning'], true)) {
    echo json_encode([
        "status" => "error",
        "message" => "Invalid type"
    ]);
    exit;
}

// ---- Simple spam / rapid-fire protection (একই token থেকে ৩ সেকেন্ডের মধ্যে দ্বিতীয় request ঠেকানো) ----
$stmt = $conn->prepare("
    SELECT gr.id FROM gift_requests gr
    INNER JOIN users u ON u.uid = gr.sender_uid
    WHERE u.token = ? AND gr.created_at > (NOW() - INTERVAL 3 SECOND)
    LIMIT 1
");
$stmt->bind_param("s", $token);
$stmt->execute();
$recent = $stmt->get_result();
$stmt->close();

if ($recent->num_rows > 0) {
    echo json_encode([
        "status" => "error",
        "message" => "Too many requests, please wait a moment"
    ]);
    exit;
}

// ================== Transaction শুরু ==================
$conn->begin_transaction();

try {
    // Sender verify + ROW LOCK (FOR UPDATE) — এইখানেই race condition বন্ধ হচ্ছে
    $stmt = $conn->prepare("SELECT uid, balance, winning FROM users WHERE token = ? FOR UPDATE");
    $stmt->bind_param("s", $token);
    $stmt->execute();
    $sender = $stmt->get_result();

    if ($sender->num_rows == 0) {
        $conn->rollback();
        echo json_encode([
            "status" => "error",
            "message" => "Invalid token"
        ]);
        exit;
    }

    $s = $sender->fetch_assoc();
    $sender_uid = $s['uid'];
    $stmt->close();

    // নিজের UID-তে gift পাঠানো বন্ধ
    if ($sender_uid == $receiver_uid) {
        $conn->rollback();
        echo json_encode([
            "status" => "error",
            "message" => "You cannot gift yourself"
        ]);
        exit;
    }

    // Receiver check
    $stmt = $conn->prepare("SELECT uid FROM users WHERE uid = ?");
    $stmt->bind_param("s", $receiver_uid);
    $stmt->execute();
    $receiver = $stmt->get_result();

    if ($receiver->num_rows == 0) {
        $conn->rollback();
        echo json_encode([
            "status" => "error",
            "message" => "Receiver not found"
        ]);
        exit;
    }
    $stmt->close();

    // Fee calculate (Flat 5 Taka, amount jai hok na keno)
    $fee = 5;
    $total = $amount + $fee;

    // Balance check (lock করা row থেকে পড়া balance, তাই এখন নির্ভরযোগ্য)
    $current_balance = $s[$type];

    if ($current_balance < $total) {
        $conn->rollback();
        echo json_encode([
            "status" => "error",
            "message" => "Insufficient balance",
            "required" => $total,
            "available" => $current_balance
        ]);
        exit;
    }

    // ---- Deduct: UPDATE এর ভেতরেই দ্বিতীয় স্তরের safety condition ----
    // $type আগেই whitelist করা হয়েছে ['balance','winning'], তাই সরাসরি বসানো নিরাপদ
    $sql = "UPDATE users SET $type = $type - ? WHERE uid = ? AND $type >= ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("dsd", $total, $sender_uid, $total);
    $stmt->execute();

    if ($stmt->affected_rows === 0) {
        // Row lock থাকার পরও এইটা হওয়ার কথা না, কিন্তু defensive check হিসেবে রাখা হলো
        $conn->rollback();
        echo json_encode([
            "status" => "error",
            "message" => "Balance changed, please try again"
        ]);
        exit;
    }
    $stmt->close();

    // Save request
    $stmt = $conn->prepare("
        INSERT INTO gift_requests
        (sender_uid, receiver_uid, amount, fee, total, type, status)
        VALUES (?, ?, ?, ?, ?, ?, 'pending')
    ");
    $stmt->bind_param("ssddds", $sender_uid, $receiver_uid, $amount, $fee, $total, $type);
    $stmt->execute();
    $request_id = $stmt->insert_id;
    $stmt->close();

    // সব ঠিক থাকলে commit — এই মুহূর্তেই lock রিলিজ হবে, পরের request প্রসেস হতে পারবে
    $conn->commit();

    echo json_encode([
        "status" => "success",
        "message" => "Gift request created",
        "request_id" => $request_id,
        "amount" => $amount,
        "fee" => $fee,
        "total_deducted" => $total
    ]);

} catch (Exception $e) {
    $conn->rollback();
    echo json_encode([
        "status" => "error",
        "message" => "Something went wrong, please try again"
    ]);
}