<?php
/**
 * ═══════════════════════════════════════════════════════════
 * /api/payment/sms-receive.php
 *
 * Android App থেকে SMS-এর তথ্য এখানে আসে। এখানেই সব
 * Security Check হয়, তারপর User-এর Balance যোগ হয়।
 * ═══════════════════════════════════════════════════════════
 */
include "conn.php";
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-Device-Secret');

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

$log_dir = __DIR__ . '/sms_logs';
if (!file_exists($log_dir)) { @mkdir($log_dir, 0777, true); }
function smsLog($msg) {
    global $log_dir;
    @file_put_contents($log_dir . '/sms_' . date('Y-m-d') . '.log', '[' . date('H:i:s') . "] $msg" . PHP_EOL, FILE_APPEND);
}

// ✅ Security ধাপ ১ — শুধু Registered Device-এর Request গ্রহণ করা
$deviceSecret = $_SERVER['HTTP_X_DEVICE_SECRET'] ?? ($_SERVER['REDIRECT_HTTP_X_DEVICE_SECRET'] ?? '');
$deviceStmt = $conn->prepare("SELECT id FROM sms_app_devices WHERE api_secret = ? AND is_active = 1 LIMIT 1");
$deviceStmt->bind_param("s", $deviceSecret);
$deviceStmt->execute();
$deviceResult = $deviceStmt->get_result();

if ($deviceResult->num_rows === 0) {
    smsLog("REJECTED: Unknown/Inactive Device Secret");
    echo json_encode(['code' => 1, 'msg' => 'Unauthorized Device']);
    exit;
}
$deviceId = $deviceResult->fetch_assoc()['id'];
$conn->query("UPDATE sms_app_devices SET last_seen = NOW() WHERE id = $deviceId");

// ✅ Data গ্রহণ
$input = json_decode(file_get_contents('php://input'), true);

// ✅ নতুন যোগ — MacroDroid-এর মতো App যদি Pre-Parsed Data-এর বদলে
// শুধু "raw_sms" (SMS-এর আসল Text) পাঠায়, তাহলে এখানেই Server
// নিজে সেটা থেকে Amount/TrxID বের করে নেয় (PHP Regex দিয়ে,
// Kotlin App-এর SmsParser.kt-এর মতোই একই Logic)।
if (isset($input['raw_sms']) && !isset($input['amount'])) {
    $rawSmsText = $input['raw_sms'];

    // Amount বের করা — "Tk 500" বা "BDT 500.00" জাতীয় Pattern
    preg_match('/(?:Tk|BDT)\s*([\d,]+\.?\d*)/i', $rawSmsText, $amountMatch);
    $extractedAmount = isset($amountMatch[1]) ? floatval(str_replace(',', '', $amountMatch[1])) : 0;

    // Transaction ID বের করা
    preg_match('/(?:Transaction ID|TrxID|TxnID)\s*[:\s]?\s*([A-Za-z0-9]+)/i', $rawSmsText, $trxidMatch);
    $extractedTrxid = $trxidMatch[1] ?? '';

    // Sender Number বের করা
    preg_match('/from\s+(01\d{9})/i', $rawSmsText, $senderMatch);
    $extractedSender = $senderMatch[1] ?? ($input['sender'] ?? 'unknown');

    $input['amount'] = $extractedAmount;
    $input['trxid'] = $extractedTrxid;
    $input['sender'] = $extractedSender;

    smsLog("PARSED FROM RAW SMS: Amount=$extractedAmount | TrxID=$extractedTrxid | Sender=$extractedSender");
}

$gateway = in_array($input['gateway'] ?? '', ['bkash', 'nagad']) ? $input['gateway'] : null;
$amount = round(floatval($input['amount'] ?? 0), 2);
$trxid = trim($input['trxid'] ?? '');
$sender = trim($input['sender'] ?? '');
$sms_time = trim($input['sms_time'] ?? date('Y-m-d H:i:s'));

smsLog("INCOMING: Gateway=$gateway | Amount=$amount | TrxID=$trxid | Sender=$sender");

