<?php
require_once '../config/connect.php';
require_once '../config/whatsapp.php';
require_once '../config/topup.php';

header('Content-Type: application/json');

function bot_json_response(int $statusCode, array $payload): void
{
    http_response_code($statusCode);
    echo json_encode($payload, JSON_UNESCAPED_SLASHES);
    exit();
}

function bot_get_payload(): array
{
    $raw = file_get_contents('php://input');
    $decoded = json_decode((string)$raw, true);

    if (is_array($decoded)) {
        return $decoded;
    }

    return $_POST;
}

function bot_extract_sender(array $payload): string
{
    $candidates = [
        $payload['sender'] ?? null,
        $payload['from'] ?? null,
        $payload['number'] ?? null,
        $payload['phone'] ?? null,
    ];

    foreach ($candidates as $candidate) {
        if (is_string($candidate) && trim($candidate) !== '') {
            return trim($candidate);
        }
    }

    return '';
}

function bot_lookup_sender_key(string $sender): string
{
    $sender = trim($sender);

    if ($sender === '') {
        return '';
    }

    if (strpos($sender, '@') !== false) {
        $sender = explode('@', $sender, 2)[0];
    }

    return wa_normalize_number($sender);
}

function bot_extract_message(array $payload): string
{
    $candidates = [
        $payload['message'] ?? null,
        $payload['text'] ?? null,
        $payload['body'] ?? null,
    ];

    foreach ($candidates as $candidate) {
        if (is_string($candidate) && trim($candidate) !== '') {
            return trim($candidate);
        }
    }

    return '';
}

function bot_is_ignored_payload(array $payload): bool
{
    $flags = [
        $payload['isGroup'] ?? null,
        $payload['group'] ?? null,
        $payload['fromMe'] ?? null,
        $payload['is_from_me'] ?? null,
    ];

    foreach ($flags as $flag) {
        if ($flag === true || $flag === 'true' || $flag === 1 || $flag === '1') {
            return true;
        }
    }

    return false;
}

function bot_help_message(string $agentName): string
{
    return "Halo {$agentName}\n"
        . "Perintah bot topup:\n"
        . "1. BANK\n"
        . "2. STATUS\n"
        . "3. TOPUP\n"
        . "4. TOPUP 200000 BRI\n\n"
        . "Format nominal tanpa titik/koma lebih aman.";
}

function bot_admin_contact_lines(mysqli $db): array
{
    $config = wa_get_config($db);
    $targets = $config['admin_targets'] ?? [];

    if (empty($targets)) {
        return ["Nomor admin belum dikonfigurasi."];
    }

    $lines = ["Konfirmasi transfer ke WhatsApp admin:"];

    foreach ($targets as $index => $target) {
        $lines[] = ($index + 1) . ". " . $target;
    }

    return $lines;
}

function bot_bank_list(mysqli $db, bool $includeAdminContact = false): string
{
    $query = mysqli_query($db, "SELECT bank, nama_rekening, nomor_rekening FROM tb_billing ORDER BY bank ASC");

    if ((!$query || mysqli_num_rows($query) === 0) && !bayarvip_is_configured($db)) {
        return "Metode pembayaran belum tersedia.";
    }

    $lines = ["Daftar metode topup:"];

    if (bayarvip_is_configured($db)) {
        $lines[] = "QRIS Otomatis";
    }

    if ($query) {
        while ($row = mysqli_fetch_assoc($query)) {
            $lines[] = $row['bank'] . " - " . $row['nama_rekening'] . " - " . $row['nomor_rekening'];
        }
    }

    $lines[] = "";
    if ($includeAdminContact) {
        foreach (bot_admin_contact_lines($db) as $line) {
            $lines[] = $line;
        }
        $lines[] = "";
        $lines[] = bayarvip_is_configured($db) ? "Kirim format: TOPUP 200000 QRIS" : "Kirim format: TOPUP 200000 BRI";
        $lines[] = "Untuk metode transfer bank, konfirmasi ke WhatsApp admin di atas, bukan ke nomor bot.";
        return implode("\n", $lines);
    }

    $lines[] = bayarvip_is_configured($db) ? "Contoh: TOPUP 200000 QRIS" : "Contoh: TOPUP 200000 BRI";

    return implode("\n", $lines);
}

function bot_status_message(mysqli $db, string $agentCode): string
{
    $agent = agent_find_by_identifier($db, $agentCode);
    $where = $agent !== null
        ? agent_reference_condition($db, 'agent_code', $agent)
        : "agent_code = '" . mysqli_real_escape_string($db, $agentCode) . "'";
    $query = mysqli_query(
        $db,
        "SELECT trxid, amount, balance, metode, status, created
         FROM tb_balance
         WHERE $where
         ORDER BY id DESC
         LIMIT 3"
    );

    if (!$query || mysqli_num_rows($query) === 0) {
        return "Belum ada riwayat topup untuk agent ini.";
    }

    $lines = ["3 status topup terakhir:"];

    while ($row = mysqli_fetch_assoc($query)) {
        $lines[] = $row['status']
            . " | " . $row['trxid']
            . " | Rp " . number_format((float)$row['amount'], 0, ',', '.')
            . " | " . $row['metode']
            . " | " . $row['created'];
    }

    return implode("\n", $lines);
}

