<?php
/**
 * Notifications — email.php
 * Handles BOTH Email (PHPMailer via SMTP) and SMS (TextSMS API)
 *
 * ═══════════════════════════════════════════════════════════════════════
 * PHPMAILER INSTALLATION
 * ═══════════════════════════════════════════════════════════════════════
 *  curl -sS https://getcomposer.org/installer | php
 *  sudo mv composer.phar /usr/local/bin/composer
 *  cd /var/www/html
 *  composer require phpmailer/phpmailer
 *
 * SMTP SETTINGS  (Admin → Settings → Email tab)
 *   smtp_host, smtp_port, smtp_user, smtp_pass,
 *   smtp_from, smtp_from_name, smtp_secure, email_notifications
 * ═══════════════════════════════════════════════════════════════════════
 */

define('VENDOR_AUTOLOAD', __DIR__ . '/../vendor/autoload.php');

// ────────────────────────────────────────────────────────────────────────────
// INTERNAL HELPER — write a timestamped line to the email debug log
// ────────────────────────────────────────────────────────────────────────────
function _emailLog($msg) {
    $logFile = __DIR__ . '/../mpesa/email_debug.log';
    $dir     = dirname($logFile);
    if (!is_dir($dir)) @mkdir($dir, 0755, true);
    @file_put_contents($logFile, '[' . date('Y-m-d H:i:s') . '] ' . $msg . "\n", FILE_APPEND);
    error_log('EMAIL: ' . $msg);
}

// ────────────────────────────────────────────────────────────────────────────
// INTERNAL HELPER — safely fetch a user's email from the DB
// (getUserData() in functions.php uses SELECT u.* which includes email,
//  but falls back to a direct query here as a safety net)
// ────────────────────────────────────────────────────────────────────────────
function _getUserEmail($userId) {
    $conn = getConnection();
    $stmt = $conn->prepare("SELECT email FROM users WHERE id = ? LIMIT 1");
    $stmt->bind_param("i", $userId);
    $stmt->execute();
    $row = $stmt->get_result()->fetch_assoc();
    return $row['email'] ?? '';
}

// ════════════════════════════════════════════════════════════════════════════
// CORE: SEND EMAIL via PHPMailer
// ════════════════════════════════════════════════════════════════════════════
function sendEmail($toEmail, $toName, $subject, $htmlBody, $textBody = null) {

    _emailLog("sendEmail() called → to={$toEmail} subject={$subject}");

    if (getSetting('email_notifications', '1') !== '1') {
        _emailLog("SKIPPED — email_notifications is OFF");
        return ['success' => true, 'error' => null];
    }

    if (!file_exists(VENDOR_AUTOLOAD)) {
        _emailLog("FAILED — PHPMailer not found at " . VENDOR_AUTOLOAD);
        return ['success' => false, 'error' => 'PHPMailer not installed. Run: composer require phpmailer/phpmailer'];
    }

    require_once VENDOR_AUTOLOAD;

    $host     = getSetting('smtp_host',      '');
    $port     = intval(getSetting('smtp_port', '587'));
    $user     = getSetting('smtp_user',      '');
    $pass     = getSetting('smtp_pass',      '');
    $from     = getSetting('smtp_from',      $user);
    $fromName = getSetting('smtp_from_name', getSetting('site_name', 'Notifications'));
    $secure   = strtolower(getSetting('smtp_secure', 'tls'));

    if (empty($host) || empty($user) || empty($pass)) {
        _emailLog("FAILED — SMTP credentials missing (host={$host} user={$user} pass=" . (empty($pass)?'EMPTY':'SET') . ")");
        return ['success' => false, 'error' => 'SMTP credentials not configured in Admin → Settings → Email'];
    }

    $mail = new \PHPMailer\PHPMailer\PHPMailer(true);
    try {
        $mail->isSMTP();
        $mail->Host       = $host;
        $mail->SMTPAuth   = true;
        $mail->Username   = $user;
        $mail->Password   = $pass;
        $mail->SMTPSecure = $secure === 'ssl'
            ? \PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS
            : \PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port       = $port;
        $mail->Timeout    = 15;

        $mail->setFrom($from, $fromName);
        $mail->addAddress($toEmail, $toName);
        $mail->addReplyTo($from, $fromName);

        $mail->isHTML(true);
        $mail->CharSet = 'UTF-8';
        $mail->Subject = $subject;
        $mail->Body    = $htmlBody;
        $mail->AltBody = $textBody ?? strip_tags(str_replace(
            ['<br>', '<br/>', '<br />', '</p>', '</div>'], "\n", $htmlBody
        ));

        $mail->send();
        _emailLog("SENT OK → to={$toEmail}");
        return ['success' => true, 'error' => null];

    } catch (\PHPMailer\PHPMailer\Exception $e) {
        _emailLog("FAILED → to={$toEmail} error=" . $mail->ErrorInfo);
        return ['success' => false, 'error' => $mail->ErrorInfo];
    }
}


