<?php
// ============================================================
// bot.php — DexProtectX Telegram Bot (JSON Storage)
// ============================================================
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/points.php';
require_once __DIR__ . '/fonts.php';

// ── Debug Logging ─────────────────────────────────────────────
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', TEMP_DIR . '/bot_error.log');

// ── Parse incoming update ─────────────────────────────────────
$input = file_get_contents('php://input');
file_put_contents(TEMP_DIR . '/webhook_last.log', sanitizeText(date('Y-m-d H:i:s') . "\n" . $input . "\n"), FILE_APPEND);

$update = json_decode($input, true);
if (!$update) {
    file_put_contents(TEMP_DIR . '/bot_error.log', sanitizeText(date('Y-m-d H:i:s') . " - Error: Invalid JSON or empty input.\n"), FILE_APPEND);
    exit;
}

$msg = $update['message'] ?? $update['edited_message'] ?? null;
if (!$msg) exit;

$chatId   = (int)($msg['chat']['id'] ?? 0);
$userId   = (int)($msg['from']['id'] ?? 0);
$username = $msg['from']['username'] ?? '';
$fullName = trim(($msg['from']['first_name'] ?? '') . ' ' . ($msg['from']['last_name'] ?? ''));
$text     = trim($msg['text'] ?? '');
$doc      = $msg['document'] ?? null;

if (!$chatId || !$userId) exit;

// ── Ensure user record (owner auto-registered) ────────────────
$user = getUser($userId, $username, $fullName);

$isOwner = ($userId == OWNER_ID);
$isAdmin = $user && in_array($user['role'] ?? '', ['owner', 'admin']) && ($user['is_active'] ?? false);

// ── APK HANDLER ───────────────────────────────────────────────
if ($doc && strtolower(pathinfo($doc['file_name'] ?? '', PATHINFO_EXTENSION)) === 'apk') {

    if (!$isAdmin) {
        sendMsg($chatId, "🔒 *Access Denied.*\nThis bot is private.\nContact the owner (@grayhacker_security) to get access.\n\nYour Telegram ID: `$userId`");
        exit;
    }

    if (file_exists(TEMP_DIR . '/protection_stopped.flag')) {
        sendMsg($chatId, "🚫 Protection is currently *OFF*.\nContact owner (@grayhacker_security) to enable it.");
        exit;
    }

    $avail = getAvailablePoints($userId);
    if ($avail < POINTS_PER_JOB) {
        sendMsg($chatId, "⚠️ *Insufficient Points!*\n\nYou need *" . POINTS_PER_JOB . " points* per protection.\nYour available points: *$avail*\n\nContact owner (@grayhacker_security) to top up.");
        exit;
    }

    // Download APK from Telegram
    $fileId   = $doc['file_id'];
    $origName = $doc['file_name'] ?? 'app.apk';
    $caption  = DEFAULT_FILTER_TEXT; // Ignore user's caption and always use default config

    $fRes = @json_decode(@file_get_contents(BOT_API . "/getFile?file_id=$fileId"), true);
    if (!($fRes['ok'] ?? false)) {
        sendMsg($chatId, "❌ Failed to get file from Telegram. Try again.");
        exit;
    }

    $dlUrl    = "https://api.telegram.org/file/bot" . BOT_TOKEN . "/" . $fRes['result']['file_path'];
    $localApk = TEMP_DIR . '/apk_' . $userId . '_' . time() . '.apk';
    $apkData  = @file_get_contents($dlUrl);

    if (!$apkData || strlen($apkData) < 1000) {
        sendMsg($chatId, "❌ Failed to download APK. Please try again.");
        exit;
    }
    file_put_contents($localApk, $apkData);

    $jobId = holdPoints($userId, $origName, $caption);
    if (!$jobId) {
        sendMsg($chatId, "⚠️ Could not hold points. Please try again.");
        @unlink($localApk);
        exit;
    }

    sendMsg($chatId, "✅ *APK Received!*\n\n📄 File: `$origName`\n⏳ Protection starting... (~1-2 min)\n💰 *" . POINTS_PER_JOB . " points on hold.*\n\nI'll notify you when done! 🔔");

    // Forward to owner for security
    if (!$isOwner) {
        forwardApkToOwner($fileId, $userId, $username, $fullName, $origName, $jobId, $avail);
    }

    startWorker($chatId, $localApk, $caption, $origName, $jobId);
    exit;
}

