// Kitchen Display — bar + kitchen station tickets, per-item status workflow.
// Each item moves new → cooking → ready → served independently. When every
// item is served the order auto-closes.
// Urgent thresholds differ by station — bar drinks should be quick.
const URGENT_SEC = { bar: 5 * 60, kitchen: 10 * 60 };
const DEFAULT_URGENT_SEC = 10 * 60;

const NEXT_STATUS = { new: "cooking", cooking: "ready", ready: "served" };

// Read an item's status, falling back to the legacy order-level fields for
// pre-existing orders that don't have per-item status yet.
function itemStatusOf(item, order) {
  if (item.status) return item.status;
  if (item.station === "bar") return order.barStatus || "new";
  if (item.station === "kitchen") return order.kitchenStatus || "new";
  return "new";
}

function isItemUrgent(item, order) {
  const status = itemStatusOf(item, order);
  if (status === "ready" || status === "served") return false;
  const ms = tsToMs(order.createdAt);
  if (!ms) return false;
  const limit = URGENT_SEC[item.station] || DEFAULT_URGENT_SEC;
  return Math.floor((Date.now() - ms) / 1000) >= limit;
}

// Play a short two-beep notification using the Web Audio API.
function playKdsAlert() {
  try {
    const Ctx = window.AudioContext || window.webkitAudioContext;
    if (!Ctx) return;
    const ctx = new Ctx();
    const beep = (t) => {
      const o = ctx.createOscillator();
      const g = ctx.createGain();
      o.type = "sine"; o.frequency.value = 880;
      g.gain.setValueAtTime(0.0001, t);
      g.gain.exponentialRampToValueAtTime(0.35, t + 0.02);
      g.gain.exponentialRampToValueAtTime(0.0001, t + 0.22);
      o.connect(g).connect(ctx.destination);
      o.start(t); o.stop(t + 0.25);
    };
    const now = ctx.currentTime;
    beep(now); beep(now + 0.35);
    setTimeout(() => ctx.close && ctx.close(), 1200);
  } catch (_) { /* audio blocked — silent */ }
}

function KitchenScreen() {
  const { orders, advanceItem, rewindItem } = usePOS();
  useTick(1000);
  const [station, setStation] = React.useState("kitchen"); // 'kitchen' | 'bar' | 'all'
  const [historyOpen, setHistoryOpen] = React.useState(false);
  const alerted = React.useRef(new Set());

  // Each "ticket" is a per-order group, but item-level status governs visibility.
  const tickets = orders
    .filter((o) => o.status !== "closed")
    .map((o) => {
      // Items at the chosen station that aren't yet served.
      const items = o.items
        .map((it, originalIdx) => ({ it, originalIdx, status: itemStatusOf(it, o) }))
        .filter(({ it, status }) => {
          const stationOk = station === "all" || it.station === station;
          return stationOk && status !== "served";
        });
      return { order: o, items };
    })
    .filter((t) => t.items.length > 0)
    // Oldest first — cook the earliest order first.
    .sort((a, b) => (a.order.createdAt?.seconds || 0) - (b.order.createdAt?.seconds || 0));

  // Beep once per ticket when any of its items crosses its station's urgent
  // threshold (bar=5min, kitchen=10min).
  React.useEffect(() => {
    tickets.forEach(({ order, items }) => {
      const anyUrgent = items.some(({ it, status }) => status !== "ready" && isItemUrgent(it, order));
      if (anyUrgent && !alerted.current.has(order.id)) {
        alerted.current.add(order.id);
        playKdsAlert();
      }
    });
  });

  return (
    <div className="kds">
      <header className="kds-head">
        <div>
          <div className="eyebrow mono">KITCHEN DISPLAY</div>
          <h2>{tickets.length} active ticket{tickets.length === 1 ? "" : "s"}</h2>
        </div>
        <div className="kds-head-right">
          <div className="station-toggle">
            {[
              { id: "kitchen", label: "Kitchen" },
              { id: "bar", label: "Bar" },
              { id: "all", label: "Both" },
            ].map((s) => (
              <button
                key={s.id}
                className={"station-tab" + (station === s.id ? " active" : "")}
                onClick={() => setStation(s.id)}
              >{s.label}</button>
            ))}
          </div>
          <button className="kiosk-signout mono" onClick={() => setHistoryOpen(true)} title="View history">History</button>
          <button className="kiosk-signout mono" onClick={() => firebase.auth().signOut()} title="Sign out">Sign out</button>
        </div>
      </header>

      <div className="kds-board">
        {tickets.length === 0 && (
          <div className="kds-empty">
            <div className="empty-mark">✓</div>
            <p>All caught up.</p>
          </div>
        )}
        {tickets.map(({ order, items }) => (
          <KitchenTicket key={order.id} order={order} items={items}
            advanceItem={advanceItem} rewindItem={rewindItem} />
        ))}
      </div>
      {historyOpen && (
        <HistorySheet
          stationFilter={station === "all" ? null : station}
          onClose={() => setHistoryOpen(false)}
        />
      )}
    </div>
  );
}