// ════════════════════════════════════════════════════════════════════════════
// EMAIL TEMPLATE BUILDER
// ════════════════════════════════════════════════════════════════════════════
function buildEmailTemplate($title, $content, $btnText = '', $btnUrl = '') {
    $siteName   = getSetting('site_name',   'Notifications');
    $themeColor = getSetting('theme_color', '#6366f1');
    $year       = date('Y');
    $siteUrl    = defined('SITE_URL') ? SITE_URL : 'https://' . ($_SERVER['HTTP_HOST'] ?? 'localhost');

    $btn = '';
    if ($btnText && $btnUrl) {
        $btn = "
        <div style='text-align:center;margin:24px 0 8px'>
          <a href='{$btnUrl}'
             style='display:inline-block;background:{$themeColor};color:#ffffff;
                    text-decoration:none;padding:12px 28px;border-radius:8px;
                    font-weight:700;font-size:14px;letter-spacing:.3px'>
            {$btnText}
          </a>
        </div>";
    }

    return "<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width,initial-scale=1'>
  <title>{$siteName}</title>
</head>
<body style='margin:0;padding:0;background:#f4f6fb;font-family:Arial,Helvetica,sans-serif'>
  <table width='100%' cellpadding='0' cellspacing='0' role='presentation'>
    <tr><td align='center' style='padding:32px 16px'>
      <table width='100%' style='max-width:560px' cellpadding='0' cellspacing='0'>
        <tr>
          <td style='background:{$themeColor};border-radius:12px 12px 0 0;padding:22px 28px;text-align:center'>
            <span style='color:#ffffff;font-size:20px;font-weight:800;letter-spacing:-.4px'>{$siteName}</span>
          </td>
        </tr>
        <tr>
          <td style='background:#ffffff;padding:28px 28px 24px;border-left:1px solid #e5e7eb;border-right:1px solid #e5e7eb'>
            <h2 style='margin:0 0 16px;font-size:18px;font-weight:800;color:#111827;letter-spacing:-.3px'>{$title}</h2>
            <div style='font-size:14px;color:#374151;line-height:1.7'>{$content}</div>
            {$btn}
          </td>
        </tr>
        <tr>
          <td style='background:#f9fafb;border:1px solid #e5e7eb;border-top:none;border-radius:0 0 12px 12px;padding:16px 28px;text-align:center'>
            <p style='margin:0;font-size:11px;color:#9ca3af'>
              &copy; {$year} {$siteName}. This email was sent automatically — please do not reply.<br>
              <a href='{$siteUrl}' style='color:{$themeColor};text-decoration:none'>{$siteUrl}</a>
            </p>
          </td>
        </tr>
      </table>
    </td></tr>
  </table>
</body>
</html>";
}


// ════════════════════════════════════════════════════════════════════════════
// WELCOME EMAIL
// ════════════════════════════════════════════════════════════════════════════
function sendWelcomeEmail($userId) {
    _emailLog("sendWelcomeEmail() userId={$userId}");
    try {
        // ── FIX: use direct query so we never miss email field ──
        $email    = _getUserEmail($userId);
        $userData = getUserData($userId);

        if (!$userData) {
            _emailLog("sendWelcomeEmail: getUserData() returned null for userId={$userId}");
            sendWelcomeSms($userId);
            return false;
        }

        // ── FIX: prefer direct email fetch, fall back to userData ──
        $toEmail = !empty($email) ? $email : ($userData['email'] ?? '');

        if (empty($toEmail)) {
            _emailLog("sendWelcomeEmail: no email for userId={$userId} — SMS only");
            sendWelcomeSms($userId);
            return false;
        }

        $siteName = getSetting('site_name', 'QuickTasks');
        $siteUrl  = defined('SITE_URL') ? SITE_URL : 'https://' . $_SERVER['HTTP_HOST'];
        $username = htmlspecialchars($userData['username'] ?? 'there');
        $refCode  = htmlspecialchars($userData['referral_code'] ?? '');

        $content = "
          <p>Hi <strong>{$username}</strong>,</p>
          <p>Welcome to <strong>{$siteName}</strong>! Your account is ready.</p>
          " . ($refCode ? "<p>Your referral code: <strong style='font-size:18px;color:#6366f1;letter-spacing:2px'>{$refCode}</strong></p>
          <p>Share it with friends to earn commissions every time they join and activate.</p>" : "") . "
        ";

        $html   = buildEmailTemplate("Welcome to {$siteName}!", $content, 'Go to Dashboard', $siteUrl . '/user/dashboard.php');
        $result = sendEmail($toEmail, $username, "Welcome to {$siteName}!", $html);
        sendWelcomeSms($userId);
        return $result['success'];

    } catch (Exception $e) {
        _emailLog("sendWelcomeEmail EXCEPTION: " . $e->getMessage());
        return false;
    }
}


