<?php
// mailer.php — shared email helpers.
// Included by api/place_order.php, admin/api.php (confirmation
// trigger), and admin/test_email.php (diagnostic endpoint).
//
// Uses PHP mail() via the cPanel MTA (Exim). For serious
// deliverability you'd swap in PHPMailer+SMTP, but mail() is
// fine for a single-branch operation and requires zero setup.

require_once __DIR__ . '/config.php';

/**
 * Build and send the "new confirmed order" HTML email.
 * Returns a status array so callers can surface errors.
 *
 * @return array{sent:bool, skipped?:string, error?:string, to?:string}
 */
function send_order_email(string $orderNumber, string $name, string $phone,
                          string $notes, string $language, array $items,
                          float $total, string $currency): array
{
    $pdo = db();
    $s = $pdo->query("SELECT key_name, value FROM settings WHERE key_name IN
        ('order_email_enabled', 'order_email_to', 'order_email_from',
         'restaurant_name')")->fetchAll(PDO::FETCH_KEY_PAIR);

    if (($s['order_email_enabled'] ?? '0') !== '1') {
        return ['sent' => false, 'skipped' => 'Email notifications disabled in settings'];
    }
    $to = trim($s['order_email_to'] ?? '');
    if ($to === '') {
        return ['sent' => false, 'skipped' => 'No recipient configured'];
    }

    $restName = $s['restaurant_name'] ?? 'Restaurant';
    $subject = "[$restName] New Order $orderNumber - $name";

    // Look up payment info for this order by order_number. We
    // could thread it through as another parameter, but every
    // caller of send_order_email already has the DB record handy
    // — pulling it here keeps the public signature stable and
    // ensures the email reflects the current DB truth (e.g. an
    // order paid online has 'paid' status by the time the email
    // fires from the callback).
    $payRow = $pdo->prepare('SELECT payment_method, payment_status FROM orders WHERE order_number = ?');
    $payRow->execute([$orderNumber]);
    $payRow = $payRow->fetch();
    $paymentMethod = $payRow['payment_method'] ?? '';
    $paymentStatus = $payRow['payment_status'] ?? 'not_required';

    $html = build_order_email_html($orderNumber, $name, $phone, $notes,
                                   $items, $total, $currency, $restName,
                                   $paymentMethod, $paymentStatus);

    return mail_html($to, $subject, $html, $s['order_email_from'] ?? '', $restName);
}

/**
 * Send the "abandonment report" digest email.
 * Lists orders that sat as pending_whatsapp and were later
 * voided (or are still pending at report time).
 */
function send_abandonment_report(array $orders): array
{
    $pdo = db();
    $s = $pdo->query("SELECT key_name, value FROM settings WHERE key_name IN
        ('abandonment_report_to', 'order_email_from', 'restaurant_name')")
        ->fetchAll(PDO::FETCH_KEY_PAIR);

    $to = trim($s['abandonment_report_to'] ?? '');
    if ($to === '') return ['sent' => false, 'skipped' => 'No report recipient configured'];
    if (empty($orders)) return ['sent' => false, 'skipped' => 'No abandoned orders to report'];

    $restName = $s['restaurant_name'] ?? 'Restaurant';
    $rows = '';
    $totalAbandoned = 0;
    foreach ($orders as $o) {
        $rows .= '<tr>';
        $rows .= '<td style="padding:8px;border-bottom:1px solid #eee">' .
                 htmlspecialchars($o['order_number'], ENT_QUOTES, 'UTF-8') . '</td>';
        $rows .= '<td style="padding:8px;border-bottom:1px solid #eee">' .
                 htmlspecialchars($o['customer_name'], ENT_QUOTES, 'UTF-8') . '</td>';
        $rows .= '<td style="padding:8px;border-bottom:1px solid #eee">' .
                 htmlspecialchars($o['customer_phone'], ENT_QUOTES, 'UTF-8') . '</td>';
        $rows .= '<td style="padding:8px;border-bottom:1px solid #eee;text-align:right">' .
                 number_format($o['total'], 3) . ' ' . htmlspecialchars($o['currency'], ENT_QUOTES, 'UTF-8') . '</td>';
        $rows .= '<td style="padding:8px;border-bottom:1px solid #eee;font-size:11px;color:#888">' .
                 htmlspecialchars($o['created_at'], ENT_QUOTES, 'UTF-8') . '</td>';
        $rows .= '</tr>';
        $totalAbandoned += floatval($o['total']);
    }

    $subject = "[$restName] Abandoned orders report - " . count($orders) . ' orders';
    $html = "<!doctype html><html><head><meta charset='utf-8'></head>
    <body style='font-family:Arial,sans-serif;color:#222;max-width:700px;margin:0 auto;padding:20px'>
      <h2 style='color:#d97706'>Abandoned Orders Report</h2>
      <p>These customers filled out the order form but never confirmed on WhatsApp,
         or the order was voided by staff.</p>
      <p style='color:#888;font-size:13px'>Total abandoned value: " . number_format($totalAbandoned, 3) . " — " .
        count($orders) . " order" . (count($orders) === 1 ? '' : 's') . "</p>
      <table style='width:100%;border-collapse:collapse;margin-top:20px;font-size:13px'>
        <thead>
          <tr style='background:#fef3c7'>
            <th style='padding:10px;text-align:left'>Order #</th>
            <th style='padding:10px;text-align:left'>Customer</th>
            <th style='padding:10px;text-align:left'>Phone</th>
            <th style='padding:10px;text-align:right'>Amount</th>
            <th style='padding:10px;text-align:left'>Placed at</th>
          </tr>
        </thead>
        <tbody>$rows</tbody>
      </table>
      <p style='margin-top:24px;padding-top:16px;border-top:1px solid #eee;font-size:12px;color:#888'>
        This is an automated report from $restName.
      </p>
    </body></html>";

    return mail_html($to, $subject, $html, $s['order_email_from'] ?? '', $restName);
}

/**
 * Low-level HTML mail sender — used by both confirmation and report emails.
 * Returns {sent, error, to} so the caller can display real feedback.
 */
function mail_html(string $to, string $subject, string $html,
                   string $fromOverride = '', string $fromName = 'Grove'): array
{
    // Pick the From address. If admin set one, use it as-is.
    // Otherwise fall back to noreply@ at the site's PARENT domain,
    // because that's usually where real mailboxes live — a
    // subdomain like qrmenu.latartekw.com typically doesn't have
    // its own mail server, so noreply@qrmenu.latartekw.com would
    // be rejected as an unrecognized sender. Stripping one DNS
    // label from the left gives us the parent (latartekw.com).
    //
    // Edge case: if the host has only two labels already (e.g.
    // "example.com"), we don't strip — that IS the parent.
    $from = trim($fromOverride);
    if ($from === '') {
        $host = parse_url(SITE_URL, PHP_URL_HOST) ?: 'localhost';
        $labels = explode('.', $host);
        // If host has 3+ labels (subdomain.tld.suffix), drop the leftmost
        if (count($labels) > 2) {
            $host = implode('.', array_slice($labels, 1));
        }
        $from = 'noreply@' . $host;
    }

    // UTF-8 encode the subject so special characters (é, Arabic, etc.)
    // don't get mangled in email clients. =?UTF-8?B?…?= is the standard
    // MIME encoded-word syntax.
    $subjectEnc = '=?UTF-8?B?' . base64_encode($subject) . '?=';

    // Build the From header.
    //
    // Edge case: if $fromName is empty (e.g. restaurant_name setting
    // wasn't configured yet), we MUST NOT produce "=?UTF-8?B??=" —
    // that's an empty encoded-word, which Exim/sendmail considers
    // malformed and silently rejects. Instead, fall back to a bare
    // address with no display name.
    //
    // Further: if the name is plain ASCII, we skip the encoded-word
    // syntax entirely — it's visually ugly in mail clients that
    // don't render it, and unnecessary for ASCII. Only reach for
    // base64 when the name contains non-ASCII bytes.
    $fromName = trim($fromName);
    if ($fromName === '') {
        $fromHeader = 'From: ' . $from;
    } elseif (preg_match('/[^\x20-\x7E]/', $fromName)) {
        // Contains non-ASCII → encode as UTF-8 base64
        $fromHeader = 'From: =?UTF-8?B?' . base64_encode($fromName) . '?= <' . $from . '>';
    } else {
        // Plain ASCII — use it directly, but quote if it contains
        // characters that have meaning in address headers (commas,
        // colons, etc.) to be safe.
        $safe = preg_match('/[,;:<>@"]/', $fromName)
              ? '"' . addcslashes($fromName, '"\\') . '"'
              : $fromName;
        $fromHeader = 'From: ' . $safe . ' <' . $from . '>';
    }

    // Build the final header block.
    $headers = [
        'MIME-Version: 1.0',
        'Content-Type: text/html; charset=UTF-8',
        $fromHeader,
        'Reply-To: ' . $from,
        'X-Mailer: Grove QR Menu',
    ];

    // ──────────────────────────────────────────────────────────
    // We deliberately bypass PHP's mail() function and pipe the
    // message directly to /usr/sbin/sendmail via proc_open. Why:
    //
    //   1. PHP's mail() has a pre-flight validation layer that
    //      returns FALSE silently on some cPanel/PHP combos
    //      even when the underlying MTA would accept the message.
    //      We hit this on PHP 8.3.30 with CloudLinux's sendmail
    //      wrapper — mail() returns FALSE and error_get_last()
    //      returns NULL, so we have zero diagnostic info.
    //
    //   2. proc_open gives us sendmail's stderr, which contains
    //      the REAL rejection reason if one happens. mail()
    //      swallows stderr and returns only a boolean.
    //
    //   3. sendmail's exit code 0 means "accepted for delivery"
    //      — the message is in the MTA's outbound queue.
    //
    // The -t flag tells sendmail to read To: from the headers
    // (which we include below); -i prevents single-dot lines in
    // the body from being interpreted as end-of-message.
    // ──────────────────────────────────────────────────────────
    error_clear_last();

    // Build the full RFC 822 message. sendmail -t reads To/Subject
    // from the headers, so we put them in the message itself
    // rather than passing as separate args.
    $rfc822 = "To: $to\r\n" .
              'Subject: ' . $subjectEnc . "\r\n" .
              implode("\r\n", $headers) . "\r\n" .
              "\r\n" .   // blank line separating headers from body
              $html;

    $descriptors = [
        0 => ['pipe', 'r'],  // stdin: we write the message here
        1 => ['pipe', 'w'],  // stdout: sendmail normally silent
        2 => ['pipe', 'w'],  // stderr: real error messages go here
    ];

    $proc = @proc_open('/usr/sbin/sendmail -t -i', $descriptors, $pipes);
    if (!is_resource($proc)) {
        return [
            'sent'  => false,
            'error' => 'Could not invoke /usr/sbin/sendmail (proc_open failed)',
            'to'    => $to,
        ];
    }

    fwrite($pipes[0], $rfc822);
    fclose($pipes[0]);
    $stdout = stream_get_contents($pipes[1]); fclose($pipes[1]);
    $stderr = stream_get_contents($pipes[2]); fclose($pipes[2]);
    $exitCode = proc_close($proc);

    if ($exitCode !== 0) {
        // sendmail refused the message — stderr has the reason.
        $detail = trim($stderr);
        if ($detail === '' && trim($stdout) !== '') $detail = trim($stdout);
        if ($detail === '') $detail = "sendmail exited with code $exitCode";
        return [
            'sent'  => false,
            'error' => $detail,
            'to'    => $to,
        ];
    }

    return ['sent' => true, 'to' => $to];
}

/** Builds the HTML body of the new-order confirmation email. */
function build_order_email_html(string $orderNumber, string $name, string $phone,
                                string $notes, array $items, float $total,
                                string $currency, string $restName,
                                string $paymentMethod = '', string $paymentStatus = ''): string
{
    $rows = '';
    foreach ($items as $it) {
        $itemName   = htmlspecialchars($it['name'] ?? '', ENT_QUOTES, 'UTF-8');
        $itemNameAr = htmlspecialchars($it['name_ar'] ?? '', ENT_QUOTES, 'UTF-8');
        $size       = htmlspecialchars($it['size_label'] ?? '', ENT_QUOTES, 'UTF-8');
        $qty        = intval($it['quantity'] ?? 1);
        $sub        = number_format(floatval($it['subtotal'] ?? 0), 3);
        $extras     = '';
        if (!empty($it['extras']) && is_array($it['extras'])) {
            $extras = "<div style='font-size:11px;color:#777;margin-top:2px'>+ " .
                      htmlspecialchars(implode(', ', array_column($it['extras'], 'name')),
                                       ENT_QUOTES, 'UTF-8') . "</div>";
        }
        $sizeRow = $size ? "<div style='font-size:11px;color:#888'>$size</div>" : '';
        $arRow   = $itemNameAr ? "<div style='font-size:11px;color:#888;direction:rtl'>$itemNameAr</div>" : '';
        $rows .= "<tr>
            <td style='padding:10px;border-bottom:1px solid #eee'>
              <div style='font-weight:600'>$itemName</div>
              $arRow $sizeRow $extras
            </td>
            <td style='padding:10px;border-bottom:1px solid #eee;text-align:center'>$qty</td>
            <td style='padding:10px;border-bottom:1px solid #eee;text-align:right'>$currency $sub</td>
          </tr>";
    }
    $notesBlock = $notes ? "<div style='margin:12px 0;padding:10px;background:#fef3c7;border-left:3px solid #f59e0b;border-radius:4px'>
        <strong>Notes:</strong> " . htmlspecialchars($notes, ENT_QUOTES, 'UTF-8') . "</div>" : '';

    $nameEsc  = htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
    $phoneEsc = htmlspecialchars($phone, ENT_QUOTES, 'UTF-8');
    $phoneLink = preg_replace('/[^\d]/', '', $phone);
    $totalFmt = number_format($total, 3);
    $dateStr  = date('Y-m-d H:i');

    // Payment block — color-coded based on what staff needs to do.
    // Green = already paid, no action. Amber = collect on hand-off.
    // Red = something's wrong (failed/pending), should not prepare.
    [$payLabel, $payColor, $payBg] = (function () use ($paymentMethod, $paymentStatus) {
        if ($paymentMethod === 'knet_card') {
            if ($paymentStatus === 'paid')    return ['Paid online (Card / KNET)', '#14532d', '#dcfce7'];
            if ($paymentStatus === 'failed')  return ['Payment FAILED — do not prepare', '#991b1b', '#fee2e2'];
            if ($paymentStatus === 'pending') return ['Awaiting payment',                '#78350f', '#fef3c7'];
            return ['Card / KNET', '#78350f', '#fef3c7'];
        }
        if ($paymentMethod === 'cash')    return ['Cash on delivery — collect on hand-off', '#78350f', '#fef3c7'];
        if ($paymentMethod === 'counter') return ['Pay at counter — verify before hand-off', '#78350f', '#fef3c7'];
        return ['WhatsApp confirmed', '#444', '#f1f5f9'];
    })();
    $paymentBlock = "<div style='margin:12px 0;padding:12px 14px;background:$payBg;border-radius:6px;font-size:14px;font-weight:600;color:$payColor;text-align:center'>"
        . htmlspecialchars($payLabel, ENT_QUOTES, 'UTF-8') . "</div>";

    return "<!doctype html><html><head><meta charset='utf-8'></head>
    <body style='font-family:Arial,sans-serif;color:#222;max-width:600px;margin:0 auto;padding:20px;background:#fafafa'>
      <div style='background:#fff;padding:24px;border-radius:8px;border:1px solid #e5e5e5'>
        <div style='background:#c4362c;color:#fff;padding:14px 18px;margin:-24px -24px 20px;border-radius:8px 8px 0 0'>
          <div style='font-size:12px;letter-spacing:2px;text-transform:uppercase;opacity:0.85'>Order Confirmed</div>
          <div style='font-size:22px;font-weight:700;margin-top:4px'>$orderNumber</div>
        </div>
        <table style='width:100%;margin-bottom:18px;font-size:14px'>
          <tr><td style='color:#666;width:120px'>Customer:</td><td><strong>$nameEsc</strong></td></tr>
          <tr><td style='color:#666'>WhatsApp:</td><td><a href='https://wa.me/$phoneLink'>$phoneEsc</a></td></tr>
          <tr><td style='color:#666'>Received:</td><td>$dateStr</td></tr>
        </table>
        $paymentBlock
        $notesBlock
        <table style='width:100%;border-collapse:collapse;font-size:14px'>
          <thead>
            <tr style='background:#f5f5f5'>
              <th style='padding:10px;text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#888'>Item</th>
              <th style='padding:10px;text-align:center;font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#888'>Qty</th>
              <th style='padding:10px;text-align:right;font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#888'>Price</th>
            </tr>
          </thead>
          <tbody>$rows</tbody>
          <tfoot>
            <tr>
              <td colspan='2' style='padding:16px 10px;text-align:right;font-weight:700;font-size:16px'>Total</td>
              <td style='padding:16px 10px;text-align:right;font-weight:700;font-size:16px;color:#c4362c'>$currency $totalFmt</td>
            </tr>
          </tfoot>
        </table>
        <div style='margin-top:24px;padding-top:16px;border-top:1px solid #eee;font-size:12px;color:#888;text-align:center'>
          $restName · <a href='" . SITE_URL . "/admin/orders.php' style='color:#c4362c;text-decoration:none'>Open in dashboard</a>
        </div>
      </div>
    </body></html>";
}