// Today's processed-item history. Pulls from the live `orders` array (which
// includes closed orders for today), then flattens to a per-item log sorted
// by served time descending.
function HistorySheet({ stationFilter, onClose }) {
  const { orders, rewindItem } = usePOS();
  const fmtTime = (ms) => ms
    ? new Date(ms).toLocaleTimeString("id-ID", { hour: "2-digit", minute: "2-digit", second: "2-digit" })
    : "—";

  const rows = [];
  orders.forEach((o) => {
    (o.items || []).forEach((it, idx) => {
      const status = it.status || (it.station === "bar" ? o.barStatus : o.kitchenStatus) || "new";
      if (status === "new") return; // never started, not history
      if (stationFilter && it.station !== stationFilter) return;
      rows.push({
        idx,
        order: o,
        item: it,
        status,
        servedAt: it.servedAt || null,
        readyAt: it.readyAt || null,
        cookingAt: it.cookingAt || null,
        // For sort: prefer servedAt, fall back to readyAt, then cookingAt, then order time.
        ts: it.servedAt || it.readyAt || it.cookingAt
            || (o.createdAt?.toMillis ? o.createdAt.toMillis() : 0),
      });
    });
  });
  rows.sort((a, b) => b.ts - a.ts);

  const served = rows.filter((r) => r.status === "served").length;

  return (
    <div className="sheet-wrap" onMouseDown={onClose}>
      <div className="sheet sheet-wide" onMouseDown={(e) => e.stopPropagation()}>
        <header className="sheet-head">
          <div>
            <div className="eyebrow mono">HISTORY · TODAY{stationFilter ? ` · ${stationFilter.toUpperCase()}` : ""}</div>
            <h3>{served} of {rows.length} processed item{rows.length === 1 ? "" : "s"} served</h3>
          </div>
          <button className="icon-x" onClick={onClose}>×</button>
        </header>
        <div className="sheet-body">
          {rows.length === 0 ? (
            <div className="muted mono">No items processed yet today.</div>
          ) : (
            <table className="data-table">
              <thead><tr>
                <th>#</th><th>Table</th><th>Qty</th><th>Item</th>
                <th>Station</th><th>Status</th>
                <th>Cooked</th><th>Ready</th><th>Served</th>
                <th></th>
              </tr></thead>
              <tbody>
                {rows.map((r, i) => {
                  const PREV = { served: "ready", ready: "cooking", cooking: "new" };
                  const undoTarget = PREV[r.status];
                  return (
                    <tr key={i}>
                      <td><Mono>{r.order.shortId}</Mono></td>
                      <td><Mono>{r.order.table}</Mono></td>
                      <td><Mono>{r.item.qty}</Mono></td>
                      <td>
                        <div>{r.item.name}</div>
                        {r.item.mods && r.item.mods.length > 0 && <div className="muted mono" style={{ fontSize: 11 }}>{r.item.mods.join(" · ")}</div>}
                        {r.item.notes && <div className="mono" style={{ fontSize: 11 }}>📝 {r.item.notes}</div>}
                      </td>
                      <td><Mono>{(r.item.station || "—").toUpperCase()}</Mono></td>
                      <td><StatusPill status={r.status}>{r.status}</StatusPill></td>
                      <td><Mono className="muted">{fmtTime(r.cookingAt)}</Mono></td>
                      <td><Mono className="muted">{fmtTime(r.readyAt)}</Mono></td>
                      <td><Mono className={r.servedAt ? "" : "muted"}>{fmtTime(r.servedAt)}</Mono></td>
                      <td>
                        {undoTarget && (
                          <button
                            className="btn-ghost-sm"
                            onClick={() => {
                              if (confirm(`Undo? '${r.item.name}' will go back from ${r.status} to ${undoTarget}.`)) {
                                rewindItem(r.order.id, r.idx);
                              }
                            }}
                            title={`Rewind to ${undoTarget}`}
                          >↶ Undo</button>
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}
        </div>
      </div>
    </div>
  );
}

function KitchenTicket({ order, items, advanceItem, rewindItem }) {
  // Card is urgent if any (non-ready) item has crossed its station threshold.
  const urgent = items.some(({ it, status }) => status !== "ready" && isItemUrgent(it, order));
  // Pick a dominant station for the card accent: bar wins if any bar item is
  // still pending; otherwise kitchen.
  const dominantStation = items.some(({ it, status }) => it.station === "bar" && status !== "served")
    ? "bar"
    : "kitchen";
  // Show overall ticket status as the worst (earliest) status of its items.
  const order_status = items.reduce((acc, x) => {
    const rank = { new: 0, cooking: 1, ready: 2, served: 3 };
    return rank[x.status] < rank[acc] ? x.status : acc;
  }, "served");
  const allReady = items.every((x) => x.status === "ready");

  const notReady = items.filter((x) => x.status !== "ready");
  const onAllReady = () => {
    if (!notReady.length) return;
    advanceItem(order.id, notReady.map((x) => x.originalIdx), "ready");
  };

  const cardClasses = [
    "kds-card",
    "kds-" + order_status,
    "kds-card-station-" + dominantStation,
    allReady ? "kds-card-all-ready" : "",
    urgent ? "urgent" : "",
  ].filter(Boolean).join(" ");

  return (
    <article className={cardClasses} key={order._bump}>
      <header className="kds-card-head">
        <div className="kds-id">
          <Mono className="kds-short">{order.shortId}</Mono>
          <div className="muted mono">{order.table === "Bar" ? "Bar" : "Table " + order.table}</div>
        </div>
        <div className="kds-card-head-right">
          <Mono className={"kds-timer " + (urgent ? "alert" : "")}>{timeSince(order.createdAt)}</Mono>
          {notReady.length > 0 && (
            <button className="btn-advance-sm" onClick={onAllReady} title="Mark every item in this order as ready">
              All ready ✓
            </button>
          )}
        </div>
      </header>
      <div className="kds-customer mono">{order.customer}</div>

      <ul className="kds-items">
        {items.map(({ it, originalIdx, status }) => {
          const next = NEXT_STATUS[status];
          const onClick = (e) => {
            if (e.target.closest("button")) return;
            if (next) advanceItem(order.id, originalIdx, next);
          };
          const onContextMenu = (e) => {
            e.preventDefault();
            if (status !== "new") rewindItem(order.id, originalIdx);
          };
          return (
            <li
              key={originalIdx}
              className={"kds-item kds-item-" + status + " kds-item-station-" + (it.station || "kitchen") + " kds-item-clickable"}
              onClick={onClick}
              onContextMenu={onContextMenu}
              title="Click to advance · right-click to rewind"
            >
              <div className="kds-item-main">
                <Mono className="kds-qty">{it.qty}×</Mono>
                <div className="kds-item-body">
                  <div className="kds-name">{it.name}</div>
                  {it.mods && it.mods.length > 0 && <div className="kds-mods mono">{it.mods.join(" · ")}</div>}
                  {it.notes && <div className="kds-note mono">📝 {it.notes}</div>}
                </div>
              </div>
              <div className="kds-item-actions">
                <StatusPill status={status}>{status}</StatusPill>
                {next && (
                  <button className="btn-advance-sm" onClick={(e) => { e.stopPropagation(); advanceItem(order.id, originalIdx, next); }}>
                    {next === "cooking" ? "Cook" : next === "ready" ? "Ready" : "Served"}
                  </button>
                )}
              </div>
            </li>
          );
        })}
      </ul>
    </article>
  );
}

// Build a printable kitchen ticket DOM offscreen, print, then clean up.
function printKitchenTicket(order, station, items) {
  const settings = getPrinterSettings();
  const root = document.createElement("div");
  root.className = "printable ticket-print";
  root.innerHTML = `
    <div class="pr-center pr-brand">${escHtml(String(station).toUpperCase())} TICKET</div>
    <div class="pr-rule"></div>
    <div class="pr-short">#${escHtml(order.shortId)}</div>
    <div class="pr-center">${order.table === "Bar" ? "Bar" : "Table " + escHtml(order.table)} · ${escHtml(order.customer || "")}</div>
    <div class="pr-rule"></div>
    ${items.map((it) => `
      <div class="pr-line"><span class="qty">${escHtml(it.qty)}×</span>${escHtml(it.name)}${it.sku ? " (" + escHtml(it.sku) + ")" : ""}</div>
      ${it.mods && it.mods.length ? `<div class="pr-mod">${it.mods.map(escHtml).join(" · ")}</div>` : ""}
      ${it.notes ? `<div class="pr-note">* ${escHtml(it.notes)}</div>` : ""}
    `).join("")}
    <div class="pr-rule"></div>
    <div class="pr-center" style="font-size:10px">${new Date().toLocaleString("en-GB", { timeZone: "Asia/Jakarta" })} WIB</div>
  `;
  document.body.appendChild(root);
  const others = document.querySelectorAll(".printable");
  others.forEach((el) => { if (el !== root) el.dataset._wasPrintable = "1", el.classList.remove("printable"); });
  printPaper(settings.paperWidth);
  setTimeout(() => {
    others.forEach((el) => { if (el.dataset._wasPrintable === "1") { el.classList.add("printable"); delete el.dataset._wasPrintable; } });
    root.remove();
  }, 800);
}

Object.assign(window, { KitchenScreen, printKitchenTicket, itemStatusOf, HistorySheet });