// ════════════════════════════════════════════════════════════════════════════
// ACTIVATION SUCCESS EMAIL
// ════════════════════════════════════════════════════════════════════════════
function sendActivationSuccessEmail($userId) {
    _emailLog("sendActivationSuccessEmail() userId={$userId}");
    try {
        $email    = _getUserEmail($userId);
        $userData = getUserData($userId);

        if (!$userData) {
            _emailLog("sendActivationSuccessEmail: getUserData() null userId={$userId}");
            sendActivationSuccessSms($userId);
            return false;
        }

        $toEmail = !empty($email) ? $email : ($userData['email'] ?? '');

        if (empty($toEmail)) {
            _emailLog("sendActivationSuccessEmail: no email userId={$userId}");
            sendActivationSuccessSms($userId);
            return false;
        }

        $siteName = getSetting('site_name', 'QuickTasks');
        $siteUrl  = defined('SITE_URL') ? SITE_URL : 'https://' . $_SERVER['HTTP_HOST'];
        $username = htmlspecialchars($userData['username'] ?? 'there');

        $content = "
          <p>Hi <strong>{$username}</strong>,</p>
          <p>🎉 Your <strong>{$siteName}</strong> account is now <strong style='color:#10b981'>ACTIVE</strong>!</p>
          <p>You can now complete tasks, refer friends, and withdraw your earnings.</p>";

        $html   = buildEmailTemplate('Account Activated!', $content, 'Start Earning', $siteUrl . '/user/dashboard.php');
        $result = sendEmail($toEmail, $username, "Your {$siteName} account is active!", $html);
        sendActivationSuccessSms($userId);
        return $result['success'];

    } catch (Exception $e) {
        _emailLog("sendActivationSuccessEmail EXCEPTION: " . $e->getMessage());
        return false;
    }
}


// ════════════════════════════════════════════════════════════════════════════
// WITHDRAWAL REQUESTED EMAIL
// ════════════════════════════════════════════════════════════════════════════
function sendWithdrawalRequestedEmail($email, $username, $withdrawalId, $amount, $fee, $netAmount, $phoneNumber, $walletType, $currencySymbol = 'KSH') {
    _emailLog("sendWithdrawalRequestedEmail() WD#{$withdrawalId} to={$email}");
    try {
        if (empty($email)) {
            _emailLog("sendWithdrawalRequestedEmail: email empty for WD#{$withdrawalId}");
        }

        $siteName = getSetting('site_name', 'QuickTasks');
        $amtF     = $currencySymbol . ' ' . number_format(floatval($amount),    2);
        $feeF     = $currencySymbol . ' ' . number_format(floatval($fee),       2);
        $netF     = $currencySymbol . ' ' . number_format(floatval($netAmount), 2);
        $uname    = htmlspecialchars($username);
        $wtype    = htmlspecialchars(ucwords(str_replace('_', ' ', $walletType)));

        $content = "
          <p>Hi <strong>{$uname}</strong>,</p>
          <p>Your withdrawal request has been received and is being processed.</p>
          <table width='100%' cellpadding='8' cellspacing='0'
                 style='border-collapse:collapse;font-size:13px;margin:16px 0'>
            <tr style='background:#f9fafb'>
              <td style='border:1px solid #e5e7eb;font-weight:600;color:#6b7280'>Reference</td>
              <td style='border:1px solid #e5e7eb;color:#111827'>WD-{$withdrawalId}</td>
            </tr>
            <tr>
              <td style='border:1px solid #e5e7eb;font-weight:600;color:#6b7280'>Wallet</td>
              <td style='border:1px solid #e5e7eb;color:#111827'>{$wtype}</td>
            </tr>
            <tr style='background:#f9fafb'>
              <td style='border:1px solid #e5e7eb;font-weight:600;color:#6b7280'>Amount</td>
              <td style='border:1px solid #e5e7eb;color:#111827'>{$amtF}</td>
            </tr>
            <tr>
              <td style='border:1px solid #e5e7eb;font-weight:600;color:#6b7280'>Fee</td>
              <td style='border:1px solid #e5e7eb;color:#ef4444'>{$feeF}</td>
            </tr>
            <tr style='background:#f0fdf4'>
              <td style='border:1px solid #e5e7eb;font-weight:700;color:#111827'>You Receive</td>
              <td style='border:1px solid #e5e7eb;font-weight:800;color:#10b981;font-size:15px'>{$netF}</td>
            </tr>
            <tr>
              <td style='border:1px solid #e5e7eb;font-weight:600;color:#6b7280'>M-Pesa</td>
              <td style='border:1px solid #e5e7eb;color:#111827'>{$phoneNumber}</td>
            </tr>
          </table>
          <p style='color:#6b7280;font-size:12px'>Funds will be sent to your M-Pesa number shortly.</p>";

        $sent = false;
        if (!empty($email)) {
            $html   = buildEmailTemplate('Withdrawal Request Received', $content);
            $result = sendEmail($email, $username, "Withdrawal #{$withdrawalId} received — {$netF}", $html);
            $sent   = $result['success'];
        }

        // Also SMS
        $conn = getConnection();
        $stmt = $conn->prepare("SELECT phone FROM users WHERE email=? LIMIT 1");
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $row = $stmt->get_result()->fetch_assoc();
        if (!empty($row['phone'])) {
            sendWithdrawalRequestedSms($row['phone'], $username, $withdrawalId, $amount, $fee, $netAmount, $phoneNumber, $walletType, $currencySymbol);
        }
        return $sent;

    } catch (Exception $e) {
        _emailLog("sendWithdrawalRequestedEmail EXCEPTION: " . $e->getMessage());
        return false;
    }
}


