<?php
/**
 * ═══════════════════════════════════════════════════════════
 * Callback.php — Root (public_html) — Dual Provider Support
 *
 * এখন এই একটা File-ই দুটো Provider (Supabase + SilentAPI)-এর
 * Callback Handle করে। System প্রথমে Provider ১-এর Secret দিয়ে
 * Signature Verify করার চেষ্টা করে, না মিললে Provider ২-এর
 * Secret দিয়ে Try করে — যেটা মেলে, সেটাকেই আসল ধরে নেয়।
 *
 * ✅ ঠিক করা হলো — GetGameUrl.php, User-ID পাঠানোর সময়
 * "site2_" Prefix জুড়ে পাঠায় (Multi-Site Collision এড়াতে)।
 * কিন্তু Callback ফিরে আসার সময়ও এই একই Prefix-সহ আসে —
 * আগে এটা কখনো সরানো হতো না, তাই Database-এ সঠিক User
 * খুঁজে পাওয়া যেতো না। এখন এই Prefix সরিয়ে, আসল User-ID
 * বের করে ব্যবহার করা হচ্ছে।
 * ═══════════════════════════════════════════════════════════
 */

error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Signature');
header('Access-Control-Allow-Methods: POST, OPTIONS');

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

mysqli_report(MYSQLI_REPORT_OFF);

// ============================================
// DATABASE CONFIGURATION (আগের মতোই অপরিবর্তিত)
// ============================================
define('DB_HOST', 'localhost');
define('DB_PORT', 3306);
define('DB_NAME', 'ayjfglxy_Cv111v');
define('DB_USER', 'ayjfglxy_Cv111v');
define('DB_PASS', 'ayjfglxy_Cv111v');

// ============================================
// ✅ দুটো Provider-এর নিজস্ব Secret Key
// ============================================
define('P1_SECRET', '425e832c35b8499aefc4a2c3f5dad242a69240ea727f94d4b9015b1e95448b78'); // Supabase
define('P2_SECRET', '87dc7cf26e24037314708f8fbcd7dc24ddba6591392202c6fd9bdc8ec2ee2c80'); // SilentAPI

// ✅ নতুন যোগ — GetGameUrl.php-এর SITE_TAG-এর সাথে মিলিয়ে
define('SITE_TAG', 'site2');

$log_dir = __DIR__ . '/apilogs';
if (!file_exists($log_dir)) { @mkdir($log_dir, 0777, true); }

function writeLog($msg) {
    global $log_dir;
    $date = date('Y-m-d');
    $time = date('H:i:s');
    @file_put_contents($log_dir . "/aviator_$date.txt", "[$time] $msg" . PHP_EOL, FILE_APPEND);
}

function jsonExit($statusCode, $payload) {
    http_response_code($statusCode);
    echo json_encode($payload, JSON_UNESCAPED_UNICODE);
    exit;
}

function getSignatureHeader() {
    $headers = function_exists('getallheaders') ? getallheaders() : [];
    foreach ($headers as $key => $value) {
        if (strtolower($key) === 'x-signature') { return trim($value); }
    }
    return trim($_SERVER['HTTP_X_SIGNATURE'] ?? '');
}

writeLog("========== New Request ==========");

$conn = @new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT);
if ($conn->connect_error) {
    writeLog("CRITICAL: DB Connection Failed - " . $conn->connect_error);
    jsonExit(500, ['code' => 1, 'msg' => 'DB Connection Error', 'balance' => 0, 'credit_amount' => 0]);
}

$input_json = file_get_contents('php://input');
$data = json_decode($input_json, true);
$signature = getSignatureHeader();

writeLog("Payload: " . $input_json . " | Sig: " . $signature);

if (!is_array($data)) {
    writeLog("ERROR: Invalid JSON body");
    jsonExit(400, ['code' => 1, 'msg' => 'Invalid JSON', 'balance' => 0, 'credit_amount' => 0]);
}