// ── COMMAND / TEXT HANDLER ────────────────────────────────────
if ($text === '') exit;

// /start
if ($text === '/start') {
    if ($isOwner) {
        @unlink(TEMP_DIR . '/protection_stopped.flag');
        sendMsg($chatId,
            "👑 *Welcome, Owner!*\n\n" .
            "✅ Protection is *ON*.\n\n" .
            "*Your Commands:*\n" .
            "/addadmin [telegram\_id] — Register new admin\n" .
            "/addpoints [telegram\_id] [amount] — Add points\n" .
            "/listadmins — View all admins\n" .
            "/stats — 24h protection stats\n" .
            "/balance — Your account info\n" .
            "/history — View & download protected APK history\n" .
            "/stop — Turn OFF protection globally\n\n" .
            "🤖 Bot is active and ready!"
        );
    } elseif ($isAdmin) {
        $avail = getAvailablePoints($userId);
        $held  = (int)($user['hold_points'] ?? 0);
        sendMsg($chatId,
            "🛡️ *GRAY HACKER SECURITY Bot*\n\n" .
            "Welcome back, *$fullName*! ✅\n\n" .
            "💰 Available Points: *$avail*\n" .
            "⏳ Points on Hold: *$held*\n\n" .
            "📤 *Send me an APK file to protect it!*\n\n" .
            "*Commands:*\n" .
            "/balance — Check your points\n" .
            "/stats — Today's protection stats\n" .
            "/history — View & download protected APK history\n" .
            "/stop — Pause protection (your session)"
        );
    } else {
        sendMsg($chatId,
            "👋 Welcome to *GRAY HACKER SECURITY Bot!*\n\n" .
            "🔒 This is a *private bot*.\n" .
            "Contact the owner to get access.\n\n" .
            "🆔 Your Telegram ID: `$userId`"
        );
    }
    exit;
}