// ════════════════════════════════════════════════════════════════════════════
// WITHDRAWAL APPROVED EMAIL
// ════════════════════════════════════════════════════════════════════════════
function sendWithdrawalApprovedEmail($withdrawalId) {
    _emailLog("sendWithdrawalApprovedEmail() WD#{$withdrawalId}");
    try {
        $conn = getConnection();
        $stmt = $conn->prepare("
            SELECT w.*, u.username, u.email, u.phone, c.currency_symbol
            FROM withdrawals w
            JOIN users u ON w.user_id = u.id
            LEFT JOIN countries c ON u.country = c.name
            WHERE w.id = ?");
        $stmt->bind_param("i", $withdrawalId);
        $stmt->execute();
        $data = $stmt->get_result()->fetch_assoc();

        if (!$data) {
            _emailLog("sendWithdrawalApprovedEmail: WD#{$withdrawalId} not found");
            return false;
        }

        _emailLog("sendWithdrawalApprovedEmail: found WD#{$withdrawalId} email=" . ($data['email'] ?? 'EMPTY'));

        $cSym  = $data['currency_symbol'] ?? 'KSH';
        $netF  = $cSym . ' ' . number_format(floatval($data['net_amount'] ?? 0), 2);
        $uname = htmlspecialchars($data['username']);

        if (!empty($data['email'])) {
            $content = "
              <p>Hi <strong>{$uname}</strong>,</p>
              <p>Great news! Your withdrawal has been <strong style='color:#10b981'>APPROVED</strong> and sent.</p>
              <p style='font-size:22px;font-weight:900;color:#10b981;text-align:center;margin:20px 0'>{$netF}</p>
              <p>Sent to M-Pesa: <strong>{$data['phone_number']}</strong><br>
                 Please allow 1–5 minutes for the funds to arrive.</p>";
            $html = buildEmailTemplate('Withdrawal Approved ✅', $content, 'View History', (defined('SITE_URL') ? SITE_URL : '') . '/user/withdrawal_history.php');
            sendEmail($data['email'], $uname, "Withdrawal approved — {$netF} sent to M-Pesa", $html);
        } else {
            _emailLog("sendWithdrawalApprovedEmail: no email on record for WD#{$withdrawalId} userId={$data['user_id']}");
        }
        sendWithdrawalApprovedSms($withdrawalId);
        return true;

    } catch (Exception $e) {
        _emailLog("sendWithdrawalApprovedEmail EXCEPTION: " . $e->getMessage());
        return false;
    }
}


// ════════════════════════════════════════════════════════════════════════════
// WITHDRAWAL REJECTED EMAIL
// ════════════════════════════════════════════════════════════════════════════
function sendWithdrawalRejectedEmail($withdrawalId) {
    _emailLog("sendWithdrawalRejectedEmail() WD#{$withdrawalId}");
    try {
        $conn = getConnection();
        $stmt = $conn->prepare("
            SELECT w.*, u.username, u.email, u.phone, c.currency_symbol
            FROM withdrawals w
            JOIN users u ON w.user_id = u.id
            LEFT JOIN countries c ON u.country = c.name
            WHERE w.id = ?");
        $stmt->bind_param("i", $withdrawalId);
        $stmt->execute();
        $data = $stmt->get_result()->fetch_assoc();

        if (!$data) {
            _emailLog("sendWithdrawalRejectedEmail: WD#{$withdrawalId} not found");
            return false;
        }

        $cSym  = $data['currency_symbol'] ?? 'KSH';
        $amtF  = $cSym . ' ' . number_format(floatval($data['amount'] ?? 0), 2);
        $wtype = htmlspecialchars(ucwords(str_replace('_', ' ', $data['wallet_type'] ?? '')));
        $uname = htmlspecialchars($data['username']);

        if (!empty($data['email'])) {
            $content = "
              <p>Hi <strong>{$uname}</strong>,</p>
              <p>Your withdrawal request #{$data['id']} was <strong style='color:#ef4444'>not approved</strong> at this time.</p>
              <p><strong>{$amtF}</strong> has been refunded back to your <strong>{$wtype}</strong>.</p>
              <p style='color:#6b7280;font-size:12px'>If you believe this is an error, please contact support.</p>";
            $html = buildEmailTemplate('Withdrawal Rejected', $content);
            sendEmail($data['email'], $uname, "Withdrawal #{$data['id']} rejected — funds refunded", $html);
        } else {
            _emailLog("sendWithdrawalRejectedEmail: no email for WD#{$withdrawalId}");
        }
        sendWithdrawalRejectedSms($withdrawalId);
        return true;

    } catch (Exception $e) {
        _emailLog("sendWithdrawalRejectedEmail EXCEPTION: " . $e->getMessage());
        return false;
    }
}


// ════════════════════════════════════════════════════════════════════════════
// PRODUCT PURCHASE EMAIL
// ════════════════════════════════════════════════════════════════════════════
function sendProductPurchaseEmail($buyerId, $productTitle, $downloadToken, $amountPaid = 0, $currencySymbol = 'KSh') {
    _emailLog("sendProductPurchaseEmail() buyerId={$buyerId} product={$productTitle}");
    try {
        $conn  = getConnection();
        $stmt  = $conn->prepare("SELECT username, email, phone FROM users WHERE id=? LIMIT 1");
        $stmt->bind_param("i", $buyerId);
        $stmt->execute();
        $buyer = $stmt->get_result()->fetch_assoc();

        if (!$buyer) {
            _emailLog("sendProductPurchaseEmail: buyer #{$buyerId} not found");
            return false;
        }

        _emailLog("sendProductPurchaseEmail: buyer email=" . ($buyer['email'] ?? 'EMPTY'));

        $siteName = getSetting('site_name', 'QuickTasks');
        $siteUrl  = rtrim(defined('SITE_URL') ? SITE_URL : 'https://' . ($_SERVER['HTTP_HOST'] ?? 'localhost'), '/');
        $dlUrl    = $siteUrl . '/user/download.php?token=' . urlencode($downloadToken);
        $amtF     = $currencySymbol . ' ' . number_format(floatval($amountPaid), 2);
        $title    = htmlspecialchars($productTitle);
        $uname    = htmlspecialchars($buyer['username']);

        if (!empty($buyer['email'])) {
            $content = "
              <p>Hi <strong>{$uname}</strong>,</p>
              <p>Your purchase of <strong>\"{$title}\"</strong> is confirmed.</p>
              <p>Amount paid: <strong>{$amtF}</strong></p>
              <p>Click the button below to download your product:</p>";
            $html = buildEmailTemplate('Purchase Confirmed! 🎉', $content, 'Download Now', $dlUrl);
            sendEmail($buyer['email'], $uname, "Your purchase: {$title}", $html);
        } else {
            _emailLog("sendProductPurchaseEmail: no email for buyerId={$buyerId}");
        }
        sendProductPurchaseSms($buyerId, $productTitle, $downloadToken, $amountPaid, $currencySymbol);
        return true;

    } catch (Exception $e) {
        _emailLog("sendProductPurchaseEmail EXCEPTION: " . $e->getMessage());
        return false;
    }
}


// ════════════════════════════════════════════════════════════════════════════
// PRODUCT COMMISSION EMAIL
// ════════════════════════════════════════════════════════════════════════════
function sendProductCommissionEmail($recipientId, $buyerUsername, $productTitle, $commissionAmount, $level = 1, $currencySymbol = 'KSh') {
    _emailLog("sendProductCommissionEmail() recipientId={$recipientId} amount={$commissionAmount}");
    try {
        $conn = getConnection();
        $stmt = $conn->prepare("SELECT username, email, phone FROM users WHERE id=? LIMIT 1");
        $stmt->bind_param("i", $recipientId);
        $stmt->execute();
        $user = $stmt->get_result()->fetch_assoc();

        if (!$user) {
            _emailLog("sendProductCommissionEmail: recipient #{$recipientId} not found");
            return false;
        }

        _emailLog("sendProductCommissionEmail: recipient email=" . ($user['email'] ?? 'EMPTY'));

        $amtF  = $currencySymbol . ' ' . number_format(floatval($commissionAmount), 2);
        $title = htmlspecialchars($productTitle);
        $buyer = htmlspecialchars($buyerUsername);
        $uname = htmlspecialchars($user['username']);

        if (!empty($user['email'])) {
            $content = "
              <p>Hi <strong>{$uname}</strong>,</p>
              <p>You earned a <strong>Level {$level}</strong> store commission!</p>
              <p><strong>{$buyer}</strong> just purchased <strong>\"{$title}\"</strong>.</p>
              <p style='font-size:20px;font-weight:900;color:#10b981;text-align:center;margin:18px 0'>{$amtF} credited</p>
              <p>The amount has been added to your Main Wallet.</p>";
            $html = buildEmailTemplate("Commission Earned! 💰", $content, 'View Wallet', (defined('SITE_URL') ? SITE_URL : '') . '/user/dashboard.php');
            sendEmail($user['email'], $uname, "You earned {$amtF} commission from a store sale", $html);
        } else {
            _emailLog("sendProductCommissionEmail: no email for recipientId={$recipientId}");
        }
        sendProductCommissionSms($recipientId, $buyerUsername, $productTitle, $commissionAmount, $level, $currencySymbol);
        return true;

    } catch (Exception $e) {
        _emailLog("sendProductCommissionEmail EXCEPTION: " . $e->getMessage());
        return false;
    }
}



// ════════════════════════════════════════════════════════════════════════════
// REFERRAL / ACTIVATION BONUS EMAIL
// ════════════════════════════════════════════════════════════════════════════
function sendReferralBonusEmail($userId, $referredUsername, $level, $amount) {
    _emailLog("sendReferralBonusEmail() userId={$userId} level={$level} amount={$amount}");
    try {
        $email    = _getUserEmail($userId);
        $userData = getUserData($userId);

        if (!$userData) {
            _emailLog("sendReferralBonusEmail: getUserData() null for userId={$userId}");
            return false;
        }

        $toEmail = !empty($email) ? $email : ($userData['email'] ?? '');

        if (empty($toEmail)) {
            _emailLog("sendReferralBonusEmail: no email for userId={$userId} — SMS only");
            return false;
        }

        $siteName = getSetting('site_name', '');
        $siteUrl  = defined('SITE_URL') ? SITE_URL : 'https://' . ($_SERVER['HTTP_HOST'] ?? 'localhost');
        $username = htmlspecialchars($userData['username'] ?? 'there');
        $referred = htmlspecialchars($referredUsername);
        $cSym     = $userData['currency_symbol'] ?? 'KSh';
        $amtF     = $cSym . ' ' . number_format(floatval($amount), 2);

        $levelLabels = [1 => 'Direct activation bonus', 2 => 'Level 2 bonus', 3 => 'Level 3 bonus'];
        $levelLabel  = $levelLabels[$level] ?? "Level {$level} bonus";

        $content = "
          <p>Hi <strong>{$username}</strong>,</p>
          <p>You just earned a <strong>{$levelLabel}</strong>!</p>
          <p><strong>{$referred}</strong> has just activated their account.</p>
          <p style='font-size:22px;font-weight:900;color:#10b981;text-align:center;margin:20px 0'>{$amtF} credited</p>
          <p>This amount has been added to your <strong>Main Wallet</strong> and is available for withdrawal.</p>";

        $html   = buildEmailTemplate("Bonus Earned! 💰", $content, 'View Wallet', $siteUrl . '/user/dashboard.php');
        $result = sendEmail($toEmail, $username, "You earned {$amtF} — {$levelLabel}", $html);
        _emailLog("sendReferralBonusEmail: result=" . ($result['success'] ? 'OK' : 'FAILED: ' . ($result['error'] ?? '?')));
        return $result['success'];

    } catch (Exception $e) {
        _emailLog("sendReferralBonusEmail EXCEPTION: " . $e->getMessage());
        return false;
    }
}


// ════════════════════════════════════════════════════════════════════════════
// SMS FUNCTIONS — ALL UNCHANGED
// ════════════════════════════════════════════════════════════════════════════

function sendSms($mobile, $message) {
    if (getSetting('sms_notifications', '1') !== '1') {
        error_log("sendSms: notifications OFF — skipping SMS to {$mobile}");
        return ['success' => true, 'message_id' => null, 'error' => null];
    }
    $apiKey=$partnerID=$shortcode='';
    $apiKey    = getSetting('sms_api_key',    '');
    $partnerID = getSetting('sms_partner_id', '');
    $shortcode = getSetting('sms_shortcode',  '');
    if (empty($apiKey) || empty($partnerID) || empty($shortcode)) {
        error_log("sendSms: credentials incomplete");
        return ['success' => false, 'message_id' => null, 'error' => 'SMS credentials not configured'];
    }
    $mobile  = normalizeMobile($mobile);
    $payload = json_encode(['apikey'=>$apiKey,'partnerID'=>$partnerID,'message'=>$message,'shortcode'=>$shortcode,'mobile'=>$mobile]);
    $ch = curl_init('https://sms.textsms.co.ke/api/services/sendsms/');
    curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>true,CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>$payload,CURLOPT_TIMEOUT=>15,CURLOPT_HTTPHEADER=>['Content-Type: application/json','Accept: application/json']]);
    $response = curl_exec($ch); $httpCode = curl_getinfo($ch,CURLINFO_HTTP_CODE); $curlErr = curl_error($ch); curl_close($ch);
    if ($curlErr) { error_log("sendSms curl error [{$mobile}]: {$curlErr}"); return ['success'=>false,'message_id'=>null,'error'=>$curlErr]; }
    $decoded = json_decode($response, true);
    $resp = $decoded['responses'][0] ?? $decoded;
    $code = intval($resp['respose-code'] ?? $resp['response-code'] ?? 0);
    if ($code === 200) return ['success'=>true,'message_id'=>$resp['messageid']??null,'error'=>null];
    $errMsg = smsErrorMessage($code) . " (code {$code})";
    error_log("sendSms failed [{$mobile}]: {$errMsg}");
    return ['success'=>false,'message_id'=>null,'error'=>$errMsg];
}