function bot_general_message(mysqli $db, string $agentName, string $message): string
{
    $normalized = strtoupper(trim(preg_replace('/\s+/', ' ', $message) ?? ''));

    if (preg_match('/\b(HALO|HAI|P|ASSALAM|PERMISI)\b/i', $normalized) === 1) {
        return "Halo {$agentName}\n"
            . "Kalau mau cek rekening topup kirim BANK.\n"
            . "Kalau mau lihat status topup kirim STATUS.\n"
            . "Kalau mau request topup kirim TOPUP 200000 BRI.";
    }

    if (
        preg_match('/\b(REKENING|BANK|TRANSFER|TOPUP|DEPOSIT)\b/i', $normalized) === 1
        || strpos($normalized, 'CARA TOPUP') !== false
    ) {
        return bot_bank_list($db, true);
    }

    if (preg_match('/\b(KONFIRMASI|BUKTI|SUDAH TRANSFER|UDAH TRANSFER|TF)\b/i', $normalized) === 1) {
        $lines = [
            "Kalau transfer sudah dilakukan, silakan konfirmasi ke WhatsApp admin berikut:",
        ];

        foreach (bot_admin_contact_lines($db) as $index => $line) {
            if ($index === 0 && strpos($line, 'Konfirmasi transfer') === 0) {
                continue;
            }
            $lines[] = $line;
        }

        $lines[] = "Sertakan bukti transfer dan nominal topup agar admin bisa proses lebih cepat.";

        return implode("\n", $lines);
    }

    if (preg_match('/\b(STATUS|CEK STATUS|PENDING)\b/i', $normalized) === 1) {
        return "Untuk cek status topup terakhir, kirim command STATUS.";
    }

    return "Pesan belum dikenali.\n"
        . "Kirim HELP untuk lihat menu.\n"
        . "Atau langsung kirim BANK, STATUS, TOPUP, atau TOPUP 200000 BRI.";
}

function bot_topup_error_text(string $code): string
{
    $messages = [
        'invalid_whatsapp' => 'Nomor WhatsApp belum valid. Update dulu dari profile agent.',
        'payment_method_required' => 'Metode pembayaran wajib diisi. Cek daftar dengan kirim BANK.',
        'invalid_balance' => 'Nominal topup tidak valid.',
        'below_minimum' => 'Nominal di bawah minimal topup.',
        'invalid_amount' => 'Format nominal tidak valid.',
        'already_pending' => 'Masih ada request topup pending. Tunggu admin proses dulu.',
        'payment_method_not_found' => 'Metode pembayaran tidak ditemukan. Kirim BANK untuk lihat daftar.',
        'insert_failed' => 'Gagal membuat request topup. Coba lagi.',
        'agent_not_found' => 'Agent tidak ditemukan.',
        'bayarvip_not_configured' => 'QRIS belum aktif. Admin perlu melengkapi konfigurasi QRIS otomatis.',
        'bayarvip_failed' => 'Gagal membuat QRIS. Coba lagi atau gunakan metode bank lain.',
        'bayarvip_invalid_response' => 'Response QRIS belum valid. Coba lagi atau hubungi admin.',
    ];

    return $messages[$code] ?? 'Permintaan tidak bisa diproses.';
}

$payload = bot_get_payload();

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
    bot_json_response(200, [
        'status' => true,
        'message' => 'Webhook ready',
    ]);
}

wa_log('webhook_incoming', [
    'keys' => array_keys($payload),
    'payload' => array_intersect_key($payload, array_flip([
        'sender',
        'from',
        'number',
        'phone',
        'message',
        'text',
        'body',
        'device',
        'name',
    ])),
]);

if (!wa_is_configured($call)) {
    bot_json_response(503, ['status' => false, 'message' => 'WhatsApp sender is not configured']);
}

if (!wa_verify_webhook_secret($call, $payload)) {
    bot_json_response(403, ['status' => false, 'message' => 'Invalid webhook secret']);
}

if (bot_is_ignored_payload($payload)) {
    bot_json_response(200, ['status' => true, 'message' => 'Ignored']);
}

$sender = bot_extract_sender($payload);
$message = bot_extract_message($payload);
$senderLookup = bot_lookup_sender_key($sender);

if ($sender === '' || $message === '') {
    wa_log('webhook_rejected', [
        'reason' => 'missing_sender_or_message',
        'sender' => $sender,
        'message' => $message,
    ]);
    bot_json_response(400, ['status' => false, 'message' => 'Sender or message missing']);
}

wa_log('webhook_parsed', [
    'sender' => $sender,
    'sender_lookup' => $senderLookup,
    'message' => $message,
]);

$agent = $senderLookup !== '' ? wa_find_agent_by_whatsapp($call, $senderLookup) : null;