if (!$gateway || $amount <= 0 || $trxid === '') {
    smsLog("REJECTED: Invalid data");
    echo json_encode(['code' => 1, 'msg' => 'Invalid Data']);
    exit;
}

// ✅ Security ধাপ ২ — Duplicate Transaction ID Check
$dupStmt = $conn->prepare("SELECT id FROM sms_transactions WHERE trxid = ? LIMIT 1");
$dupStmt->bind_param("s", $trxid);
$dupStmt->execute();
if ($dupStmt->get_result()->num_rows > 0) {
    smsLog("REJECTED: Duplicate TrxID - $trxid");
    echo json_encode(['code' => 1, 'msg' => 'Duplicate Transaction']);
    exit;
}

// ✅ Security ধাপ ৩ — SMS-কে প্রথমেই একটা রেকর্ড হিসেবে Save করা
// (Match হোক বা না হোক, প্রতিটা SMS-ই Audit-এর জন্য রাখা হচ্ছে)
$rawSms = json_encode($input);
$insertSms = $conn->prepare("INSERT INTO sms_transactions (trxid, amount, gateway, sender_number, sms_time, raw_sms, status) VALUES (?, ?, ?, ?, ?, ?, 'unmatched')");
$insertSms->bind_param("sdssss", $trxid, $amount, $gateway, $sender, $sms_time, $rawSms);
$insertSms->execute();
$smsRecordId = $conn->insert_id;

// ✅ Security ধাপ ৪ — Matching Pending Order খোঁজা
// (Amount + Gateway মিলতে হবে, আর Order তৈরি হওয়ার ৩০ মিনিটের মধ্যে হতে হবে)
$matchStmt = $conn->prepare("
    SELECT * FROM deposit_orders
    WHERE amount = ? AND gateway = ? AND status = 'pending' AND expires_at >= NOW()
    ORDER BY created_at ASC
    LIMIT 1
");
$matchStmt->bind_param("ds", $amount, $gateway);
$matchStmt->execute();
$matchResult = $matchStmt->get_result();

if ($matchResult->num_rows === 0) {
    smsLog("UNMATCHED: No pending order found for Amount=$amount Gateway=$gateway");
    echo json_encode(['code' => 0, 'msg' => 'SMS Recorded (কোনো Matching Order পাওয়া যায়নি, Admin Manual Check করবে)']);
    exit;
}

$order = $matchResult->fetch_assoc();

// ✅ সবকিছু একটা Transaction-এর ভেতরে — Atomic (একসাথে সফল/একসাথে ব্যর্থ)
$conn->begin_transaction();
try {
    // Order Status Update
    $updOrder = $conn->prepare("UPDATE deposit_orders SET status = 'success', matched_trxid = ?, matched_at = NOW() WHERE id = ? AND status = 'pending'");
    $updOrder->bind_param("si", $trxid, $order['id']);
    $updOrder->execute();
    if ($updOrder->affected_rows <= 0) {
        throw new Exception('Order status update failed (হয়তো ইতিমধ্যে Process হয়ে গেছে)');
    }

    // SMS Record-কে "Matched" করা
    $conn->query("UPDATE sms_transactions SET status = 'matched', order_id = '{$order['order_id']}' WHERE id = $smsRecordId");

    // ✅ User Balance বাড়ানো
    $balUpd = $conn->prepare("UPDATE shonu_kaichila SET motta = motta + ? WHERE balakedara = ?");
    $balUpd->bind_param("di", $amount, $order['user_id']);
    $balUpd->execute();
    if ($balUpd->affected_rows <= 0) {
        throw new Exception('User balance-এ যোগ করতে ব্যর্থ');
    }

    $conn->commit();
    smsLog("SUCCESS: Order {$order['order_id']} matched with TrxID $trxid. User {$order['user_id']} balance +$amount");
    echo json_encode(['code' => 0, 'msg' => 'Payment Verified & Balance Updated', 'order_id' => $order['order_id']]);

} catch (Throwable $e) {
    $conn->rollback();
    smsLog("CRITICAL: " . $e->getMessage());
    echo json_encode(['code' => 1, 'msg' => 'Processing Error: ' . $e->getMessage()]);
}
