// Blyzr — app shell with persistent agent panel + screen routing.

const { useState: uS, useEffect: uE, useMemo: uM, useRef: uR } = React;

let MSG_ID = 1;
const nid = () => `m${MSG_ID++}`;

const App = () => {
  /* screen routing */
  const [screen, setScreen] = uS({ name: 'welcome' });
  const goto = (next) => setScreen(typeof next === 'string' ? { name: next } : next);

  /* basket state */
  const [basket, setBasket] = uS(new Set());
  const [qty, setQty] = uS({});

  const addToBasket = (id, opts = {}) => {
    setBasket((b) => {
      if (b.has(id)) return b;
      const n = new Set(b); n.add(id);
      return n;
    });
    setQty((q) => ({ ...q, [id]: (q[id] || 0) + 1 }));
  };
  const removeFromBasket = (id) => {
    setBasket((b) => { const n = new Set(b); n.delete(id); return n; });
    setQty((q) => { const n = { ...q }; delete n[id]; return n; });
  };
  const setBasketQty = (id, q) => {
    if (q <= 0) return removeFromBasket(id);
    setQty((cur) => ({ ...cur, [id]: q }));
  };

  /* pantry — what we already have (so we don't auto-add) */
  const pantrySet = uM(() => new Set(BLYZR.pantry.filter((it) => it.level > 0.2).map((it) => it.id)), []);

  /* messages */
  const [messages, setMessages] = uS([
    { id: nid(), role: 'agent', text: "Evening, Maya. Want me to plan dinner or build the weekly basket? You can also drop a fridge photo." , chips: [
      { label: 'Plan dinner', send: 'what should i make tonight' },
      { label: 'Scan my fridge', send: 'scan my fridge' },
      { label: 'Weekly basket', accent: true, send: 'weekly basket' },
    ]},
  ]);
  const [typing, setTyping] = uS(false);
  const [listening, setListening] = uS(false);
  const [agentOpen, setAgentOpen] = uS(false); // chat stays minimized by default
  const basketTotal = Array.from(basket).reduce((s, id) => s + BLYZR.productById[id].price * (qty[id] || 1), 0);

  const send = (text) => {
    setAgentOpen(true); // surface the conversation when the user talks to Blyzr
    const userId = nid();
    setMessages((ms) => [...ms, { id: userId, role: 'user', text }]);
    setTyping(true);

    setTimeout(() => {
      const { reply, action, followUp } = think(text);
      setTyping(false);
      const agentMsg = { id: nid(), role: 'agent', text: reply, chips: followUp?.chips };
      setMessages((ms) => [...ms, agentMsg]);

      if (action) {
        // Stagger so the user sees the response before the canvas swaps
        setTimeout(() => {
          if (action.screen === 'recipe') {
            goto({ name: 'recipe', recipeId: action.recipeId, autoAdd: action.autoAdd });
          } else if (action.screen === 'fridge' && action.scanned) {
            goto({ name: 'fridge', scanned: true });
          } else if (action.screen === 'basket' && action.preset) {
            // Pre-fill weekly / restock
            if (action.preset === 'weekly') {
              ['p-tom','p-bas','p-moz','p-pas','p-bread','p-milk','p-coff','p-spi','p-eggs','p-avo'].forEach((id) => addToBasket(id));
            } else if (action.preset === 'restock') {
              ['p-eggs','p-milk','p-onn','p-coff'].forEach((id) => addToBasket(id));
            }
            goto({ name: 'basket', preset: action.preset });
          } else {
            goto({ name: action.screen });
          }
        }, 350);
      }
    }, 700 + Math.random() * 400);
  };

  const handleMic = () => {
    setListening((l) => !l);
    if (!listening) {
      // simulate transcript -> send
      setTimeout(() => {
        setListening(false);
        send("I want something with tomatoes from my fridge");
      }, 2400);
    }
  };

  const handleAttach = () => {
    goto({ name: 'fridge' });
    send("Here's my fridge photo");
  };

  /* render screen */
  const renderScreen = () => {
    switch (screen.name) {
      case 'welcome':
        return <Welcome onSend={send} listening={listening}/>;
      case 'fridge':
        return <FridgeScan scanned={screen.scanned} onSend={send} onAdd={addToBasket} basket={basket}/>;
      case 'recipes':
        return <Recipes onSend={send} onAdd={addToBasket} basket={basket} onOpenRecipe={(id) => goto({ name: 'recipe', recipeId: id })}/>;
      case 'recipe': {
        const rec = BLYZR.recipes.find((x) => x.id === screen.recipeId);
        if (rec && rec.steps) {
          return <RecipeArticle recipeId={screen.recipeId} onAdd={addToBasket} basket={basket} quantities={qty} onQty={setBasketQty} onBack={() => goto('recipes')} onSend={send} onGoBasket={() => goto('basket')}/>;
        }
        return <RecipeDetail recipeId={screen.recipeId} autoAdd={screen.autoAdd} onAdd={addToBasket} basket={basket} pantrySet={pantrySet} onSend={send} onBack={() => goto('recipes')} onGoBasket={() => goto('basket')}/>;
      }
      case 'basket':
        return <Basket basket={basket} quantities={qty} onAdd={addToBasket} onRemove={removeFromBasket} onQty={setBasketQty} onCheckout={() => goto('checkout')} onSend={send} preset={screen.preset}/>;
      case 'checkout':
        return <Checkout basket={basket} quantities={qty} onPlace={() => goto('order-placed')} onBack={() => goto('basket')}/>;
      case 'order-placed':
        return <OrderPlaced onContinue={() => goto('tracking')}/>;
      case 'tracking':
        return <Tracking onSend={send}/>;
      case 'pantry':
        return <Pantry onAdd={addToBasket} basket={basket} onSend={send}/>;
      case 'catalog':
        return <Catalog onOpenProduct={(id) => goto({ name: 'product', productId: id })} onAdd={addToBasket} basket={basket} onSend={send}/>;
      case 'product':
        return <ProductDetail productId={screen.productId} onAdd={addToBasket} onQty={setBasketQty} quantities={qty} basket={basket} onBack={() => goto('catalog')} onOpenProduct={(id) => goto({ name: 'product', productId: id })} onSend={send} onGoBasket={() => goto('basket')}/>;
      case 'business':
        return <Business onSend={send} onHome={() => goto('welcome')}/>;
      case 'cafe':
        return <Cafe onSend={send} onHome={() => goto('welcome')}/>;
      case 'legal':
        return <Legal tab={screen.tab} onHome={() => goto('welcome')}/>;
      default:
        return <Welcome onSend={send} listening={listening}/>;
    }
  };

  const navItems = [
    { id: 'welcome',  icon: 'home',   label: 'Home' },
    { id: 'recipes',  icon: 'recipe', label: 'Ideas' },
    { id: 'catalog',  icon: 'grid',   label: 'Shop' },
    { id: 'fridge',   icon: 'camera', label: 'Scan' },
    { id: 'basket',   icon: 'basket', label: 'Basket' },
    { id: 'tracking', icon: 'truck',  label: 'Orders' },
    { id: 'pantry',   icon: 'pantry', label: 'Pantry' },
  ];

  return (
    <div className="app">
      {/* LEFT RAIL */}
      <nav className="rail">
        <button className="rail-logo" title="Home" onClick={() => goto('welcome')}>b</button>
        {navItems.map((n) => (
          <button
            key={n.id}
            className={`rail-btn ${screen.name === n.id || (n.id === 'recipes' && screen.name === 'recipe') || (n.id === 'catalog' && screen.name === 'product') ? 'active' : ''}`}
            onClick={() => goto(n.id)}
            title={n.label}
          >
            {Icon[n.icon]({})}
          </button>
        ))}
        <div className="rail-spacer"/>
        <div className="rail-avatar" title="Maya Okafor">M</div>
      </nav>

      {/* MAIN CANVAS */}
      <main className="canvas">
        <div className="canvas-top">
          <button className="brand" onClick={() => goto('welcome')} title="Home">
            <span className="brand-orb"><OrbMini/></span>
            <span className="brand-word">blyzr</span>
          </button>
          <div className="canvas-top-actions">
            <button className={`top-link ${screen.name === 'business' ? 'active' : ''}`} onClick={() => goto('business')}>For business</button>
            <button className={`top-link ${screen.name === 'cafe' ? 'active' : ''}`} onClick={() => goto('cafe')}>Café</button>
            {basket.size > 0 && (
              <button className="basket-pill" onClick={() => goto('basket')} title="Basket">
                <Icon.basket style={{ width: 16, height: 16 }}/>
                <span className="mono">{basket.size}</span>
                <span className="basket-pill-total mono">${basketTotal.toFixed(2)}</span>
              </button>
            )}
            <button className="ask-btn" onClick={() => setAgentOpen(true)}>
              <span className="ask-orb"><OrbMini/></span>
              <span className="ask-label">Ask blyzr</span>
            </button>
          </div>
        </div>
        <div className="canvas-inner">
          {renderScreen()}
          <footer className="app-footer">
            <div className="foot-left">
              <span className="foot-orb"><OrbMini/></span>
              <span>© blyzr 2026</span>
              <span className="foot-tag">a quieter way to shop</span>
            </div>
            <div className="foot-links">
              <button className="foot-link" onClick={() => goto({ name: 'legal', tab: 'privacy' })}>Privacy</button>
              <button className="foot-link" onClick={() => goto({ name: 'legal', tab: 'terms' })}>Terms</button>
              <button className="foot-link" onClick={() => goto({ name: 'legal', tab: 'cookies' })}>Cookies</button>
              <a href="Blyzr Brand Guidelines.html" target="_blank" rel="noopener" className="foot-link">
                Design system
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" style={{ width: 11, height: 11 }}><path d="M7 17 17 7M9 7h8v8"/></svg>
              </a>
            </div>
          </footer>
        </div>
      </main>

      {/* AGENT — overlay, minimized by default */}
      {agentOpen && <div className="agent-scrim show" onClick={() => setAgentOpen(false)}/>}
      <AgentPanel
        messages={messages}
        typing={typing}
        onSend={send}
        listening={listening}
        onMic={handleMic}
        onAttach={handleAttach}
        open={agentOpen}
        onClose={() => setAgentOpen(false)}
      />
    </div>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