function sendBulkSms($recipients) {
    $apiKey=getSetting('sms_api_key',''); $partnerID=getSetting('sms_partner_id',''); $shortcode=getSetting('sms_shortcode','');
    $smslist=[];
    foreach(array_slice($recipients,0,20) as $i=>$r){$smslist[]=['partnerID'=>$partnerID,'apikey'=>$apiKey,'pass_type'=>'plain','clientsmsid'=>$i+1,'mobile'=>normalizeMobile($r['mobile']),'message'=>$r['message'],'shortcode'=>$shortcode];}
    $payload=json_encode(['count'=>count($smslist),'smslist'=>$smslist]);
    $ch=curl_init('https://sms.textsms.co.ke/api/services/sendbulk/');
    curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>true,CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>$payload,CURLOPT_TIMEOUT=>20,CURLOPT_HTTPHEADER=>['Content-Type: application/json','Accept: application/json']]);
    $response=curl_exec($ch); curl_close($ch); return json_decode($response,true);
}

function getSmsBalance() {
    $apiKey=getSetting('sms_api_key',''); $partnerID=getSetting('sms_partner_id','');
    $ch=curl_init('https://sms.textsms.co.ke/api/services/getbalance/');
    curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>true,CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>json_encode(['apikey'=>$apiKey,'partnerID'=>$partnerID]),CURLOPT_TIMEOUT=>10,CURLOPT_HTTPHEADER=>['Content-Type: application/json']]);
    $response=curl_exec($ch); curl_close($ch); return json_decode($response,true);
}

