<?php
/**
 * chat_foreigners_callback.php
 * ─────────────────────────────
 * PesaFlux/LipaLink POSTs this JSON after every payment result:
 * {
 *   "event":            "payment.success",
 *   "transaction_id":   "PFX20240101ABCDEF",
 *   "mpesa_receipt":    "QHY67XXXXX",
 *   "msisdn":           "254712345678",
 *   "amount":           100.00,
 *   "reference":        "CF_UNLOCK_123_1234567890",
 *   "business_id":      6,
 *   "status":           "Success",
 *   "transaction_date": "2024-01-01 12:00:00"
 * }
 * Respond HTTP 200. PesaFlux does NOT retry on failure.
 */

require_once '../config/database.php';
require_once '../includes/functions.php';
require_once '../includes/lipalink.php'; // LipaLink/PesaFlux API helper

// ── Respond 200 immediately so PesaFlux doesn't time out ──────────
header('Content-Type: application/json');
http_response_code(200);
echo json_encode(['ResultCode' => 0, 'ResultDesc' => 'Received']);
if (function_exists('fastcgi_finish_request')) fastcgi_finish_request();

// ── Logging ───────────────────────────────────────────────────────
$log_file = __DIR__ . '/chat_foreigners_callback_log.txt';
function cf_log($msg) {
    global $log_file;
    file_put_contents($log_file, '[' . date('Y-m-d H:i:s') . '] ' . $msg . "\n", FILE_APPEND);
}

$raw = file_get_contents('php://input');
cf_log("===== NEW CALLBACK =====");
cf_log("RAW: " . $raw);

// ── Parse webhook using shared LipaLink helper ───────────────────
$wh = lipalink_parse_webhook($raw);
if (!$wh['valid']) {
    cf_log("ERROR: Invalid or unrecognisable webhook payload");
    exit;
}

$event          = $wh['event'];
$transaction_id = $wh['transaction_id'];
$mpesa_receipt  = $wh['mpesa_receipt'];
$paid_amount    = $wh['amount'];
$wh_reference   = $wh['reference'];
$isSuccess      = $wh['is_success'];
$isFailed       = $wh['is_failure'];

cf_log("event=$event tx_id=$transaction_id status={$wh['status']} amount=$paid_amount ref=$wh_reference");

if (!$isSuccess && !$isFailed) {
    cf_log("Non-terminal event — ignoring");
    exit;
}

$conn = getConnection();

// ── Ensure table exists ───────────────────────────────────────────
$chk = $conn->query("SHOW TABLES LIKE 'chat_foreigners_payments'");
if (!$chk || $chk->num_rows === 0) {
    cf_log("chat_foreigners_payments table missing");
    exit;
}

// ── Find payment record ───────────────────────────────────────────
// Try by checkout_request_id (= transaction_id we stored after STK push)
// then by reference (our CF_UNLOCK_xxx reference)
$payment = null;

