/* Small helpers local to the split lane. Nothing here rescues a step a person could not do —
   the evaluate-click is only used where a full-screen sibling scrim (`m2-dock-scrim`) makes
   Playwright's hit-test land on the overlay, which a real thumb does not suffer from. */
import { DWELL, arriveAsDiner } from "../lib-witness.mjs";

export async function arrive(page, rid, table) {
  const seen = await arriveAsDiner(page, rid, table, "mosaic_v2");
  const gateNo = page.locator('[data-testid="m2-dietary-gate-no"]').first();
  if (await gateNo.count()) {
    seen.push("dietary gate (testid)");
    await gateNo.evaluate(e => e.click()).catch(() => {});
    await page.waitForTimeout(DWELL);
  }
  return seen;
}

/** Tap something, falling back to a bubbling native click when the dock scrim intercepts. */
export async function tap(page, locator, timeout = 12000) {
  try { await locator.click({ timeout }); }
  catch { await locator.evaluate(e => e.click()); }
  await page.waitForTimeout(2500);
}

/** Who does this diner think is at the table? Names + counts straight off the cart chips. */
export async function whoIsHere(page) {
  return page.evaluate(() => [...document.querySelectorAll('[data-testid^="cart-scope-chip-"]')]
    .map(e => ({ testid: e.getAttribute("data-testid"),
                 text: (e.textContent || "").replace(/\s+/g, " ").trim() })));
}

/** Every settle-ish handle currently on screen, so I can say what I was offered, not guess. */
export async function settleControls(page) {
  return page.evaluate(() => [...new Set([...document.querySelectorAll("[data-testid]")]
    .map(e => e.getAttribute("data-testid"))
    .filter(x => /split|cover|payhow|settle|pay|charge|share|invite|tip|gratuit/i.test(x)))].sort());
}

/** Open the running-order sheet (only exists once the cart has something in it). */
export async function openSheet(page) {
  const t = page.locator('[data-testid="m2-dock-cart"], [data-testid="m2-view-order"]').first();
  if (!(await t.count())) return false;
  await tap(page, t);
  await page.waitForTimeout(DWELL);
  return true;
}

/** ONE diner adds a dish and actually SENDS it, then proves the order landed.
 *
 *  This primitive did not exist, and its absence is why two journeys were parked as blocked.
 *  Both assumed the second diner had ordered when she never had: the sheet was opened, no
 *  split or cover options appeared, and that was written up as the app having nothing to
 *  offer. The app was right - there genuinely was nothing to split. The harness was wrong.
 *
 *  So this returns only when the order is CONFIRMED on the ledger, and throws otherwise. A
 *  caller can no longer proceed believing a diner ordered when they did not.
 */
export async function placeOwnOrder(page, who = "this diner") {
  const tile = page.locator('[data-testid^="m2-tile-"]').first();
  if (!(await tile.count())) throw new Error(`${who}: the menu has no dishes to order.`);
  await tile.evaluate(e => e.click());
  await page.waitForTimeout(DWELL);

  const add = page.locator('[data-testid="composition-add"]').first();
  if (!(await add.count())) throw new Error(`${who}: opened a dish but found no way to add it.`);
  await tap(page, add);

  const count = (await page.locator('[data-testid="m2-dock-cart-count"]').first()
                   .innerText().catch(() => "")).trim();
  if (!count || count === "0") throw new Error(`${who}: nothing landed in the cart.`);

  const trig = page.locator('[data-testid="m2-dock-trigger"]').first();
  if (await trig.count()) { await tap(page, trig); }
  const cart = page.locator('[data-testid="m2-dock-cart"]').first();
  if (await cart.count()) { await tap(page, cart); }

  const btn = page.locator('[data-testid="order-now-btn"]').first();
  if (!(await btn.count()))
    throw new Error(`${who}: there is no Place order button, so this order was never sent.`);
  const label = (await btn.innerText()).replace(/\s+/g, " ").trim();
  await tap(page, btn);
  await page.waitForTimeout(DWELL * 2);

  // PROVE it landed. "I pressed the button" is not the same claim as "an order exists".
  const tab = page.locator('[data-testid="m2-cart-tab-table"]').first();
  if (await tab.count()) { await tap(page, tab); await page.waitForTimeout(2500); }
  const landed = await page.evaluate(() => {
    const badge = document.querySelector('[data-testid="order-status-badge"]');
    const cancels = document.querySelectorAll('[data-testid^="cancel-item-"]').length;
    const sheet = document.querySelector('[data-testid="cart-sheet"]');
    return { badge: (badge?.innerText || "").trim(),
             cancels,
             sheet: (sheet?.innerText || "").replace(/\s+/g, " ").trim().slice(0, 200) };
  });
  const ok = landed.cancels > 0 || /ordered|kitchen|on its way|served/i.test(landed.badge);
  if (!ok)
    throw new Error(`${who}: pressed "${label}" but no order appears on the table ledger `
      + `(badge "${landed.badge}", ${landed.cancels} cancellable lines). The order was NOT sent, `
      + `so anything that depends on it would be testing an empty table.`);
  return { label, badge: landed.badge, lines: landed.cancels, sheet: landed.sheet };
}