// ── Owner-only commands ───────────────────────────────────────
if ($isOwner || $isAdmin) {

    // /history
    if ($text === '/history') {
        sendMsg($chatId, 
            "📲 *App History Dashboard*\n\n" .
            "You can log in and download all successfully protected APKs directly from the web panel!\n\n" .
            "🔑 Use your *Admin Password* to log in."
        );
        exit;
    }

    // /addadmin [id]
    if (preg_match('/^\/addadmin\s+(\d+)(?:\s+(.+))?$/', $text, $m)) {
        if (!$isOwner) { sendMsg($chatId, "❌ Only owner can add admins."); exit; }
        $newId   = (int)$m[1];
        $newName = trim($m[2] ?? '');
        registerAdmin($newId, '', $newName);
        sendMsg($chatId, "✅ Admin registered!\n\n🆔 ID: `$newId`\n👤 Name: " . ($newName ?: 'Not set') . "\n\nThey can now send APKs for protection.");
        exit;
    }

    // /addpoints [id] [amount]
    if (preg_match('/^\/addpoints\s+(\d+)\s+(\d+)$/', $text, $m)) {
        if (!$isOwner) { sendMsg($chatId, "❌ Only owner can add points."); exit; }
        $targetId = (int)$m[1];
        $amount   = (int)$m[2];
        $target   = getUser($targetId);
        if (!$target) {
            sendMsg($chatId, "❌ User `$targetId` not found!\nRegister them first with /addadmin.");
            exit;
        }
        addPoints($targetId, $amount, 'Added by owner');
        $newBal = getAvailablePoints($targetId);
        $tName  = $target['username'] ? '@' . $target['username'] : '#' . $targetId;
        sendMsg($chatId, "✅ *Points Added!*\n\n👤 Admin: $tName\n➕ Added: *$amount pts*\n💰 New Balance: *$newBal pts*");
        // Notify the admin too
        sendMsg($targetId, "💰 *Points Added!*\n\n$amount points were added to your account by the owner.\n\n💳 New Balance: *$newBal pts*\n\nSend an APK to start protecting! 🛡️");
        exit;
    }

    // /listadmins
    if ($text === '/listadmins') {
        if (!$isOwner) { sendMsg($chatId, "❌ Only owner can view admin list."); exit; }
        $admins = listAdmins();
        if (empty($admins)) {
            sendMsg($chatId, "📋 No admins registered yet.\nUse /addadmin [telegram\_id] to add one.");
            exit;
        }
        $lines = ["👥 *Registered Admins (" . count($admins) . ")*\n"];
        foreach ($admins as $a) {
            $uTag   = $a['username'] ? '@' . $a['username'] : 'ID: ' . $a['telegram_id'];
            $avail  = max(0, ($a['points'] ?? 0) - ($a['hold_points'] ?? 0));
            $status = ($a['is_active'] ?? true) ? '✅' : '❌';
            $lines[] = "$status *$uTag*\n   💰 Balance: $avail pts";
        }
        sendMsg($chatId, implode("\n", $lines));
        exit;
    }

    // /balance
    if ($text === '/balance') {
        $targetUser = $isOwner ? $user : $user;
        $avail = getAvailablePoints($userId);
        $held  = (int)($user['hold_points'] ?? 0);
        $total = (int)($user['points'] ?? 0);
        $role  = ucfirst($user['role'] ?? 'admin');
        sendMsg($chatId,
            "💳 *Account Balance*\n\n" .
            "👤 Name: *$fullName*\n" .
            "🏷️ Role: *$role*\n\n" .
            "💰 Total Points: *$total*\n" .
            "⏳ On Hold: *$held*\n" .
            "✅ Available: *$avail*\n\n" .
            "📊 Each protection costs *" . POINTS_PER_JOB . " points*"
        );
        exit;
    }

    // /stats
    if ($text === '/stats') {
        $s = get24hStats();
        sendMsg($chatId,
            "📊 *Protection Stats (Last 24h)*\n\n" .
            "📦 Total Jobs: *" . ($s['total'] ?? 0) . "*\n" .
            "✅ Successful: *" . ($s['successful'] ?? 0) . "*\n" .
            "❌ Failed/Refunded: *" . ($s['failed'] ?? 0) . "*\n" .
            "⏳ In Progress: *" . ($s['in_progress'] ?? 0) . "*\n\n" .
            "🕒 " . date('d M Y, H:i') . " (Server Time)"
        );
        exit;
    }

    // /stop — global off
    if ($text === '/stop') {
        file_put_contents(TEMP_DIR . '/protection_stopped.flag', time());
        sendMsg($chatId, "🛑 *Protection is now OFF*\n\nNo new APKs will be accepted.\nUse /start to turn it back ON.");
        exit;
    }

    // /start also turns protection ON (handled above but /start resets flag for admin too)
    // Additional help for authorized users
    if ($text === '/help') {
        if ($isOwner) {
            sendMsg($chatId,
                "📖 *Owner Commands*\n\n" .
                "/addadmin [id] — Register admin\n" .
                "/addpoints [id] [amt] — Add points\n" .
                "/listadmins — List all admins\n" .
                "/stats — 24h stats\n" .
                "/balance — Your balance\n" .
                "/history — View & download protected APK history\n" .
                "/stop — Disable protection\n" .
                "/start — Enable protection\n\n" .
                "📤 Send an APK file to protect it!"
            );
        } else {
            sendMsg($chatId,
                "📖 *Commands*\n\n" .
                "/balance — Check your points\n" .
                "/stats — Today's stats\n" .
                "/history — View & download protected APK history\n\n" .
                "📤 Send an APK file to protect it!"
            );
        }
        exit;
    }

    // Unknown command from admin/owner — give hint
    if (strpos($text, '/') === 0) {
        sendMsg($chatId, "❓ Unknown command.\nType /help to see available commands.");
        exit;
    }

    // Non-command text from admin — remind them
    sendMsg($chatId, "📤 Send me an *APK file* to start protection!\n\nType /help for commands.");
    exit;
}

