import { NextRequest } from 'next/server';
import { getWidgetSettings } from '@server/services/widget.service';
import { wrapRouteHandler } from '@server/logger/request';

const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

function escHtml(value: string): string {
  return String(value || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}

const HEX_COLOR_RE = /^#[0-9a-f]{6}$/i;
const FALLBACK_COLOR = '#f97316';

function sanitizeColor(color: string | null | undefined): string {
  const c = (color || '').trim();
  return HEX_COLOR_RE.test(c) ? c : FALLBACK_COLOR;
}

function darkenHex(hex: string, amount: number): string {
  const num = parseInt(hex.replace('#', ''), 16);
  if (isNaN(num)) return FALLBACK_COLOR;
  const r = Math.max(0, (num >> 16) - amount);
  const g = Math.max(0, ((num >> 8) & 0xff) - amount);
  const b = Math.max(0, (num & 0xff) - amount);
  return '#' + ((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1);
}

function hexToRgb(hex: string): string {
  const r = parseInt(hex.slice(1, 3), 16);
  const g = parseInt(hex.slice(3, 5), 16);
  const b = parseInt(hex.slice(5, 7), 16);
  return `${r},${g},${b}`;
}

async function resolveBranding(req: NextRequest): Promise<{ brandUrl: string; brandName: string }> {
  let brandUrl = '';
  let brandName = '';
  try {
    const { db, platformSettings } = await import('@server/db/drizzle');
    const { inArray } = await import('drizzle-orm');
    const rows = await db.select({ k: platformSettings.key, v: platformSettings.value })
      .from(platformSettings)
      .where(inArray(platformSettings.key, ['site_marketing_url', 'site_title']));
    for (const r of rows) {
      const v = typeof r.v === 'string' ? r.v : '';
      if (r.k === 'site_marketing_url' && v) brandUrl = v;
      if (r.k === 'site_title' && v) brandName = v;
    }
  } catch { /* ignore */ }
  if (!brandUrl) {
    try { brandUrl = new URL(req.url).origin; } catch { brandUrl = '#'; }
  }
  if (!brandName) brandName = 'RestroAgent';
  return { brandUrl, brandName };
}

export const GET = wrapRouteHandler(async (req: Request) => {
  const nreq = req as NextRequest;
  return _handleGET(nreq);
});

const _handleGET = async (req: NextRequest) => {
  const url = new URL(req.url);
  const rawId = url.searchParams.get('restaurantId') || '';

  if (!UUID_RE.test(rawId)) {
    return new Response('Invalid restaurantId', { status: 400 });
  }

  const settings = await getWidgetSettings(rawId);
  const { brandUrl, brandName } = await resolveBranding(req);
  const pc = sanitizeColor(settings?.primary_color);
  const dark = darkenHex(pc, 30);
  const rgb = hexToRgb(pc);
  const botName = escHtml(settings?.bot_name || 'AI Assistant');
  const placeholder = escHtml(settings?.placeholder_text || 'Type your message...');
  const welcomeMsg = escHtml(settings?.welcome_message || '');
  const iconUrl = settings?.icon_url || null;
  const avatarHtml = iconUrl
    ? `<img src="${escHtml(iconUrl)}" alt="Bot" style="width:100%;height:100%;object-fit:cover;border-radius:50%;" />`
    : '&#x1F37D;&#xFE0F;';

  const html = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Chat Preview</title>
  <style>
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
    html, body { height: 100%; overflow: hidden; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #fff; }

    #chat-panel { display: flex; flex-direction: column; height: 100vh; width: 100%; background: #fff; }

    #chat-header {
      background: linear-gradient(135deg, ${pc}, ${dark});
      padding: 12px 14px; display: flex; align-items: center; gap: 10px; flex-shrink: 0;
    }
    .hdr-avatar { width: 36px; height: 36px; background: rgba(255,255,255,0.2); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; overflow: hidden; }
    .hdr-info { flex: 1; }
    .hdr-name { color: white; font-weight: 700; font-size: 14px; }
    .hdr-status { color: rgba(255,255,255,0.8); font-size: 11px; display: flex; align-items: center; gap: 4px; margin-top: 2px; }
    .hdr-dot { width: 6px; height: 6px; background: #4ade80; border-radius: 50%; animation: blink 2s infinite; }
    @keyframes blink { 0%,100%{opacity:1} 50%{opacity:0.4} }

    #chat-messages {
      flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 9px; scroll-behavior: smooth;
    }
    #chat-messages::-webkit-scrollbar { width: 3px; }
    #chat-messages::-webkit-scrollbar-thumb { background: #e5e7eb; border-radius: 2px; }

    .msg-row { display: flex; gap: 6px; align-items: flex-end; }
    .msg-row.user { flex-direction: row-reverse; }
    .msg-icon { width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; color: white; }
    .msg-icon.ai { background: linear-gradient(135deg, ${pc}, ${dark}); font-size: 14px; }
    .msg-icon.user { background: linear-gradient(135deg, #6366f1, #4338ca); }
    .msg-bubble { max-width: 78%; min-width: fit-content; padding: 9px 12px; font-size: 13px; line-height: 1.5; word-break: break-word; }
    .msg-bubble.ai { background: #f3f4f6; color: #111827; border-radius: 4px 14px 14px 14px; }
    .msg-bubble.user { background: linear-gradient(135deg, ${pc}, ${dark}); color: white; border-radius: 14px 4px 14px 14px; }
    .msg-time { font-size: 10px; color: #9ca3af; margin-top: 3px; }

    .typing-row { display: flex; gap: 6px; align-items: flex-end; }
    .typing-dots { display: flex; gap: 4px; align-items: center; padding: 10px 14px; background: #f3f4f6; border-radius: 4px 14px 14px 14px; }
    .typing-dots span { width: 6px; height: 6px; border-radius: 50%; background: #d1d5db; animation: tdots 1.2s infinite; }
    .typing-dots span:nth-child(2) { animation-delay: 0.2s; }
    .typing-dots span:nth-child(3) { animation-delay: 0.4s; }
    @keyframes tdots { 0%,60%,100%{transform:translateY(0)} 30%{transform:translateY(-5px)} }

    .sys-msg { text-align: center; font-size: 11px; color: #9ca3af; background: #f9fafb; border-radius: 8px; padding: 4px 10px; align-self: center; }

    .action-card { background: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 10px; padding: 9px 12px; font-size: 12px; color: #15803d; display: flex; align-items: center; gap: 5px; }

    /* Chips */
    .chips-row { display: flex; flex-wrap: wrap; gap: 7px; margin-left: 32px; }
    .chip { background: #fff; border: 1.5px solid #e5e7eb; border-radius: 20px; padding: 6px 13px; font-size: 12px; color: #374151; cursor: pointer; transition: all 0.15s; white-space: nowrap; font-family: inherit; }
    .chip:hover:not(:disabled) { background: ${pc}; color: white; border-color: ${pc}; }
    .chip:disabled { opacity: 0.5; cursor: default; }
    .chip-primary { background: ${pc}; color: white; border-color: ${pc}; }
    .chip-primary:hover:not(:disabled) { background: ${dark}; border-color: ${dark}; }

    /* Menu */
    .menu-view { background: #f9fafb; border: 1.5px solid #e5e7eb; border-radius: 14px; overflow: visible; width: 100%; }
    .menu-hdr { display: flex; align-items: center; justify-content: space-between; padding: 9px 12px; background: ${pc}; color: white; border-radius: 12px 12px 0 0; overflow: hidden; }
    .menu-title { font-weight: 700; font-size: 13px; }
    .menu-close { background: rgba(255,255,255,0.2); border: none; cursor: pointer; color: white; font-size: 13px; width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
    .menu-close:hover { background: rgba(255,255,255,0.35); }
    .cat-tabs { display: flex; gap: 4px; padding: 8px 8px 6px; overflow-x: auto; background: #fff; border-bottom: 1px solid #f3f4f6; scrollbar-width: thin; scrollbar-color: #d1d5db transparent; -webkit-overflow-scrolling: touch; }
    .cat-tabs::-webkit-scrollbar { height: 3px; }
    .cat-tabs::-webkit-scrollbar-thumb { background: #d1d5db; border-radius: 2px; }
    .cat-tab { background: transparent; border: 1.5px solid #e5e7eb; border-radius: 16px; padding: 4px 10px; font-size: 11px; color: #6b7280; cursor: pointer; white-space: nowrap; font-family: inherit; transition: all 0.15s; flex-shrink: 0; }
    .cat-tab.active { background: ${pc}; color: white; border-color: ${pc}; font-weight: 600; }
    .cat-tab:hover:not(.active) { border-color: ${pc}; color: ${pc}; }
    .items-list { max-height: 200px; overflow-y: auto; padding: 6px; scrollbar-width: thin; }
    .items-list::-webkit-scrollbar { width: 3px; }
    .items-list::-webkit-scrollbar-thumb { background: #e5e7eb; border-radius: 2px; }
    .item-card { display: flex; align-items: center; gap: 8px; padding: 7px 6px; margin-bottom: 4px; background: #fff; border-radius: 10px; border: 1px solid #f3f4f6; }
    .item-card:last-child { margin-bottom: 0; }
    .item-img { width: 44px; height: 44px; border-radius: 8px; object-fit: cover; flex-shrink: 0; }
    .item-info { flex: 1; min-width: 0; }
    .item-name { font-size: 12px; font-weight: 600; color: #111827; }
    .item-desc { font-size: 11px; color: #9ca3af; margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .item-price { font-size: 12px; font-weight: 700; color: ${pc}; margin-top: 2px; }
    .item-qty { display: flex; align-items: center; gap: 5px; flex-shrink: 0; }
    .add-btn { background: ${pc}; color: white; border: none; border-radius: 7px; padding: 4px 9px; font-size: 11px; cursor: pointer; font-family: inherit; font-weight: 600; }
    .add-btn:hover { background: ${dark}; }
    .qty-btn { width: 22px; height: 22px; background: #f3f4f6; border: none; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 700; color: #374151; line-height: 1; }
    .qty-btn:hover { background: #e5e7eb; }
    .qty-num { font-size: 12px; font-weight: 700; color: #111827; min-width: 16px; text-align: center; }
    .vc-btn { display: none; align-items: center; justify-content: center; gap: 6px; width: 100%; padding: 10px 12px; background: #111827; color: white; border: none; cursor: pointer; font-size: 12px; font-weight: 700; font-family: inherit; }
    .vc-btn:hover { background: #1f2937; }

    /* Cart bar */
    #cart-bar { display: none; flex-shrink: 0; background: #111827; color: white; padding: 9px 12px; align-items: center; gap: 8px; }
    .cbi { flex: 1; font-size: 12px; color: rgba(255,255,255,0.85); }
    .cbi strong { color: white; font-size: 13px; }
    .cb-view { background: transparent; color: rgba(255,255,255,0.6); border: none; font-size: 11px; cursor: pointer; font-family: inherit; text-decoration: underline; white-space: nowrap; }
    .cb-view:hover { color: white; }
    .cb-order { background: ${pc}; color: white; border: none; border-radius: 8px; padding: 6px 12px; font-size: 12px; font-weight: 700; cursor: pointer; font-family: inherit; white-space: nowrap; }
    .cb-order:hover { background: ${dark}; }

    /* Cart summary */
    .cart-summary { background: #f9fafb; border: 1.5px solid #e5e7eb; border-radius: 12px; padding: 12px; width: 100%; }
    .cart-title { font-weight: 700; font-size: 13px; color: #111827; margin-bottom: 8px; }
    .cart-line { display: flex; justify-content: space-between; font-size: 12px; color: #374151; padding: 2px 0; }
    .cart-total { font-weight: 700; font-size: 13px; color: #111827; margin-top: 8px; padding-top: 8px; border-top: 1px solid #e5e7eb; }

    /* Booking */
    .booking-step { width: 100%; }
    .booking-q { font-size: 13px; font-weight: 600; color: #374151; margin-bottom: 8px; }
    .booking-input-row { display: flex; gap: 7px; align-items: center; margin-top: 6px; }
    .booking-input { flex: 1; border: 1.5px solid #e5e7eb; border-radius: 9px; padding: 7px 11px; font-size: 12px; font-family: inherit; outline: none; color: #111827; background: #fafafa; }
    .booking-input:focus { border-color: ${pc}; background: #fff; }
    .booking-confirm { background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 10px; padding: 10px 12px; margin-bottom: 10px; }
    .booking-title { font-weight: 700; font-size: 12px; color: #1d4ed8; margin-bottom: 6px; }
    .booking-line { font-size: 12px; color: #374151; padding: 2px 0; }

    #chat-footer { padding: 9px 12px; border-top: 1px solid #f3f4f6; display: flex; gap: 8px; align-items: flex-end; background: #fff; flex-shrink: 0; }
    #chat-input { flex: 1; border: 1.5px solid #e5e7eb; border-radius: 12px; padding: 8px 12px; font-size: 13px; font-family: inherit; outline: none; resize: none; max-height: 80px; transition: border-color 0.2s; color: #111827; background: #fafafa; line-height: 1.4; }
    #chat-input:focus { border-color: ${pc}; background: #fff; }
    #chat-input::placeholder { color: #9ca3af; }
    #send-btn { width: 36px; height: 36px; flex-shrink: 0; background: linear-gradient(135deg, ${pc}, ${dark}); border: none; border-radius: 10px; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(${rgb}, 0.35); }
    #send-btn:disabled { opacity: 0.45; cursor: default; }
    #send-btn svg { width: 15px; height: 15px; fill: white; }

    #branding { text-align: center; font-size: 10px; color: #d1d5db; padding: 4px 12px 6px; background: #fff; flex-shrink: 0; }
    #branding a { color: #9ca3af; text-decoration: none; }
    #branding a:hover { color: #6b7280; }
  </style>
</head>
<body>
  <div id="chat-panel">
    <div id="chat-header">
      <div class="hdr-avatar">${avatarHtml}</div>
      <div class="hdr-info">
        <div class="hdr-name">${botName}</div>
        <div class="hdr-status"><span class="hdr-dot"></span> Online</div>
      </div>
    </div>
    <div id="chat-messages"></div>
    <div id="cart-bar">
      <div class="cbi">&#x1F6D2; <strong><span id="cbc">0</span></strong> item(s) &middot; $<strong><span id="cbt">0.00</span></strong></div>
      <button class="cb-view" id="cbv">View</button>
      <button class="cb-order" id="cbo">Place Order</button>
    </div>
    <div id="chat-footer">
      <textarea id="chat-input" rows="1" placeholder="${placeholder}" maxlength="1000"></textarea>
      <button id="send-btn" aria-label="Send">
        <svg viewBox="0 0 24 24"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>
      </button>
    </div>
    <div id="branding">Powered by <a href="${escHtml(brandUrl)}" target="_blank" rel="noopener">${escHtml(brandName)}</a></div>
  </div>

  <script>
  (function() {
    var RESTAURANT_ID = '${rawId}';
    var WELCOME_MSG = '${welcomeMsg.replace(/'/g, "\\'")}';
    var sessionToken = null;
    var messages = [];
    var isLoading = false;
    var cart = {};
    var menuData = null;
    var activeCategory = null;
    var bookingStep = -1;
    var bookingData = {};

    var msgList = document.getElementById('chat-messages');
    var inputEl = document.getElementById('chat-input');
    var sendBtn = document.getElementById('send-btn');
    var cartBar = document.getElementById('cart-bar');
    var cbcEl  = document.getElementById('cbc');
    var cbtEl  = document.getElementById('cbt');

    document.getElementById('cbo').addEventListener('click', placeOrderFromCart);
    document.getElementById('cbv').addEventListener('click', showCartSummary);

    function getCartCount() { return Object.values(cart).reduce(function(s,i){return s+i.qty;},0); }
    function getCartTotal() { return Object.values(cart).reduce(function(s,i){return s+i.price*i.qty;},0); }

    function esc(s) { return String(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;'); }
    function nowTime() { return new Date().toLocaleTimeString([],{hour:'2-digit',minute:'2-digit'}); }
    function scrollDown() { setTimeout(function(){msgList.scrollTop=msgList.scrollHeight;},30); }

    function setLoading(v) {
      isLoading = v;
      sendBtn.disabled = v;
      inputEl.disabled = v;
    }

    /* Messages */
    function appendMsg(sender, content, meta) {
      meta = meta || {};
      messages.push({sender:sender, content:content});
      var isUser = sender === 'user';
      var row = document.createElement('div');
      row.className = 'msg-row' + (isUser ? ' user' : '');
      var icon = document.createElement('div');
      icon.className = 'msg-icon ' + (isUser ? 'user' : 'ai');
      icon.textContent = isUser ? 'Y' : '\\uD83E\\uDD16';
      var wrap = document.createElement('div');
      // Build the bubble + time via createElement so AI/user content (which may
      // contain HTML-significant characters) never reaches innerHTML.
      var bubble = document.createElement('div');
      bubble.className = 'msg-bubble ' + (isUser ? 'user' : 'ai');
      bubble.textContent = content;
      var timeEl = document.createElement('div');
      timeEl.className = 'msg-time';
      timeEl.textContent = nowTime();
      wrap.appendChild(bubble); wrap.appendChild(timeEl);
      if (isUser) { row.appendChild(wrap); row.appendChild(icon); }
      else { row.appendChild(icon); row.appendChild(wrap); }
      msgList.appendChild(row);
      if (meta.orderCreated) {
        var orderLabel = meta.orderCreated.order_number ? '#' + meta.orderCreated.order_number : String(meta.orderCreated.id||'').slice(0,8).toUpperCase();
        var ac = document.createElement('div'); ac.className = 'action-card'; ac.textContent = '\\u2705 Order placed! Order ' + orderLabel;
        msgList.appendChild(ac);
      }
      if (meta.bookingCreated) {
        var ac2 = document.createElement('div'); ac2.className = 'action-card'; ac2.textContent = '\\u2705 Booking confirmed! Ref: ' + String(meta.bookingCreated.id||'').slice(0,8).toUpperCase();
        msgList.appendChild(ac2);
      }
      scrollDown();
    }

    function appendSys(text) {
      var el = document.createElement('div'); el.className = 'sys-msg'; el.textContent = text; msgList.appendChild(el); scrollDown();
    }

    function showTyping() {
      var row = document.createElement('div'); row.id = 'typing-ind'; row.className = 'typing-row';
      var icon = document.createElement('div'); icon.className = 'msg-icon ai'; icon.textContent = '\\uD83E\\uDD16';
      var dots = document.createElement('div'); dots.className = 'typing-dots'; dots.innerHTML = '<span></span><span></span><span></span>';
      row.appendChild(icon); row.appendChild(dots); msgList.appendChild(row); scrollDown();
    }
    function hideTyping() { var el = document.getElementById('typing-ind'); if (el) el.remove(); }

    /* Quick replies */
    function addQuickReplies(replies) {
      if (!replies || !replies.length) return;
      var el = document.createElement('div'); el.className = 'chips-row';
      // Quick-reply labels come from the AI response — build them via
      // createElement + textContent so any reply text is treated as literal.
      replies.forEach(function(r){
        var b = document.createElement('button');
        b.className = 'chip';
        b.textContent = r;
        el.appendChild(b);
      });
      msgList.appendChild(el);
      el.querySelectorAll('.chip').forEach(function(chip){
        chip.addEventListener('click', function(){
          if (isLoading) return;
          var text = chip.textContent.trim(); el.remove();
          var lower = text.toLowerCase();
          if (lower.includes('menu')||lower.includes('order food')||lower.includes('browse')||lower.includes('see our menu')) { openMenuView(); }
          else if (lower.includes('book')||lower.includes('table')||lower.includes('reserv')) { bookingStep=0; bookingData={}; showBookingStep(); }
          else { appendMsg('user', text); sendToAI(text); }
        });
      });
      scrollDown();
    }

    /* AI item suggestion cards */
    function addItemCards(items) {
      if(!items||!items.length||!msgList) return;
      var row=document.createElement('div');
      row.style.cssText='display:flex;gap:8px;overflow-x:auto;padding:4px 0 4px 0;scrollbar-width:none;margin-bottom:4px;';
      items.forEach(function(item){
        var card=document.createElement('div');
        card.style.cssText='flex:0 0 auto;min-width:130px;max-width:160px;border:1px solid #e5e7eb;border-radius:12px;padding:10px 10px 8px;background:#fff;display:flex;flex-direction:column;gap:4px;box-shadow:0 1px 3px rgba(0,0,0,0.07);';
        var nm=document.createElement('div');
        nm.style.cssText='font-size:12px;font-weight:600;color:#111827;line-height:1.3;word-break:break-word;';
        nm.textContent=item.name;
        var itemPrice=isNaN(Number(item.price))?0:Number(item.price);
        var pr=document.createElement('div');
        pr.style.cssText='font-size:12px;color:#6b7280;font-weight:500;';
        pr.textContent='$'+itemPrice.toFixed(2);
        var btn=document.createElement('button');
        btn.className='chip chip-primary';
        btn.style.cssText='margin-top:4px;padding:4px 8px;font-size:11px;font-weight:600;border-radius:8px;';
        btn.textContent='+ Add to Cart';
        btn.addEventListener('click',function(){
          var key='ai-'+item.name.toLowerCase().replace(/[^a-z0-9]/g,'_');
          if(!cart[key]){cart[key]={name:item.name,price:itemPrice,qty:0};}
          cart[key].qty++; updateCartBar();
          btn.textContent='\\u2713 Added'; btn.className='chip'; btn.style.background='#16a34a'; btn.style.color='#fff'; btn.style.borderColor='#16a34a'; btn.disabled=true;
          setTimeout(function(){btn.textContent='+ Add to Cart'; btn.className='chip chip-primary'; btn.style.background=''; btn.style.color=''; btn.style.borderColor=''; btn.disabled=false;},1500);
        });
        card.appendChild(nm); card.appendChild(pr); card.appendChild(btn); row.appendChild(card);
      });
      msgList.appendChild(row); scrollDown();
    }

    /* Initial chips */
    function showInitialChips() {
      var existing = document.getElementById('init-chips'); if (existing) return;
      var el = document.createElement('div'); el.className = 'chips-row'; el.id = 'init-chips';
      var chips = [{a:'order',l:'\\uD83C\\uDF7D\\uFE0F Order Food'},{a:'book',l:'\\uD83D\\uDCC5 Book a Table'},{a:'ask',l:'\\uD83D\\uDCAC Ask a Question'}];
      // Build via DOM — same pattern as the other chip rows so no concat'ed
      // markup goes through innerHTML.
      chips.forEach(function(c){
        var b = document.createElement('button');
        b.className = 'chip';
        b.setAttribute('data-action', c.a);
        b.textContent = c.l;
        el.appendChild(b);
      });
      msgList.appendChild(el); scrollDown();
      el.querySelectorAll('.chip').forEach(function(chip){
        chip.addEventListener('click', function(){
          var a = chip.getAttribute('data-action'); el.remove();
          if (a==='order') { openMenuView(); }
          else if (a==='book') { bookingStep=0; bookingData={}; showBookingStep(); }
          else { inputEl.placeholder='What would you like to know?'; inputEl.focus(); appendSys('Type your question below.'); }
        });
      });
    }

    /* Menu */
    function openMenuView() {
      var existing = document.getElementById('menu-view'); if (existing) { existing.scrollIntoView({behavior:'smooth',block:'nearest'}); return; }
      if (menuData) { renderMenu(); return; }
      var loadEl = document.createElement('div'); loadEl.className='sys-msg'; loadEl.textContent='Loading menu\\u2026'; loadEl.id='menu-loading'; msgList.appendChild(loadEl); scrollDown();
      fetch('/api/widget/menu?restaurantId='+RESTAURANT_ID).then(function(r){return r.json();}).then(function(d){
        var loader=document.getElementById('menu-loading'); if(loader) loader.remove();
        menuData = (d.categories&&d.categories.length>0)?d:{categories:[]};
        activeCategory = menuData.categories.length>0?menuData.categories[0].id:null;
        renderMenu();
      }).catch(function(){
        var loader=document.getElementById('menu-loading'); if(loader) loader.textContent='Could not load menu.';
      });
    }

    function renderMenu() {
      if (!menuData||menuData.categories.length===0) { appendSys('Our digital menu is not set up yet. Feel free to ask!'); return; }
      var menuEl = document.createElement('div'); menuEl.id='menu-view'; menuEl.className='menu-view';
      // Static scaffold (no interpolation) — safe to assign via innerHTML.
      menuEl.innerHTML =
        '<div class="menu-hdr"><span class="menu-title">&#x1F4CB; Our Menu</span><button class="menu-close">&#x2715;</button></div>' +
        '<div class="cat-tabs"></div>' +
        '<div class="items-list"></div>' +
        '<button class="vc-btn">&#x1F6D2; Place Order &middot; <span class="vc-c">0</span> items &middot; $<span class="vc-t">0.00</span></button>';
      // Category tabs use restaurant-controlled name/id — build via DOM so
      // they cannot break out of attributes or inject markup.
      var tabsEl = menuEl.querySelector('.cat-tabs');
      menuData.categories.forEach(function(c){
        var tabBtn = document.createElement('button');
        tabBtn.className = 'cat-tab' + (c.id === activeCategory ? ' active' : '');
        tabBtn.setAttribute('data-cat', c.id);
        tabBtn.textContent = c.name;
        if (tabsEl) tabsEl.appendChild(tabBtn);
      });
      msgList.appendChild(menuEl); scrollDown();

      var itemsList = menuEl.querySelector('.items-list');
      var vcBtn = menuEl.querySelector('.vc-btn');

      function refreshItems() {
        var cat = null;
        for (var i=0;i<menuData.categories.length;i++){if(menuData.categories[i].id===activeCategory){cat=menuData.categories[i];break;}}
        if (!cat||!itemsList) return;
        // Wipe previous render with replaceChildren so no concat'ed strings linger.
        while (itemsList.firstChild) itemsList.removeChild(itemsList.firstChild);
        var avail = cat.items.filter(function(it){return it.is_available;});
        if (avail.length===0){
          var empty = document.createElement('div');
          empty.style.cssText = 'padding:12px;text-align:center;color:#9ca3af;font-size:12px;';
          empty.textContent = 'No items available.';
          itemsList.appendChild(empty);
          return;
        }
        // Build each row via createElement + textContent so item.id / item.name /
        // item.description never reach innerHTML — protects the widget iframe
        // (which lives on customer pages) from XSS via menu-data interpolation.
        avail.forEach(function(item){
          var qty = cart[item.id]?cart[item.id].qty:0;
          var card = document.createElement('div');
          card.className = 'item-card';
          if (item.image_url) {
            var img = document.createElement('img');
            img.className = 'item-img';
            img.src = item.image_url;
            img.alt = item.name || '';
            img.onerror = function(){ img.style.display = 'none'; };
            card.appendChild(img);
          }
          var info = document.createElement('div');
          info.className = 'item-info';
          var nameEl = document.createElement('div');
          nameEl.className = 'item-name';
          nameEl.textContent = item.name || '';
          if (item.is_veg) {
            var veg = document.createElement('span');
            veg.style.cssText = 'font-size:10px;color:#16a34a;font-weight:600;margin-left:3px;';
            veg.textContent = '\\uD83C\\uDF3F';
            nameEl.appendChild(veg);
          }
          info.appendChild(nameEl);
          if (item.description) {
            var desc = item.description.length>50 ? item.description.slice(0,50)+'\\u2026' : item.description;
            var descEl = document.createElement('div');
            descEl.className = 'item-desc';
            descEl.textContent = desc;
            info.appendChild(descEl);
          }
          var priceEl = document.createElement('div');
          priceEl.className = 'item-price';
          priceEl.textContent = '$'+Number(item.price).toFixed(2);
          info.appendChild(priceEl);
          card.appendChild(info);

          var qtyWrap = document.createElement('div');
          qtyWrap.className = 'item-qty';
          if (qty > 0) {
            var minus = document.createElement('button');
            minus.className = 'qty-btn qminus';
            minus.textContent = '\\u2212';
            minus.addEventListener('click', function(){
              if(cart[item.id]){cart[item.id].qty--;if(cart[item.id].qty<=0)delete cart[item.id];refreshItems();updateCartBar();refreshVcBtn();}
            });
            var qNum = document.createElement('span');
            qNum.className = 'qty-num';
            qNum.textContent = String(qty);
            var plus = document.createElement('button');
            plus.className = 'qty-btn qplus';
            plus.textContent = '+';
            plus.addEventListener('click', function(){
              if(!cart[item.id])cart[item.id]={name:item.name,price:Number(item.price),qty:0};
              cart[item.id].qty++; refreshItems(); updateCartBar(); refreshVcBtn();
            });
            qtyWrap.appendChild(minus); qtyWrap.appendChild(qNum); qtyWrap.appendChild(plus);
          } else {
            var add = document.createElement('button');
            add.className = 'add-btn';
            add.textContent = '+ Add';
            add.addEventListener('click', function(){
              if(!cart[item.id])cart[item.id]={name:item.name,price:Number(item.price),qty:0};
              cart[item.id].qty++; refreshItems(); updateCartBar(); refreshVcBtn();
            });
            qtyWrap.appendChild(add);
          }
          card.appendChild(qtyWrap);
          itemsList.appendChild(card);
        });
      }

      function refreshVcBtn(){
        var c=getCartCount(),t=getCartTotal();vcBtn.style.display=c>0?'flex':'none';
        var cc=vcBtn.querySelector('.vc-c');if(cc)cc.textContent=c;var ct=vcBtn.querySelector('.vc-t');if(ct)ct.textContent=t.toFixed(2);
      }

      menuEl.querySelectorAll('.cat-tab').forEach(function(tab){
        tab.addEventListener('click',function(){
          activeCategory=tab.getAttribute('data-cat');
          menuEl.querySelectorAll('.cat-tab').forEach(function(t){t.classList.toggle('active',t.getAttribute('data-cat')===activeCategory);});
          refreshItems();
        });
      });
      menuEl.querySelector('.menu-close').addEventListener('click',function(){menuEl.remove();updateCartBar();});
      vcBtn.addEventListener('click',function(){menuEl.remove();showCartSummary();});
      refreshItems(); refreshVcBtn();
    }

    function updateCartBar() {
      var cnt=getCartCount(),tot=getCartTotal();
      cartBar.style.display=cnt>0?'flex':'none';
      if(cbcEl)cbcEl.textContent=cnt; if(cbtEl)cbtEl.textContent=tot.toFixed(2);
    }

    function showCartSummary() {
      var items=Object.values(cart); if(items.length===0){openMenuView();return;}
      var tot=getCartTotal(); var el=document.createElement('div'); el.className='cart-summary';
      // Cart lines interpolate item.name (restaurant menu data) — build the
      // entire summary via DOM so no row content reaches innerHTML.
      var titleEl = document.createElement('div'); titleEl.className='cart-title'; titleEl.textContent='\\uD83D\\uDED2 Your Order';
      el.appendChild(titleEl);
      items.forEach(function(i){
        var line = document.createElement('div'); line.className='cart-line';
        var left = document.createElement('span'); left.textContent = i.qty + '\\u00D7 ' + i.name;
        var right = document.createElement('span'); right.textContent = '$' + (i.price * i.qty).toFixed(2);
        line.appendChild(left); line.appendChild(right);
        el.appendChild(line);
      });
      var totEl = document.createElement('div'); totEl.className='cart-total'; totEl.textContent = 'Total \\u00B7 $' + tot.toFixed(2);
      el.appendChild(totEl);
      var chipsRow = document.createElement('div'); chipsRow.className='chips-row'; chipsRow.style.cssText='margin-top:10px;margin-left:0;';
      var btnDo = document.createElement('button'); btnDo.className='chip chip-primary'; btnDo.id='do-order'; btnDo.textContent='\\u2705 Place Order';
      var btnAdd = document.createElement('button'); btnAdd.className='chip'; btnAdd.id='add-more'; btnAdd.textContent='+ Add More';
      var btnClr = document.createElement('button'); btnClr.className='chip'; btnClr.id='clear-cart'; btnClr.style.cssText='color:#ef4444;border-color:#fca5a5;'; btnClr.textContent='\\u00D7 Clear';
      chipsRow.appendChild(btnDo); chipsRow.appendChild(btnAdd); chipsRow.appendChild(btnClr);
      el.appendChild(chipsRow);
      msgList.appendChild(el); scrollDown();
      btnDo.addEventListener('click',function(){el.remove();placeOrderFromCart();});
      btnAdd.addEventListener('click',function(){el.remove();openMenuView();});
      btnClr.addEventListener('click',function(){cart={};el.remove();updateCartBar();appendSys('Cart cleared.');});
    }

    function placeOrderFromCart() {
      var items=Object.values(cart); if(items.length===0){openMenuView();return;}
      showOrderDeliveryStep();
    }

    function showOrderDeliveryStep() {
      var el=document.createElement('div'); el.className='booking-step';
      el.innerHTML='<div class="booking-q">&#x1F69A; How would you like your order?</div>'+
        '<div class="chips-row" style="margin-left:0;">'+
          '<button class="chip" data-dt="dine-in">&#x1F37D;&#xFE0F; Dine-In</button>'+
          '<button class="chip" data-dt="takeaway">&#x1F6CD;&#xFE0F; Takeaway</button>'+
          '<button class="chip" data-dt="delivery">&#x1F6EB; Delivery</button>'+
        '</div>';
      msgList.appendChild(el); scrollDown();
      el.querySelectorAll('.chip[data-dt]').forEach(function(chip){
        chip.addEventListener('click',function(){
          el.querySelectorAll('button').forEach(function(b){b.disabled=true;});
          var dt=chip.getAttribute('data-dt');
          var dtLabel=dt==='dine-in'?'Dine-In':dt==='takeaway'?'Takeaway':'Delivery';
          var q=el.querySelector('.booking-q'); if(q) q.textContent='\uD83D\uDE9A '+dtLabel+' \u2713';
          var cr=el.querySelector('.chips-row'); if(cr) cr.remove();
          if(dt==='dine-in'){showOrderTableStep(dt);}else if(dt==='delivery'){showOrderAddressStep(dt);}else{showOrderNameStep(dt,'','');}
        });
      });
    }

    function showOrderTableStep(deliveryType) {
      var el=document.createElement('div'); el.className='booking-step';
      el.innerHTML='<div class="booking-q">&#x1FA51; Which table are you at?</div>'+
        '<div class="booking-input-row">'+
          '<input type="text" class="booking-input" id="tbl-no" placeholder="e.g. 5" style="max-width:100px;" />'+
          '<button class="chip chip-primary" id="tbl-ok">Next &#x2192;</button>'+
          '<button class="chip" id="tbl-skip">No table</button>'+
        '</div>';
      msgList.appendChild(el); scrollDown();
      function proceed(tableNumber){
        el.querySelectorAll('button,input').forEach(function(b){b.disabled=true;});
        var q=el.querySelector('.booking-q');
        if(q)q.textContent=tableNumber?'\uD83E\uDE51 Table '+tableNumber+' \u2713':'\uD83E\uDE51 No table \u2713';
        el.querySelector('.booking-input-row')&&el.querySelector('.booking-input-row').remove();
        showOrderNameStep(deliveryType,tableNumber,'');
      }
      var tblOk=el.querySelector('#tbl-ok'),tblEl=el.querySelector('#tbl-no'),tblSkip=el.querySelector('#tbl-skip');
      if(tblOk&&tblEl){
        tblOk.addEventListener('click',function(){proceed(tblEl.value.trim());});
        tblEl.addEventListener('keydown',function(e){if(e.key==='Enter')tblOk.click();});
        setTimeout(function(){tblEl.focus();},60);
      }
      if(tblSkip){tblSkip.addEventListener('click',function(){proceed('');});}
    }

    function showOrderAddressStep(deliveryType) {
      var el=document.createElement('div'); el.className='booking-step';
      el.innerHTML='<div class="booking-q">&#x1F4CD; Your delivery address?</div>'+
        '<div class="booking-input-row">'+
          '<input type="text" class="booking-input" id="oa-addr" placeholder="e.g. 123 Main St, City" />'+
          '<button class="chip chip-primary" id="oa-ok">Next &#x2192;</button>'+
        '</div>';
      msgList.appendChild(el); scrollDown();
      var oaOk=el.querySelector('#oa-ok'),oaEl=el.querySelector('#oa-addr');
      if(oaOk&&oaEl){
        oaOk.addEventListener('click',function(){
          var v=oaEl.value.trim(); if(!v){oaEl.focus();return;}
          el.querySelectorAll('button,input').forEach(function(b){b.disabled=true;});
          var q=el.querySelector('.booking-q');if(q)q.textContent='\uD83D\uDCCD '+v+' \u2713';
          el.querySelector('.booking-input-row')&&el.querySelector('.booking-input-row').remove();
          showOrderNameStep(deliveryType,'',v);
        });
        oaEl.addEventListener('keydown',function(e){if(e.key==='Enter')oaOk.click();});
        setTimeout(function(){oaEl.focus();},60);
      }
    }

    function showOrderNameStep(deliveryType, tableNumber, deliveryAddress) {
      var el=document.createElement('div'); el.className='booking-step';
      el.innerHTML='<div class="booking-q">&#x1F464; Your name?</div>'+
        '<div class="booking-input-row">'+
          '<input type="text" class="booking-input" id="on-name" placeholder="e.g. John Smith" />'+
          '<button class="chip chip-primary" id="on-ok">Next &#x2192;</button>'+
        '</div>';
      msgList.appendChild(el); scrollDown();
      var onOk=el.querySelector('#on-ok'),onEl=el.querySelector('#on-name');
      if(onOk&&onEl){
        onOk.addEventListener('click',function(){
          var v=onEl.value.trim(); if(!v){onEl.focus();return;}
          el.querySelectorAll('button,input').forEach(function(b){b.disabled=true;});
          var q=el.querySelector('.booking-q');if(q)q.textContent='\uD83D\uDC64 '+v+' \u2713';
          el.querySelector('.booking-input-row')&&el.querySelector('.booking-input-row').remove();
          showOrderPhoneStep(deliveryType,tableNumber,v,deliveryAddress);
        });
        onEl.addEventListener('keydown',function(e){if(e.key==='Enter')onOk.click();});
        setTimeout(function(){onEl.focus();},60);
      }
    }

    function showOrderPhoneStep(deliveryType, tableNumber, customerName, deliveryAddress) {
      var el=document.createElement('div'); el.className='booking-step';
      el.innerHTML='<div class="booking-q">&#x1F4F1; Your phone number</div>'+
        '<div class="booking-input-row">'+
          '<input type="tel" class="booking-input" id="op-phone" placeholder="e.g. +1 555 000 0000" />'+
          '<button class="chip chip-primary" id="op-ok">Place Order</button>'+
        '</div>';
      msgList.appendChild(el); scrollDown();
      function confirmOrder(phone) {
        el.querySelectorAll('button,input').forEach(function(b){b.disabled=true;});
        var items=Object.values(cart); var tot=getCartTotal();
        var displaySummary=items.map(function(i){return i.qty+'\u00D7 '+i.name;}).join(', ');
        var aiSummary=items.map(function(i){return i.qty+'x '+i.name+' @$'+(i.price||0).toFixed(2);}).join(', ');
        var dtLabel=deliveryType==='dine-in'?'Dine-In':deliveryType==='takeaway'?'Takeaway':'Delivery';
        var name=customerName||'Widget Customer';
        var aiMsg='I would like to order: '+aiSummary+'. Total: $'+tot.toFixed(2)+'. Delivery type: '+dtLabel+'. Customer name: '+name+'. My phone number: '+phone+(tableNumber?'. Table number: '+tableNumber:'')+(deliveryAddress?'. Delivery address: '+deliveryAddress:'')+'. Please process this order now using the place_order tool.';
        cart={}; updateCartBar();
        appendMsg('user','Place my order: '+displaySummary);
        sendToAI(aiMsg);
      }
      var opOk=el.querySelector('#op-ok'),opEl=el.querySelector('#op-phone');
      if(opOk&&opEl){
        opOk.addEventListener('click',function(){var v=opEl.value.trim();if(!v){opEl.focus();return;}confirmOrder(v);});
        opEl.addEventListener('keydown',function(e){if(e.key==='Enter')opOk.click();});
        setTimeout(function(){opEl.focus();},60);
      }
    }

    /* Booking */
    function isoToTime12(t){var pts=t.split(':');var hh=parseInt(pts[0], 10);var mm=pts[1];var ap=hh>=12?'PM':'AM';hh=hh%12||12;return hh+':'+mm+' '+ap;}
    function toIsoDate(d){var y=d.getFullYear();var m=d.getMonth()+1;var dd=d.getDate();return y+'-'+(m<10?'0':'')+m+'-'+(dd<10?'0':'')+dd;}

    function showBookingStep() {
      var step=bookingStep; var el=document.createElement('div'); el.className='booking-step';
      // Helper: append a chip button with optional data-val / data-iso.
      function addChip(parent, label, val, iso) {
        var b = document.createElement('button');
        b.className = 'chip';
        if (val !== undefined) b.setAttribute('data-val', val);
        if (iso !== undefined) b.setAttribute('data-iso', iso);
        b.textContent = label;
        parent.appendChild(b);
        return b;
      }
      function addQ(parent, text) {
        var q = document.createElement('div'); q.className='booking-q'; q.textContent = text; parent.appendChild(q); return q;
      }
      function addChipsRow(parent) {
        var r = document.createElement('div'); r.className='chips-row'; r.style.cssText='margin-left:0;'; parent.appendChild(r); return r;
      }

      if (step===0) {
        var today=new Date(); var tom=new Date(today); tom.setDate(today.getDate()+1); var da=new Date(today); da.setDate(today.getDate()+2);
        function fd(d){return d.toLocaleDateString('en-US',{weekday:'long',month:'long',day:'numeric'});}
        addQ(el, '\\uD83D\\uDCC5 When would you like to visit?');
        var row0 = addChipsRow(el);
        addChip(row0, 'Today', fd(today), toIsoDate(today));
        addChip(row0, 'Tomorrow', fd(tom), toIsoDate(tom));
        addChip(row0, da.toLocaleDateString('en-US',{weekday:'short',month:'short',day:'numeric'}), fd(da), toIsoDate(da));
        // Date input + button — purely static markup, no interpolation.
        var inputRow0 = document.createElement('div'); inputRow0.className='booking-input-row';
        inputRow0.innerHTML = '<input type="date" class="booking-input" id="dp" /><button class="chip" id="dp-ok">Other date</button>';
        el.appendChild(inputRow0);
      } else if (step===1) {
        var tcs=[{label:'12:00 PM',iso:'12:00'},{label:'1:00 PM',iso:'13:00'},{label:'6:00 PM',iso:'18:00'},{label:'7:00 PM',iso:'19:00'},{label:'8:00 PM',iso:'20:00'}];
        addQ(el, '\\uD83D\\uDD50 What time?');
        var row1 = addChipsRow(el);
        tcs.forEach(function(t){ addChip(row1, t.label, t.label, t.iso); });
        var inputRow1 = document.createElement('div'); inputRow1.className='booking-input-row';
        inputRow1.innerHTML = '<input type="time" class="booking-input" id="tp" /><button class="chip" id="tp-ok">Other time</button>';
        el.appendChild(inputRow1);
      } else if (step===2) {
        addQ(el, '\\uD83D\\uDC65 How many guests?');
        var row2 = addChipsRow(el);
        ['1','2','3','4','5','6','7+'].forEach(function(n){ addChip(row2, n, n); });
      } else if (step===3) {
        el.innerHTML='<div class="booking-q">&#x1F464; Name for the reservation?</div>'+
          '<div class="booking-input-row"><input type="text" class="booking-input" id="np" placeholder="Your name"/><button class="chip chip-primary" id="np-ok">Next &#x2192;</button></div>';
      } else if (step===4) {
        el.innerHTML='<div class="booking-q">&#x1F4F1; Your phone number</div>'+
          '<div class="booking-input-row"><input type="tel" class="booking-input" id="bph" placeholder="e.g. +1 555 000 0000"/><button class="chip chip-primary" id="bph-ok">Next &#x2192;</button></div>';
      } else if (step===5) {
        // Confirm card interpolates user-typed name/phone — build via DOM.
        var d=bookingData;
        var conf = document.createElement('div'); conf.className='booking-confirm';
        var ctitle = document.createElement('div'); ctitle.className='booking-title'; ctitle.textContent='\\uD83D\\uDCCB Confirm Reservation'; conf.appendChild(ctitle);
        var l1 = document.createElement('div'); l1.className='booking-line'; l1.textContent='\\uD83D\\uDCC5 ' + (d.date||''); conf.appendChild(l1);
        var l2 = document.createElement('div'); l2.className='booking-line'; l2.textContent='\\uD83D\\uDD50 ' + (d.time||''); conf.appendChild(l2);
        var psStr = String(d.partySize||'');
        var l3 = document.createElement('div'); l3.className='booking-line'; l3.textContent='\\uD83D\\uDC65 ' + psStr + ' guest' + (parseInt(d.partySize, 10)!==1?'s':''); conf.appendChild(l3);
        var l4 = document.createElement('div'); l4.className='booking-line'; l4.textContent='\\uD83D\\uDC64 ' + (d.name||''); conf.appendChild(l4);
        if (d.phone) { var l5 = document.createElement('div'); l5.className='booking-line'; l5.textContent='\\uD83D\\uDCF1 ' + d.phone; conf.appendChild(l5); }
        el.appendChild(conf);
        var confRow = addChipsRow(el);
        var bConf = document.createElement('button'); bConf.className='chip chip-primary'; bConf.id='conf-book'; bConf.textContent='\\u2705 Confirm'; confRow.appendChild(bConf);
        var bRest = document.createElement('button'); bRest.className='chip'; bRest.id='restart-book'; bRest.textContent='\\u2190 Start over'; confRow.appendChild(bRest);
      }
      msgList.appendChild(el); scrollDown();

      el.querySelectorAll('.chip[data-val]').forEach(function(chip){
        chip.addEventListener('click',function(){handleBookingChoice(chip.getAttribute('data-val'),el,chip.getAttribute('data-iso'));});
      });
      if(step===0){var dpOk=el.querySelector('#dp-ok'),dp=el.querySelector('#dp');if(dpOk&&dp)dpOk.addEventListener('click',function(){if(!dp.value)return;var isoDate=dp.value;var dt=new Date(dp.value+'T12:00:00');handleBookingChoice(dt.toLocaleDateString('en-US',{weekday:'long',month:'long',day:'numeric'}),el,isoDate);});}
      if(step===1){var tpOk=el.querySelector('#tp-ok'),tp=el.querySelector('#tp');if(tpOk&&tp)tpOk.addEventListener('click',function(){if(!tp.value)return;handleBookingChoice(isoToTime12(tp.value),el,tp.value);});}
      if(step===3){var npOk=el.querySelector('#np-ok'),np=el.querySelector('#np');if(npOk&&np){npOk.addEventListener('click',function(){var v=np.value.trim();if(v)handleBookingChoice(v,el);});np.addEventListener('keydown',function(e){if(e.key==='Enter')npOk.click();});setTimeout(function(){np.focus();},60);}}
      if(step===4){
        var bphOk=el.querySelector('#bph-ok'),bph=el.querySelector('#bph');
        if(bphOk&&bph){bphOk.addEventListener('click',function(){var v=bph.value.trim();if(!v){bph.focus();return;}handleBookingChoice(v,el);});bph.addEventListener('keydown',function(e){if(e.key==='Enter')bphOk.click();});setTimeout(function(){bph.focus();},60);}
      }
      if(step===5){
        var cb=el.querySelector('#conf-book'),rb=el.querySelector('#restart-book');
        if(cb)cb.addEventListener('click',function(){
          el.remove();var d2=bookingData;
          appendMsg('user','&#x1F4C5; Book: '+d2.partySize+' guests on '+d2.date+' at '+d2.time);
          var dateStr2=d2.date+(d2.isoDate?' (ISO: '+d2.isoDate+')':'');
          var timeStr2=d2.time+(d2.isoTime?' (ISO: '+d2.isoTime+')':'');
          sendToAI('Please book a table for '+d2.partySize+' guests on '+dateStr2+' at '+timeStr2+' for '+d2.name+'.'+(d2.phone?' Phone: '+d2.phone+'.':'')+' Please confirm and use the book_table tool.');
          bookingStep=-1;bookingData={};
        });
        if(rb)rb.addEventListener('click',function(){el.remove();bookingStep=0;bookingData={};showBookingStep();});
      }
    }

    function handleBookingChoice(val,el,isoVal){
      el.querySelectorAll('button,input').forEach(function(b){b.disabled=true;});
      var step=bookingStep;
      if(step===0){bookingData.date=val;if(isoVal)bookingData.isoDate=isoVal;var q=el.querySelector('.booking-q');if(q)q.textContent='\uD83D\uDCC5 '+val+' \u2713';}
      else if(step===1){bookingData.time=val;if(isoVal)bookingData.isoTime=isoVal;var q2=el.querySelector('.booking-q');if(q2)q2.textContent='\uD83D\uDD50 '+val+' \u2713';}
      else if(step===2){bookingData.partySize=val;var q3=el.querySelector('.booking-q');if(q3)q3.textContent='\uD83D\uDC65 '+val+' guest'+(parseInt(val, 10)!==1?'s':'')+' \u2713';}
      else if(step===3){bookingData.name=val;}
      else if(step===4){bookingData.phone=val||'';}
      var cr=el.querySelector('.chips-row');if(cr)cr.remove();var ir=el.querySelector('.booking-input-row');if(ir)ir.remove();
      bookingStep++;setTimeout(showBookingStep,120);
    }

    /* AI */
    async function sendToAI(messageText) {
      if (!sessionToken) {
        try {
          var sr=await fetch('/api/widget/start',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({restaurantId:RESTAURANT_ID})});
          var sd=await sr.json(); sessionToken=sd.sessionToken||null;
        } catch(e){}
      }
      if (!sessionToken) { appendMsg('ai','Sorry, I could not connect right now.'); setLoading(false); return; }
      setLoading(true); showTyping();
      var history=messages.slice(-20).map(function(m){return{role:m.sender==='user'?'user':'assistant',content:m.content};});
      try {
        var res=await fetch('/api/widget/message',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionToken:sessionToken,message:messageText,history:history.slice(0,-1)})});
        var data=await res.json(); hideTyping();
        appendMsg('ai', data.reply||'How can I help you?', {orderCreated:data.orderCreated,bookingCreated:data.bookingCreated});
        if(data.quickReplies&&data.quickReplies.length>0){setTimeout(function(){addQuickReplies(data.quickReplies);},80);}
        if(data.suggestedItems&&data.suggestedItems.length>0){setTimeout(function(){addItemCards(data.suggestedItems);},120);}
        if(data.shouldEscalate){appendSys('You are now connected with our team.');}
      } catch(e) {
        hideTyping(); appendMsg('ai','Sorry, something went wrong.');
      } finally {
        setLoading(false); inputEl.focus();
      }
    }

    async function sendMessage() {
      var text=inputEl.value.trim(); if(!text||isLoading) return;
      var ic=document.getElementById('init-chips'); if(ic) ic.remove();
      inputEl.value=''; inputEl.style.height='auto';
      appendMsg('user',text); await sendToAI(text);
    }

    sendBtn.addEventListener('click', sendMessage);
    inputEl.addEventListener('keydown', function(e){if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();sendMessage();}});
    inputEl.addEventListener('input', function(){this.style.height='auto';this.style.height=Math.min(this.scrollHeight,80)+'px';});

    /* Session start */
    async function startSession() {
      try {
        var res=await fetch('/api/widget/start',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({restaurantId:RESTAURANT_ID})});
        var data=await res.json(); sessionToken=data.sessionToken||null;
        if(WELCOME_MSG) { appendMsg('ai',WELCOME_MSG); setTimeout(showInitialChips,250); }
        else { showInitialChips(); }
      } catch(e) {
        appendSys('Could not connect. Check your settings and try refreshing.');
      }
      sendBtn.disabled = false;
    }

    startSession();
  })();
  </script>
</body>
</html>`;

  return new Response(html, {
    headers: {
      'Content-Type': 'text/html; charset=utf-8',
      'Cache-Control': 'no-store',
      'X-Frame-Options': 'SAMEORIGIN',
    },
  });
};