if ($transaction_id) {
    $s = $conn->prepare("SELECT * FROM chat_foreigners_payments
        WHERE checkout_request_id=? LIMIT 1");
    $s->bind_param("s", $transaction_id); $s->execute();
    $payment = $s->get_result()->fetch_assoc();
}

if (!$payment && $wh_reference) {
    $s = $conn->prepare("SELECT * FROM chat_foreigners_payments
        WHERE reference=? LIMIT 1");
    $s->bind_param("s", $wh_reference); $s->execute();
    $payment = $s->get_result()->fetch_assoc();
}

if (!$payment) {
    cf_log("No payment record found for tx_id=$transaction_id ref=$wh_reference");
    exit;
}

cf_log("Found payment id={$payment['id']} user={$payment['user_id']} status={$payment['status']}");

// ── Already processed — idempotency guard ─────────────────────────
if ($payment['status'] === 'completed') {
    cf_log("Already completed — skip");
    exit;
}

// ── Process result ────────────────────────────────────────────────
if ($isSuccess) {
    $amt = $paid_amount > 0 ? $paid_amount : $payment['amount'];
    $upd = $conn->prepare("UPDATE chat_foreigners_payments
        SET status='completed', completed_at=NOW(), checkout_request_id=?
        WHERE id=? AND status='pending'");
    $upd->bind_param("si", $transaction_id, $payment['id']);
    $upd->execute();

    if ($upd->affected_rows === 0) {
        cf_log("UPDATE hit 0 rows — race condition or already updated");
        exit;
    }

    cf_log("✅ Payment completed for user #{$payment['user_id']} receipt=$mpesa_receipt");

    // ── Distribute chat referral commissions ─────────────────────
    try {
        distributeChatCommissions($conn, $payment['user_id'], $amt);
    } catch (Exception $e) {
        cf_log("Commission error (non-critical): " . $e->getMessage());
    }

    // ── Send confirmation email ───────────────────────────────────
    try {
        require_once '../includes/email.php';
        if (function_exists('sendEmail')) {
            $uS = $conn->prepare("SELECT username,email FROM users WHERE id=? LIMIT 1");
            $uS->bind_param("i", $payment['user_id']); $uS->execute();
            $user = $uS->get_result()->fetch_assoc();
            if ($user && !empty($user['email'])) {
                $site = getSetting('site_name', 'Earnovix');
                $html = "<p>Hi <strong>" . htmlspecialchars($user['username']) . "</strong>,</p>
                         <p>Your <strong>Chat Foreigners</strong> access has been unlocked!</p>
                         <p>You can now chat with verified international users and earn rewards.</p>
                         <p>Access is valid for <strong>30 days</strong> from today.</p>
                         <p>M-PESA Receipt: <strong>{$mpesa_receipt}</strong></p>";
                sendEmail($user['email'], $user['username'], "{$site}: Chat Foreigners Unlocked!", $html);
                cf_log("Email sent to {$user['email']}");
            }
        }
    } catch (Exception $e) {
        cf_log("Email error (non-critical): " . $e->getMessage());
    }

} else {
    // Failed/cancelled
    $fail = $conn->prepare("UPDATE chat_foreigners_payments
        SET status='failed' WHERE id=? AND status='pending'");
    $fail->bind_param("i", $payment['id']); $fail->execute();
    cf_log("❌ Payment failed/cancelled — event=$event");
}

cf_log("===== END CALLBACK =====
");

// ════════════════════════════════════════════════════════════════════
// distributeChatCommissions()
// Walks referred_by chain and credits each upline's chat_wallet
// based on settings: cf_commission_l1, cf_commission_l2, cf_commission_l3
// ════════════════════════════════════════════════════════════════════
function distributeChatCommissions($conn, $userId, $paidAmount) {
    global $log_file;

    // Get upline commission settings (fixed KES amounts or % — stored as fixed here)
    $levels = [
        1 => floatval(getSetting('cf_commission_l1', '0')),
        2 => floatval(getSetting('cf_commission_l2', '0')),
        3 => floatval(getSetting('cf_commission_l3', '0')),
    ];

    // Skip if no commissions configured
    if (array_sum($levels) <= 0) {
        file_put_contents($log_file, '[' . date('Y-m-d H:i:s') . '] No CF commissions configured — skipping' . "
", FILE_APPEND);
        return;
    }

    // Get the payer's referrer chain
    $currentUserId = $userId;
    $level = 1;

    while ($level <= 3) {
        // Get this user's referrer
        $rStmt = $conn->prepare("SELECT id, username, referred_by FROM users WHERE id=? LIMIT 1");
        $rStmt->bind_param("i", $currentUserId); $rStmt->execute();
        $user = $rStmt->get_result()->fetch_assoc();

        if (!$user || empty($user['referred_by'])) {
            file_put_contents($log_file, '[' . date('Y-m-d H:i:s') . "] L{$level}: No more referrers — stopping
", FILE_APPEND);
            break;
        }

        $referrerId = intval($user['referred_by']);
        $commission = $levels[$level] ?? 0;

        if ($commission <= 0) {
            file_put_contents($log_file, '[' . date('Y-m-d H:i:s') . "] L{$level}: Zero commission — skipping level
", FILE_APPEND);
            $currentUserId = $referrerId;
            $level++;
            continue;
        }

        // Check idempotency — don't double-pay for same payer+level
        $dupChk = $conn->prepare("SELECT id FROM transactions WHERE reference=? AND user_id=? LIMIT 1");
        $dupRef = "CF_COMM_L{$level}_{$userId}";
        $dupChk->bind_param("si", $dupRef, $referrerId); $dupChk->execute();
        if ($dupChk->get_result()->num_rows > 0) {
            file_put_contents($log_file, '[' . date('Y-m-d H:i:s') . "] L{$level}: Already paid referrer #{$referrerId} — skip
", FILE_APPEND);
            $currentUserId = $referrerId;
            $level++;
            continue;
        }

        // Credit the referrer's chat_wallet
        ensureWalletExists($conn, $referrerId);
        $upd = $conn->prepare("UPDATE wallets SET
            chat_wallet = COALESCE(chat_wallet,0) + ?,
            balance     = COALESCE(balance,0)     + ?,
            updated_at  = NOW()
            WHERE user_id=?");
        $upd->bind_param("ddi", $commission, $commission, $referrerId); $upd->execute();

        // Log transaction
        $desc = "Chat Foreigners L{$level} commission from user #{$userId} payment (Ksh {$paidAmount})";
        $tStmt = $conn->prepare("INSERT INTO transactions
            (user_id, wallet_type, type, amount, description, reference, status)
            VALUES (?, 'chat', 'credit', ?, ?, ?, 'completed')");
        $tStmt->bind_param("idss", $referrerId, $commission, $desc, $dupRef); $tStmt->execute();

        // Get referrer username for log
        $rNameStmt = $conn->prepare("SELECT username FROM users WHERE id=? LIMIT 1");
        $rNameStmt->bind_param("i", $referrerId); $rNameStmt->execute();
        $rName = $rNameStmt->get_result()->fetch_assoc()['username'] ?? "#{$referrerId}";

        file_put_contents($log_file, '[' . date('Y-m-d H:i:s') . "] ✅ L{$level}: Ksh {$commission} → {$rName} (#{$referrerId}) chat_wallet
", FILE_APPEND);

        $currentUserId = $referrerId;
        $level++;
    }
}