// ✅ কোন Provider থেকে এসেছে, Signature দিয়ে বের করা
$providerUsed = null;
if ($signature !== '') {
    $calc_p1 = hash_hmac('sha256', $input_json, P1_SECRET);
    $calc_p2 = hash_hmac('sha256', $input_json, P2_SECRET);

    if (hash_equals($calc_p1, $signature)) {
        $providerUsed = 1;
    } elseif (hash_equals($calc_p2, $signature)) {
        $providerUsed = 2;
    }
}

if ($providerUsed === null) {
    writeLog("ERROR: Signature Mismatch (matched neither Provider). Sent: $signature");
    jsonExit(401, ['code' => 1, 'msg' => 'Invalid Signature', 'balance' => 0, 'credit_amount' => 0]);
}

writeLog("INFO: Verified as Provider $providerUsed");

// ✅ দুটো Provider-ই মূলত একই ধরনের Field ব্যবহার করে
$uid_raw      = trim((string)($data['member_account'] ?? ''));
$game_code    = trim((string)($data['game_uid'] ?? 'unknown'));
$bet_amount   = round((float)($data['bet_amount'] ?? 0), 2);
$win_amount   = round((float)($data['win_amount'] ?? 0), 2);
$txn_id       = trim((string)($data['serial_number'] ?? ''));
$round_id     = trim((string)($data['game_round'] ?? ''));
$currency     = trim((string)($data['currency_code'] ?? 'INR'));

if ($uid_raw === '') {
    writeLog("ERROR: Missing member_account");
    jsonExit(400, ['code' => 1, 'msg' => 'Missing member_account', 'balance' => 0, 'credit_amount' => 0]);
}

// ✅ ঠিক করা হলো — GetGameUrl.php যে "site2_" Prefix জুড়ে
// User-ID পাঠিয়েছিল, Callback ফেরত আসার সময় সেই একই Prefix
// থাকে। এখানে সেটা সরিয়ে, আসল Database-User-ID বের করা হচ্ছে।
$sitePrefix = SITE_TAG . '_';
if (strpos($uid_raw, $sitePrefix) === 0) {
    $uid = substr($uid_raw, strlen($sitePrefix));
    writeLog("INFO: SITE_TAG সরানো হলো — Raw: '$uid_raw' → Clean: '$uid'");
} else {
    // Prefix না থাকলে (অন্য কোনো পুরনো/ভিন্ন Flow থেকে এলে),
    // Raw Value-ই ব্যবহার করা — Safe Fallback
    $uid = $uid_raw;
    writeLog("INFO: SITE_TAG Prefix পাওয়া যায়নি, Raw ব্যবহার হচ্ছে: '$uid'");
}

writeLog("Player: $uid | Provider: $providerUsed | Game: $game_code | Bet: $bet_amount | Win: $win_amount | TxnID: $txn_id");

// ✅ Duplicate Transaction Check (দুই Provider-এর জন্যই একই Table ব্যবহার হচ্ছে)
if ($txn_id !== '') {
    $dup_stmt = $conn->prepare("SELECT balance_after FROM game_bet_logs WHERE serial_number = ? LIMIT 1");
    if ($dup_stmt) {
        $dup_stmt->bind_param("s", $txn_id);
        $dup_stmt->execute();
        $dup_res = $dup_stmt->get_result();
        if ($dup_res && $dup_res->num_rows > 0) {
            $existing = $dup_res->fetch_assoc();
            $bal = round((float)($existing['balance_after'] ?? 0), 2);
            writeLog("INFO: Duplicate txn $txn_id — returning cached balance $bal");
            jsonExit(200, ['code' => 0, 'msg' => 'Success', 'balance' => $bal, 'credit_amount' => $bal]);
        }
        $dup_stmt->close();
    }
}

$bal_stmt = $conn->prepare("SELECT motta FROM shonu_kaichila WHERE balakedara = ? LIMIT 1");
if (!$bal_stmt) {
    writeLog("CRITICAL: Balance prepare failed - " . $conn->error);
    jsonExit(500, ['code' => 1, 'msg' => 'DB Error', 'balance' => 0, 'credit_amount' => 0]);
}
$bal_stmt->bind_param("s", $uid);
$bal_stmt->execute();
$bal_res = $bal_stmt->get_result();
if (!$bal_res || $bal_res->num_rows === 0) {
    writeLog("ERROR: User $uid not found in shonu_kaichila");
    jsonExit(404, ['code' => 1, 'msg' => 'User not found', 'balance' => 0, 'credit_amount' => 0]);
}
$user_row = $bal_res->fetch_assoc();
$current_bal = round((float)$user_row['motta'], 2);
$bal_stmt->close();