function normalizeMobile($mobile) {
    $mobile=preg_replace('/\D/','',$mobile);
    if(strlen($mobile)===9)  $mobile='254'.$mobile;
    if(strlen($mobile)===10) $mobile='254'.substr($mobile,1);
    return $mobile;
}

function smsErrorMessage($code) {
    $codes=[200=>'Success',1001=>'Invalid sender ID / shortcode',1002=>'Network not allowed',1003=>'Invalid mobile number',1004=>'Low bulk credits',1005=>'System error',1006=>'Invalid credentials',1007=>'System error',1008=>'No delivery report',1009=>'Unsupported data type',1010=>'Unsupported request type',4090=>'Internal error',4091=>'No Partner ID set',4092=>'No API key provided',4093=>'Details not found'];
    return $codes[$code]??'Unknown error';
}

function sendWelcomeSms($userId) {
    try{$userData=getUserData($userId);if(!$userData||empty($userData['phone']))return false;$siteName=getSetting('site_name','QuickTasks');$siteUrl=defined('SITE_URL')?SITE_URL:'https://'.$_SERVER['HTTP_HOST'];$message="Welcome to {$siteName}! Your account is ready. Login: {$siteUrl}/login.php Refer friends & earn. Your ref code: {$userData['referral_code']}";$result=sendSms($userData['phone'],$message);return $result['success'];}catch(Exception $e){error_log("sendWelcomeSms: ".$e->getMessage());return false;}
}