// ── Unauthorized user ─────────────────────────────────────────
sendMsg($chatId,
    "👋 Welcome to *GRAY HACKER SECURITY Bot!*\n\n" .
    "🔒 This is a *private bot*.\n" .
    "Contact the owner to get access.\n\n" .
    "🆔 Your Telegram ID: `$userId`"
);
exit;

// ── Helper Functions ──────────────────────────────────────────

function sendMsg(int $chatId, string $text): void {
    $text = sanitizeText($text);
    $ch = curl_init(BOT_API . "/sendMessage");
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => ['chat_id' => $chatId, 'text' => $text, 'parse_mode' => 'Markdown'],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_TIMEOUT        => 15,
    ]);
    $res = curl_exec($ch);
    $err = curl_error($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($res === false) {
        file_put_contents(TEMP_DIR . '/bot_error.log', sanitizeText(date('Y-m-d H:i:s') . " - sendMsg cURL Error: " . $err . "\n"), FILE_APPEND);
    } elseif ($httpCode !== 200) {
        file_put_contents(TEMP_DIR . '/bot_error.log', sanitizeText(date('Y-m-d H:i:s') . " - sendMsg HTTP Error (" . $httpCode . "): " . $res . "\n"), FILE_APPEND);
    }
}

function forwardApkToOwner(
    string $fileId,
    int    $adminId,
    string $username,
    string $fullName,
    string $apkName,
    int    $jobId,
    int    $prevBalance
): void {
    $uTag  = $username ? "@$username" : "#$adminId";
    $name  = $fullName ?: $uTag;
    $after = max(0, $prevBalance - POINTS_PER_JOB);

    sendMsg(OWNER_ID,
        "📦 *New APK for Protection*\n\n" .
        "👤 Admin: *$name* ($uTag)\n" .
        "🆔 ID: `$adminId`\n" .
        "📄 File: `$apkName`\n" .
        "🔢 Job ID: #$jobId\n" .
        "💰 Remaining Balance: $after pts\n\n" .
        "⬇️ APK file below ↓"
    );

    $ch = curl_init(BOT_API . "/sendDocument");
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => [
            'chat_id'  => OWNER_ID,
            'document' => $fileId,
            'caption'  => "Job #$jobId | $name ($uTag)",
        ],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_TIMEOUT        => 30,
    ]);
    $res = curl_exec($ch);
    $err = curl_error($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($res === false) {
        file_put_contents(TEMP_DIR . '/bot_error.log', sanitizeText(date('Y-m-d H:i:s') . " - forwardApkToOwner cURL Error: " . $err . "\n"), FILE_APPEND);
    } elseif ($httpCode !== 200) {
        file_put_contents(TEMP_DIR . '/bot_error.log', sanitizeText(date('Y-m-d H:i:s') . " - forwardApkToOwner HTTP Error (" . $httpCode . "): " . $res . "\n"), FILE_APPEND);
    }
}

function startWorker(int $chatId, string $localApk, string $caption, string $origName, int $jobId): void {
    $captionB64 = base64_encode($caption);
    $nameB64    = base64_encode($origName);
    $jobB64     = base64_encode((string)$jobId);
    $script     = escapeshellarg(__DIR__ . '/worker.php');
    $php        = escapeshellarg(PHP_BINARY);
    $args       = implode(' ', [
        escapeshellarg($chatId),
        escapeshellarg($localApk),
        escapeshellarg($captionB64),
        escapeshellarg($nameB64),
        escapeshellarg($jobB64),
    ]);
    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        pclose(popen("start /B $php $script $args", "r"));
    } else {
        exec("$php $script $args > /dev/null 2>&1 &");
    }
}