if ($agent === null) {
    wa_send_message(
        $call,
        $sender,
        "Nomor WA ini belum terdaftar di agent.\nSilakan isi nomor WhatsApp di profile agent atau minta admin update data agent."
    );
    bot_json_response(200, ['status' => true, 'message' => 'Agent not registered']);
}

$agentName = trim((string)($agent['agent_name'] ?? 'Agent'));
$normalizedMessage = strtoupper(trim(preg_replace('/\s+/', ' ', $message) ?? ''));

if ($normalizedMessage === 'HELP' || $normalizedMessage === 'MENU') {
    wa_send_message($call, $sender, bot_help_message($agentName));
    bot_json_response(200, ['status' => true, 'message' => 'Help sent']);
}

if ($normalizedMessage === 'BANK' || $normalizedMessage === 'METODE') {
    wa_send_message($call, $sender, bot_bank_list($call));
    bot_json_response(200, ['status' => true, 'message' => 'Bank list sent']);
}

if ($normalizedMessage === 'STATUS') {
    wa_send_message($call, $sender, bot_status_message($call, $agentName));
    bot_json_response(200, ['status' => true, 'message' => 'Status sent']);
}

if ($normalizedMessage === 'TOPUP') {
    wa_send_message($call, $sender, bot_bank_list($call, true));
    bot_json_response(200, ['status' => true, 'message' => 'Topup instruction sent']);
}

if (strpos($normalizedMessage, 'TOPUP ') === 0 && preg_match('/^TOPUP\s+([\d.,]+)\s+([A-Z0-9_-]+)$/i', $normalizedMessage, $matches) !== 1) {
    wa_send_message($call, $sender, "Format topup belum tepat.\nContoh yang benar: TOPUP 200000 BRI");
    bot_json_response(200, ['status' => true, 'message' => 'Invalid topup format']);
}

if (preg_match('/^TOPUP\s+([\d.,]+)\s+([A-Z0-9_-]+)$/i', $normalizedMessage, $matches) !== 1) {
    wa_send_message($call, $sender, bot_general_message($call, $agentName, $message));
    bot_json_response(200, ['status' => true, 'message' => 'General reply sent']);
}

$amount = (float)preg_replace('/[^\d]/', '', $matches[1]);
$paymentMethod = strtoupper(trim($matches[2]));

$result = topup_create_request($call, [
    'agent_name' => $agentName,
    'whatsapp' => $senderLookup !== '' ? $senderLookup : $sender,
    'amount' => $amount,
    'payment_method' => $paymentMethod,
]);

if (!$result['ok']) {
    wa_send_message($call, $sender, bot_topup_error_text((string)$result['code']));
    bot_json_response(200, ['status' => true, 'message' => 'Topup rejected']);
}

$currencyAmount = number_format((float)$result['amount'], 0, ',', '.');
$coinLabel = number_format((float)$result['balance'], 0, ',', '.');
$adminUrl = wa_app_url('index?page=ProsesTopup');

if (topup_is_qris_method((string)$result['payment_method'])) {
    $qrUrl = (string)($result['gateway']['qr_url'] ?? bayarvip_qr_url($call, (string)$result['trxid']));
    $agentReply = "Request topup QRIS diterima via bot\n"
        . "TrxID: {$result['trxid']}\n"
        . "Nominal: Rp {$currencyAmount}\n"
        . "Coin: {$coinLabel}\n"
        . "Status: Menunggu pembayaran QRIS\n"
        . "Invoice: {$result['checkout_url']}\n"
        . "QRIS: {$qrUrl}";
} else {
    $agentReply = "Request topup diterima via bot\n"
        . "TrxID: {$result['trxid']}\n"
        . "Nominal: Rp {$currencyAmount}\n"
        . "Coin: {$coinLabel}\n"
        . "Metode: {$result['payment_method']}\n"
        . "Transfer ke: {$result['nama_rekening']} / {$result['nomor_rekening']}\n"
        . "Status: Menunggu konfirmasi admin\n\n"
        . implode("\n", bot_admin_contact_lines($call)) . "\n"
        . "Setelah transfer, konfirmasi ke WhatsApp admin di atas, bukan ke nomor bot.";
}

$adminMessage = "Request topup baru dari bot WA\n"
    . "TrxID: {$result['trxid']}\n"
    . "Agent: {$agentName}\n"
    . "Nominal: Rp {$currencyAmount}\n"
    . "Coin: {$coinLabel}\n"
    . "Metode: {$result['payment_method']}\n"
    . "WA: " . ($senderLookup !== '' ? $senderLookup : $sender) . "\n"
    . "Waktu: {$result['created']}\n"
    . (topup_is_qris_method((string)$result['payment_method'])
        ? "Invoice: {$result['checkout_url']}"
        : "Proses admin: {$adminUrl}");

wa_send_message($call, $sender, $agentReply);
wa_send_admin_alert($call, $adminMessage);

bot_json_response(200, ['status' => true, 'message' => 'Topup created']);
