function App() {
  const [query, setQuery] = React.useState("");
  const [index, setIndex] = React.useState(0);
  const [filters, setFilters] = React.useState({});
  const [sort, setSort] = React.useState("distance");
  const [dragProgress, setDragProgress] = React.useState(0);
  const [openR, setOpenR] = React.useState(null);
  const [rect, setRect] = React.useState(null);
  const [carts, setCarts] = React.useState({});
  const [armed, setArmed] = React.useState(null);
  const [account, setAccount] = React.useState(false);
  const [addressOpen, setAddressOpen] = React.useState(false);
  const [addresses, setAddresses] = React.useState(ADDRESSES);
  const [botOpen, setBotOpen] = React.useState(false);
  const [botDismissed, setBotDismissed] = React.useState(false);
  const [searchOpen, setSearchOpen] = React.useState(false);
  const [searchOrigin, setSearchOrigin] = React.useState(null);
  const [order, setOrder] = React.useState(null);
  const [subs, setSubs] = React.useState([]); // assinaturas da Feira: {name, cadence, next, status}
  const [counter, setCounter] = React.useState(false); // paying at the balcão: the chip steps aside

  const shell = React.useRef(null);
  const cart = openR ? (carts[openR.name] || []) : [];

  const addItem = (d) => setCarts(c => {
    const list = c[openR.name] || [];
    const has = list.some(i => i.name === d.name);
    return { ...c, [openR.name]: has ? list.map(i => i.name === d.name ? { ...i, qty: i.qty + 1 } : i) : [...list, { ...d, qty: 1 }] };
  });
  const setQty = (name, n) => setCarts(c => ({
    ...c,
    [openR.name]: n <= 0 ? (c[openR.name] || []).filter(i => i.name !== name) : (c[openR.name] || []).map(i => i.name === name ? { ...i, qty: n } : i)
  }));

  const openRestaurant = (r, domRect) => {
    const base = shell.current ? shell.current.getBoundingClientRect() : { top: 0, left: 0 };
    setRect({ top: domRect.top - base.top, left: domRect.left - base.left, width: domRect.width, height: domRect.height });
    setOpenR(r);
  };

  React.useEffect(() => {
    if (!order || order.step >= 3) return;
    const t = setTimeout(() => setOrder(o => ({ ...o, step: o.step + 1, eta: ["28 min", "22 min", "12 min", "Entregue"][o.step + 1] })), 3000);
    return () => clearTimeout(t);
  }, [order]);

  return (
    <div ref={shell} className="beco-dark beco-shell"
      onClick={() => { if (armed) setArmed(null); }}
      style={{
        position: "relative", width: 390, height: 844, overflow: "hidden",
        background: "var(--black)", border: "1px solid var(--ink-700)", borderRadius: "var(--radius-xl)",
        color: "var(--white)", fontFamily: "var(--font-body)"
      }}>

      <div style={{ position: "absolute", top: 48, left: 16, right: 168, zIndex: 50 }}>
        <SearchPill value={query} onChange={setQuery} filters={filters} onFilters={setFilters} sort={sort} onSort={setSort}
          botDismissed={botDismissed} onRestoreBot={() => setBotDismissed(false)}
          onOpenSearch={(o) => { setSearchOrigin(o); setSearchOpen(true); }} />
      </div>

      <BotBubble open={botOpen} onOpen={() => setBotOpen(true)}
        dismissed={botDismissed} onDismiss={() => setBotDismissed(true)} />

      {/* Invisible scrim: the dismissing tap closes the open slab and nothing else — it never
          reaches the feed behind it. Dismiss on click, not pointerdown: React flushes discrete
          events synchronously, so closing on pointerdown would unmount the scrim before pointerup
          and the click would retarget to whatever is now under the cursor. pointerdown/up are
          swallowed without state changes so FeedView's drag never sees the gesture. */}
      {(addressOpen || botOpen) && (
        <div onPointerDown={e => { e.preventDefault(); e.stopPropagation(); }}
          onPointerUp={e => { e.preventDefault(); e.stopPropagation(); }}
          onClick={e => {
            e.preventDefault(); e.stopPropagation();
            setAddressOpen(false); setBotOpen(false);
          }}
          style={{ position: "absolute", inset: 0, zIndex: 310, background: "transparent", touchAction: "none" }} />
      )}

      <FeedView
        query={query} filters={filters} sort={sort} categories={CATEGORIES} index={index} setIndex={setIndex}
        dragProgress={dragProgress} setDragProgress={setDragProgress}
        onOpenRestaurant={openRestaurant} />

      <CartBubbles carts={carts} armed={armed} onArm={setArmed}
        onOpen={(k) => openRestaurant(PLACES.find(r => r.name === k), { top: 700, left: 300, width: 58, height: 58 })}
        onClose={(k) => { setCarts(c => { const n = { ...c }; delete n[k]; return n; }); setArmed(null); }} />

      <CategoryRail items={CATEGORIES} index={index} onIndex={setIndex}
        active={Boolean(dragProgress)} progress={dragProgress} />

      {openR && (
        <RestaurantView
          restaurant={openR} rect={rect} cart={cart}
          onAdd={addItem} onQty={setQty}
          onClose={() => { setCounter(false); setOpenR(null); }}
          onCheckout={setCounter}
          onConfirm={(info) => {
            if (info && info.sub && openR.producer) {
              setSubs(s => s.some(x => x.name === openR.name) ? s : [...s, {
                name: openR.name, cadence: openR.producer.sub.label,
                next: openR.producer.next, status: "ativa"
              }]);
            }
            setOrder({ id: "4821", where: openR.name, step: 0, eta: "28 min" });
            setCarts(c => { const n = { ...c }; delete n[openR.name]; return n; });
            setCounter(false); setOpenR(null); setAccount(true);
          }} />
      )}

      <div style={{ opacity: counter ? 0 : 1, pointerEvents: counter ? "none" : "auto", transition: "opacity 220ms var(--ease-out)" }}>
      <AddressRail addresses={addresses} open={addressOpen} restaurant={openR}
        onOpen={() => setAddressOpen(true)} onClose={() => setAddressOpen(false)}
        onPick={(a) => setAddresses(list => [a, ...list.filter(x => x.line !== a.line)])}
        onSave={(next, wasLine) => setAddresses(list => wasLine
          ? list.map(x => x.line === wasLine ? { ...x, ...next } : x)
          : [...list, next])}
        onDelete={(line) => setAddresses(list => list.length > 1 ? list.filter(x => x.line !== line) : list)} />
      </div>

      <AccountPanel open={account} name="Rafa" activeOrder={order} onClose={() => setAccount(false)}
        subs={subs}
        onPauseSub={(n) => setSubs(s => s.map(x => x.name === n ? { ...x, status: x.status === "pausada" ? "ativa" : "pausada" } : x))}
        onSkipSub={(n) => setSubs(s => s.map(x => x.name === n ? { ...x, status: x.status === "próxima pulada" ? "ativa" : "próxima pulada" } : x))}
        onCancelSub={(n) => setSubs(s => s.filter(x => x.name !== n))} />
      <SearchOverlay open={searchOpen} origin={searchOrigin} value={query} onChange={setQuery}
        onClose={() => setSearchOpen(false)}
        onPickRestaurant={(r) => {
          setSearchOpen(false);
          openRestaurant(r, { top: 300, left: 20, width: 350, height: 120 });
        }} />
      <BotPanel open={botOpen} onClose={() => setBotOpen(false)} />
      <StatusBar name="Rafa" accountOpen={account} onOpenAccount={() => setAccount(a => !a)} />
    </div>
  );
}
Object.assign(window, { App });
