<?php
/**
 * pay/callback.php
 * Payment Gateway Instant Webhook Callback Handler
 */

// Response Header
header('Content-Type: application/json');

include(__DIR__ . "/../service/samparka.php");

/* =========================================================
   PAYMENT GATEWAY SETTINGS
   ========================================================= */
define('PG_API_SECRET', '39ced892f4c4bfaa9468e3a9da2d783082ba310225693a97');

/* =========================================================
   1. RAW INPUT & SIGNATURE VERIFICATION
   ========================================================= */
$rawPayload = file_get_contents('php://input');
$headers = getallheaders();

// Lowercase headers normalize
$headersNormalized = [];
foreach ($headers as $key => $val) {
    $headersNormalized[strtolower($key)] = $val;
}

$receivedSignature = $headersNormalized['x-signature'] ?? '';
$timestamp = $headersNormalized['x-timestamp'] ?? '';
$nonce = $headersNormalized['x-nonce'] ?? '';

if (empty($receivedSignature) || empty($timestamp) || empty($nonce)) {
    http_response_code(400);
    echo json_encode(['status' => false, 'message' => 'Missing security headers']);
    exit;
}

// Re-calculate HMAC Signature
$expectedPayload = $timestamp . '.' . $nonce . '.' . $rawPayload;
$calculatedSignature = hash_hmac('sha256', $expectedPayload, PG_API_SECRET);

if (!hash_equals($calculatedSignature, $receivedSignature)) {
    http_response_code(401);
    echo json_encode(['status' => false, 'message' => 'Invalid signature']);
    exit;
}

/* =========================================================
   2. PARSE DATA
   ========================================================= */
$data = json_decode($rawPayload, true);

if (!is_array($data)) {
    http_response_code(400);
    echo json_encode(['status' => false, 'message' => 'Invalid JSON payload']);
    exit;
}

// Extract transaction fields
$trx_id     = trim($data['trx_id'] ?? $data['trxid'] ?? '');
$amount     = (float)($data['amount'] ?? 0);
$claimedBy  = trim($data['claimed_by'] ?? ''); // Expected format: User#123
$provider   = trim($data['provider'] ?? 'Gateway');
$mobile     = trim($data['sender_mobile'] ?? '');

if (empty($trx_id) || $amount <= 0 || empty($claimedBy)) {
    http_response_code(422);
    echo json_encode(['status' => false, 'message' => 'Missing required transaction details']);
    exit;
}

// Extract User ID from claimed_by string (e.g. "User#15" -> 15)
$uid = 0;
if (preg_match('/User#(\d+)/i', $claimedBy, $matches)) {
    $uid = (int)$matches[1];
}

if ($uid <= 0) {
    http_response_code(422);
    echo json_encode(['status' => false, 'message' => 'Invalid user ID format in claimed_by']);
    exit;
}

/* =========================================================
   3. DATABASE TRANSACTIONS
   ========================================================= */

// Duplicate TrxID Check
$trxEsc = mysqli_real_escape_string($conn, $trx_id);
$dupQ = mysqli_query($conn, "SELECT shonu FROM thevani WHERE ullekha = '$trxEsc' LIMIT 1");

if ($dupQ && mysqli_num_rows($dupQ) > 0) {
    // Already processed, return 200 OK to gateway so it stops sending callbacks
    echo json_encode(['status' => true, 'message' => 'Transaction already processed']);
    exit;
}

// User Check
$userQ = mysqli_query($conn, "SELECT id, code FROM shonu_subjects WHERE id = '$uid' AND status = '1' LIMIT 1");
$userRow = $userQ ? mysqli_fetch_assoc($userQ) : null;

if (!$userRow) {
    http_response_code(404);
    echo json_encode(['status' => false, 'message' => 'User not found or inactive']);
    exit;
}

// Pool Identification (Agent vs Admin)
$poolIsAgent = false;
$poolId = null;

if (!empty($userRow['code'])) {
    $codeEsc = mysqli_real_escape_string($conn, $userRow['code']);
    $refQ = mysqli_query($conn, "SELECT id FROM shonu_subjects WHERE owncode = '$codeEsc' LIMIT 1");
    $refRow = $refQ ? mysqli_fetch_assoc($refQ) : null;

    if ($refRow) {
        $refId = (int)$refRow['id'];
        $agentQ = mysqli_query($conn, "SELECT userid FROM tb_agent WHERE userid = '$refId' AND status = '1' LIMIT 1");
        if ($agentQ && mysqli_num_rows($agentQ) > 0) {
            $poolIsAgent = true;
            $poolId = $refId;
        }
    }
}

if (!$poolIsAgent) {
    $adminQ = mysqli_query($conn, "SELECT unohs FROM nirvahaka_shonu ORDER BY unohs ASC LIMIT 1");
    $adminRow = $adminQ ? mysqli_fetch_assoc($adminQ) : null;
    $poolId = $adminRow['unohs'] ?? null;
}

if ($poolId === null) {
    http_response_code(500);
    echo json_encode(['status' => false, 'message' => 'Balance pool not available']);
    exit;
}

/* =========================================================
   4. EXECUTE BALANCE UPDATE
   ========================================================= */
mysqli_begin_transaction($conn);

try {
    // Update User Balance
    $upUser = mysqli_query($conn, "UPDATE shonu_kaichila SET motta = motta + $amount WHERE balakedara = '$uid'");

    // Deduct Pool Balance
    $poolIdInt = (int)$poolId;
    if ($poolIsAgent) {
        $upPool = mysqli_query($conn, "UPDATE shonu_kaichila SET motta = motta - $amount WHERE balakedara = '$poolIdInt'");
    } else {
        $upPool = mysqli_query($conn, "UPDATE nirvahaka_shonu SET motta = motta - $amount WHERE unohs = '$poolIdInt'");
    }

    // Insert Log in thevani
    $mobileEsc = mysqli_real_escape_string($conn, $mobile);
    $providerEsc = mysqli_real_escape_string($conn, $provider . '-Callback');
    
    $insDep = mysqli_query(
        $conn,
        "INSERT INTO thevani (balakedara, kula, motta, mobila, ullekha, dinamka, dinankavannuracisi, sthiti)
         VALUES ('$uid', '$providerEsc', '$amount', '$mobileEsc', '$trxEsc', CURDATE(), NOW(), 1)"
    );

    if ($upUser && $upPool && $insDep) {
        mysqli_commit($conn);
        echo json_encode(['status' => true, 'message' => 'Deposit successful and balance updated']);
    } else {
        mysqli_rollback($conn);
        http_response_code(500);
        echo json_encode(['status' => false, 'message' => 'Database update failed']);
    }
} catch (Throwable $e) {
    mysqli_rollback($conn);
    http_response_code(500);
    echo json_encode(['status' => false, 'message' => 'Server Error: ' . $e->getMessage()]);
}