function sendActivationSuccessSms($userId) {
    try{$userData=getUserData($userId);if(!$userData||empty($userData['phone']))return false;$siteName=getSetting('site_name','QuickTasks');$siteUrl=defined('SITE_URL')?SITE_URL:'https://'.$_SERVER['HTTP_HOST'];$message="Congrats {$userData['username']}! Your {$siteName} account is now ACTIVE. Start earning now: {$siteUrl}/user/dashboard.php";$result=sendSms($userData['phone'],$message);return $result['success'];}catch(Exception $e){error_log("sendActivationSuccessSms: ".$e->getMessage());return false;}
}

function sendReferralBonusNotification($userId, $referredUsername, $level, $amount) {
    // Send email first (also logs internally)
    sendReferralBonusEmail($userId, $referredUsername, $level, $amount);
    // Then SMS
    try{$userData=getUserData($userId);if(!$userData||empty($userData['phone']))return false;$siteName=getSetting('site_name','');$amt=number_format(floatval($amount),2);$message="{$siteName}: Level {$level} bonus! {$referredUsername} just activated. Ksh {$amt} credited to your wallet.";$result=sendSms($userData['phone'],$message);return $result['success'];}catch(Exception $e){error_log("sendReferralBonusNotification: ".$e->getMessage());return false;}
}

function sendWithdrawalRequestedSms($phone, $username, $withdrawalId, $amount, $fee, $netAmount, $phoneNumber, $walletType, $currencySymbol='KSH') {
    $siteName=getSetting('site_name','QuickTasks');$netF=number_format(floatval($netAmount),2);$message="{$siteName}: Hi {$username}, withdrawal #{$withdrawalId} received. {$currencySymbol} {$netF} will be sent to {$phoneNumber} after approval.";$result=sendSms($phone,$message);return $result['success'];
}

function sendWithdrawalNotificationAdmin($withdrawalId) {
    try{$conn=getConnection();$stmt=$conn->prepare("SELECT w.*,u.username,u.phone AS user_phone,c.currency_symbol FROM withdrawals w JOIN users u ON w.user_id=u.id LEFT JOIN countries c ON u.country=c.name WHERE w.id=?");$stmt->bind_param("i",$withdrawalId);$stmt->execute();$data=$stmt->get_result()->fetch_assoc();if(!$data)return false;$adminPhone=getSetting('admin_phone','');if(empty($adminPhone))return false;$siteName=getSetting('site_name','QuickTasks');$cSym=$data['currency_symbol']??'KSH';$netF=number_format(floatval($data['net_amount']??0),2);$pending=$conn->query("SELECT COUNT(*) as cnt FROM withdrawals WHERE status='pending'")->fetch_assoc()['cnt'];$message="{$siteName} ADMIN: NEW withdrawal #{$withdrawalId} from {$data['username']}. {$cSym} {$netF} to {$data['phone_number']}. Pending: {$pending}. Login to approve.";$result=sendSms($adminPhone,$message);return $result['success'];}catch(Exception $e){error_log("sendWithdrawalNotificationAdmin: ".$e->getMessage());return false;}
}