if ($bet_amount == 0 && $win_amount == 0) {
    writeLog("BALANCE CHECK: User $uid = $current_bal");
    jsonExit(200, ['code' => 0, 'msg' => 'Success', 'balance' => $current_bal, 'credit_amount' => $current_bal]);
}

if ($bet_amount > 0 && $current_bal < $bet_amount) {
    writeLog("ERROR: Insufficient balance. Bal: $current_bal | Bet: $bet_amount");
    jsonExit(200, ['code' => 1, 'msg' => 'Insufficient balance', 'balance' => $current_bal, 'credit_amount' => $current_bal]);
}

$conn->begin_transaction();

try {
    if ($bet_amount > 0) {
        $update_stmt = $conn->prepare("UPDATE shonu_kaichila SET motta = motta - ? + ? WHERE balakedara = ? AND motta >= ?");
        if (!$update_stmt) throw new Exception('Update prepare failed: ' . $conn->error);
        $update_stmt->bind_param("ddsd", $bet_amount, $win_amount, $uid, $bet_amount);
    } else {
        $update_stmt = $conn->prepare("UPDATE shonu_kaichila SET motta = motta + ? WHERE balakedara = ?");
        if (!$update_stmt) throw new Exception('Win update prepare failed: ' . $conn->error);
        $update_stmt->bind_param("ds", $win_amount, $uid);
    }

    $update_stmt->execute();
    if ($update_stmt->affected_rows <= 0) {
        throw new Exception('Balance update rejected (affected_rows=0)');
    }
    $update_stmt->close();

    $new_bal_stmt = $conn->prepare("SELECT motta FROM shonu_kaichila WHERE balakedara = ? LIMIT 1");
    $new_bal_stmt->bind_param("s", $uid);
    $new_bal_stmt->execute();
    $new_bal_res = $new_bal_stmt->get_result();
    $new_bal_row = $new_bal_res->fetch_assoc();
    $new_balance = round((float)($new_bal_row['motta'] ?? 0), 2);
    $new_bal_stmt->close();

    $profit = round($win_amount - $bet_amount, 2);
    $log_stmt = $conn->prepare("INSERT INTO game_bet_logs (user_id, game_code, bet_amount, win_amount, profit_loss, balance_before, balance_after, serial_number, game_round, currency_code, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())");
    if ($log_stmt) {
        $log_stmt->bind_param("ssdddddsss", $uid, $game_code, $bet_amount, $win_amount, $profit, $current_bal, $new_balance, $txn_id, $round_id, $currency);
        $log_stmt->execute();
        $log_stmt->close();
    } else {
        writeLog("WARN: game_bet_logs insert skipped - " . $conn->error);
    }

    $conn->commit();
    writeLog("SUCCESS: Provider $providerUsed | User $uid | Old: $current_bal | New: $new_balance");
    jsonExit(200, ['code' => 0, 'msg' => 'Success', 'balance' => $new_balance, 'credit_amount' => $new_balance]);

} catch (Throwable $e) {
    $conn->rollback();
    writeLog("CRITICAL: " . $e->getMessage());

    $retry_stmt = $conn->prepare("SELECT motta FROM shonu_kaichila WHERE balakedara = ? LIMIT 1");
    $fallback_bal = $current_bal;
    if ($retry_stmt) {
        $retry_stmt->bind_param("s", $uid);
        $retry_stmt->execute();
        $retry_res = $retry_stmt->get_result();
        $retry_row = $retry_res ? $retry_res->fetch_assoc() : null;
        $fallback_bal = round((float)($retry_row['motta'] ?? $current_bal), 2);
        $retry_stmt->close();
    }

    jsonExit(500, ['code' => 1, 'msg' => 'Transaction Failed', 'balance' => $fallback_bal, 'credit_amount' => $fallback_bal]);
}