function sendWithdrawalApprovedSms($withdrawalId) {
    try{$conn=getConnection();$stmt=$conn->prepare("SELECT w.*,u.username,u.phone,c.currency_symbol FROM withdrawals w JOIN users u ON w.user_id=u.id LEFT JOIN countries c ON u.country=c.name WHERE w.id=?");$stmt->bind_param("i",$withdrawalId);$stmt->execute();$data=$stmt->get_result()->fetch_assoc();if(!$data||empty($data['phone']))return false;$siteName=getSetting('site_name','QuickTasks');$cSym=$data['currency_symbol']??'KSH';$netF=number_format(floatval($data['net_amount']??0),2);$message="{$siteName}: Withdrawal APPROVED! {$cSym} {$netF} sent to M-Pesa {$data['phone_number']}. Allow 1-5 mins to receive.";$result=sendSms($data['phone'],$message);return $result['success'];}catch(Exception $e){error_log("sendWithdrawalApprovedSms: ".$e->getMessage());return false;}
}

function sendWithdrawalRejectedSms($withdrawalId) {
    try{$conn=getConnection();$stmt=$conn->prepare("SELECT w.*,u.username,u.phone,c.currency_symbol FROM withdrawals w JOIN users u ON w.user_id=u.id LEFT JOIN countries c ON u.country=c.name WHERE w.id=?");$stmt->bind_param("i",$withdrawalId);$stmt->execute();$data=$stmt->get_result()->fetch_assoc();if(!$data||empty($data['phone']))return false;$siteName=getSetting('site_name','QuickTasks');$cSym=$data['currency_symbol']??'KSH';$amtF=number_format(floatval($data['amount']??0),2);$message="{$siteName}: Withdrawal #{$data['id']} was rejected. {$cSym} {$amtF} refunded to your ".ucfirst($data['wallet_type'])." wallet.";$result=sendSms($data['phone'],$message);return $result['success'];}catch(Exception $e){error_log("sendWithdrawalRejectedSms: ".$e->getMessage());return false;}
}

function sendProductPurchaseSms($buyerId, $productTitle, $downloadToken, $amountPaid=0, $currencySymbol='KSh') {
    try{$conn=getConnection();$stmt=$conn->prepare("SELECT username,phone FROM users WHERE id=? LIMIT 1");$stmt->bind_param("i",$buyerId);$stmt->execute();$buyer=$stmt->get_result()->fetch_assoc();if(!$buyer||empty($buyer['phone']))return false;$siteName=getSetting('site_name','QuickTasks');$siteUrl=rtrim(defined('SITE_URL')?SITE_URL:'https://'.($_SERVER['HTTP_HOST']??'localhost'),'/');$dlUrl=$siteUrl.'/user/download.php?token='.urlencode($downloadToken);$amtF=$currencySymbol.' '.number_format(floatval($amountPaid),2);$message="{$siteName}: Hi {$buyer['username']}! Purchase confirmed. Paid {$amtF} for \"{$productTitle}\". Download: {$dlUrl}";if(strlen($message)>306)$message="{$siteName}: Purchase confirmed! \"{$productTitle}\" {$amtF}. Download: {$dlUrl}";$result=sendSms($buyer['phone'],$message);return $result['success'];}catch(Exception $e){error_log("sendProductPurchaseSms: ".$e->getMessage());return false;}
}

function sendProductCommissionSms($recipientId, $buyerUsername, $productTitle, $commissionAmount, $level=1, $currencySymbol='KSh') {
    try{$conn=getConnection();$stmt=$conn->prepare("SELECT username,phone FROM users WHERE id=? LIMIT 1");$stmt->bind_param("i",$recipientId);$stmt->execute();$user=$stmt->get_result()->fetch_assoc();if(!$user||empty($user['phone']))return false;$siteName=getSetting('site_name','QuickTasks');$amtF=$currencySymbol.' '.number_format(floatval($commissionAmount),2);$message="{$siteName}: Level {$level} store commission! {$buyerUsername} bought \"{$productTitle}\". {$amtF} credited to your Main Wallet.";$result=sendSms($user['phone'],$message);return $result['success'];}catch(Exception $e){error_log("sendProductCommissionSms: ".$e->getMessage());return false;}
}


// ════════════════════════════════════════════════════════════════════════════
// COMPATIBILITY ALIASES
// ════════════════════════════════════════════════════════════════════════════

function sendWithdrawalEmails($withdrawalId, $userEmail, $username, $amount, $fee, $netAmount, $phoneNumber, $walletType, $currencySymbol='KSH') {
    return [
        'user_email' => sendWithdrawalRequestedEmail($userEmail, $username, $withdrawalId, $amount, $fee, $netAmount, $phoneNumber, $walletType, $currencySymbol),
        'admin_sms'  => sendWithdrawalNotificationAdmin($withdrawalId),
    ];
}