// ============ 玄境 root ============
function CartDrawer({ open, onClose, items, setItems, lang }) {
  const en = lang === 'en';
  const total = items.reduce((s, it) => s + it.price * it.qty, 0);
  const remove = (i) => setItems(items.filter((_, idx) => idx !== i));
  const [stage, setStage] = useState('cart'); // cart | confirm | done
  const [order, setOrder] = useState('');
  const [failed, setFailed] = useState(false);
  const [placing, setPlacing] = useState(false);
  useEffect(() => { if (!open) { const t = setTimeout(() => { setStage('cart'); setFailed(false); setOrder(''); }, 400); return () => clearTimeout(t); } }, [open]);
  const placeOrder = async () => {
    setPlacing(true);
    try {
      // Stripe 结账：只上送 SKU id + 数量，价格由服务端 CATALOG 复算
      const res = await window.api('/api/checkout', { kind: 'cart', items: items.map(it => ({ id: it.id, qty: it.qty })) });
      location.href = res.url; // 成功页 /thanks/?ref=… 由 Stripe 回跳
    } catch (e) {
      // 支付通道异常：回退旧记录单（不收款，微信直连），再不行如实报错
      try {
        const res = await window.api('/api/order', { items });
        setOrder(res.ref);
        setFailed(false);
      } catch (e2) {
        setOrder('');
        setFailed(true);
      }
      setPlacing(false);
      setStage('done');
    }
  };
  const sf = en ? 'var(--font-en-serif)' : 'var(--font-serif)';
  return (
    <>
      <div className={`cart-overlay ${open ? 'open' : ''}`} onClick={onClose} />
      <aside className={`cart-drawer ${open ? 'open' : ''}`}>
        <div className="cart-head">
          <h3 style={en ? { fontFamily: 'var(--font-en-serif)', fontWeight: 700, letterSpacing: '.02em' } : null}>{stage === 'done' ? (failed ? (en ? 'Not Sent' : '未能送出') : (en ? 'Bond Sealed' : '結緣既成')) : (en ? 'Inquire · Satchel' : '問道 · 緣囊')}</h3>
          <button onClick={onClose} style={{ color: '#E9DEC2', fontSize: 26, lineHeight: 1 }}>✕</button>
        </div>

        {stage === 'cart' && (
          <>
            <div className="cart-body">
              {items.length === 0 && <div className="cart-empty" style={{ fontFamily: sf }}>{en ? <>Your satchel is empty<br />Choose an art and form a bond with the Master.</> : <>緣囊空空<br />擇一數術，與道長結緣。</>}</div>}
              {items.map((it, i) => (
                <div key={i} className="cart-item">
                  <div style={{ flex: 1 }}>
                    <div className="ci-t" style={{ fontFamily: sf }}>{it.title}</div>
                    <div className="ci-o" style={{ fontFamily: sf }}>{it.option}　× {it.qty}</div>
                  </div>
                  <div style={{ textAlign: 'right' }}>
                    <div style={{ fontFamily: sf, color: 'var(--gold-text)', fontSize: 17 }}>{window.usd(it.price * it.qty)}</div>
                    <button onClick={() => remove(i)} style={{ fontFamily: sf, fontSize: 13, color: '#8E815F', marginTop: 6, textDecoration: 'underline' }}>{en ? 'Remove' : '移除'}</button>
                  </div>
                </div>
              ))}
            </div>
            {items.length > 0 && (
              <div className="cart-foot">
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 18 }}>
                  <span style={{ fontFamily: sf, color: '#C7B98F', fontSize: 17 }}>{en ? 'Total fee' : '潤金合計'}</span>
                  <span style={{ fontFamily: sf, color: 'var(--gold-text)', fontSize: 26, fontWeight: 700 }}>{window.usd(total)}</span>
                </div>
                <button className="btn-cart" onClick={() => setStage('confirm')} style={{ display: 'block', textAlign: 'center', width: '100%' }}>{en ? 'Proceed · Checkout' : '前往結緣 · Checkout'}</button>
              </div>
            )}
          </>
        )}

        {stage === 'confirm' && (
          <>
            <div className="cart-body">
              <div style={{ fontFamily: sf, fontStyle: 'italic', color: '#9E9170', marginBottom: 18, lineHeight: 1.8 }}>{en ? 'Please review the arts you’ve requested; once confirmed, the Master will reach out within a day.' : '請核對所求數術，確認後道長將於一日內親赴結緣。'}</div>
              {items.map((it, i) => (
                <div key={i} className="cart-item">
                  <div style={{ flex: 1 }}>
                    <div className="ci-t" style={{ fontFamily: sf }}>{it.title}</div>
                    <div className="ci-o" style={{ fontFamily: sf }}>{it.option}　× {it.qty}</div>
                  </div>
                  <div style={{ fontFamily: sf, color: 'var(--gold-text)', fontSize: 17 }}>{window.usd(it.price * it.qty)}</div>
                </div>
              ))}
              <div style={{ marginTop: 22, fontFamily: sf, color: '#C7B98F', fontSize: 14, lineHeight: 2 }}>
                <div>{en ? 'Title' : '緣主稱謂'}　<span style={{ color: '#8E815F' }}>{en ? 'Devotee' : '善信'}</span></div>
                <div>{en ? 'Session' : '結緣方式'}　<span style={{ color: '#8E815F' }}>{en ? 'WeChat / IG / WhatsApp' : '微信 / IG / WhatsApp'}</span></div>
                <div>{en ? 'Payment' : '支付方式'}　<span style={{ color: '#8E815F' }}>{en ? 'Card · Alipay · WeChat Pay — Stripe secure checkout' : 'Stripe 安全支付 · 銀行卡 / 支付寶 / 微信支付'}</span></div>
              </div>
            </div>
            <div className="cart-foot">
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 18 }}>
                <span style={{ fontFamily: sf, color: '#C7B98F', fontSize: 17 }}>{en ? 'Amount due' : '應付潤金'}</span>
                <span style={{ fontFamily: sf, color: 'var(--gold-text)', fontSize: 26, fontWeight: 700 }}>{window.usd(total)}</span>
              </div>
              <button className="btn-cart" onClick={placeOrder} disabled={placing} style={{ width: '100%', ...(placing ? { opacity: .6 } : null) }}>{placing ? (en ? 'Heading to checkout…' : '前往支付中…') : (en ? 'Confirm · Proceed to Payment' : '確認結緣 · 前往支付')}</button>
              <button onClick={() => setStage('cart')} style={{ width: '100%', marginTop: 12, fontFamily: sf, fontSize: 14, color: '#8E815F', textDecoration: 'underline' }}>{en ? 'Back to satchel' : '返回緣囊'}</button>
            </div>
          </>
        )}

        {stage === 'done' && !failed && (
          <div className="cart-body" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: '40px 28px' }}>
            <div style={{ fontSize: 46, color: 'var(--gold-text)', marginBottom: 10 }}>✦</div>
            <div style={{ fontFamily: en ? 'var(--font-en-serif)' : 'var(--font-brush)', fontWeight: en ? 700 : 400, fontSize: en ? 26 : 30, color: '#F2E6C9', marginBottom: 14 }}>{en ? 'Ritual Order Placed' : '法事訂單已成'}</div>
            <p style={{ fontFamily: sf, fontStyle: 'italic', color: '#C7B98F', lineHeight: 2, marginBottom: 22 }}>{en ? <>The Master has received your request<br />and will divine it in person within twenty-four hours.</> : <>道長已收悉緣主所求，<br />將於二十四時辰內親為推演。</>}</p>
            <div style={{ border: '1px solid rgba(226,176,68,.4)', padding: '14px 26px', fontFamily: 'var(--font-en-serif)', fontSize: 18, color: 'var(--gold-text)', letterSpacing: '.08em', marginBottom: 10 }}>{en ? 'Order No.' : '訂單編號'}　{order}</div>
            <p style={{ fontFamily: sf, fontSize: 13, color: '#8E815F', marginBottom: 26 }}>{en ? <>Add WeChat <WeChatId /> and quote this number to continue.</> : <>敬加微信 <WeChatId /> 報此編號，以續前緣。</>}</p>
            <button className="btn-cart" onClick={() => { setItems([]); onClose(); }} style={{ width: '100%' }}>{en ? 'Amen · Keep browsing' : '善哉 · 繼續瀏覽'}</button>
          </div>
        )}

        {stage === 'done' && failed && (
          <div className="cart-body" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: '40px 28px' }}>
            <div style={{ fontSize: 46, color: 'var(--red-bright)', marginBottom: 10 }}>⚠</div>
            <div style={{ fontFamily: en ? 'var(--font-en-serif)' : 'var(--font-brush)', fontWeight: en ? 700 : 400, fontSize: en ? 24 : 28, color: '#F2E6C9', marginBottom: 14 }}>{en ? 'Order Not Sent' : '訂單未能送出'}</div>
            <p style={{ fontFamily: sf, fontStyle: 'italic', color: '#C7B98F', lineHeight: 2, marginBottom: 22 }}>{en ? <>A network issue interrupted the order.<br />Nothing was saved — please add the Master on WeChat to place it directly.</> : <>網絡異常，訂單未能記錄。<br />請直接加道長微信下單，以免遺漏。</>}</p>
            <p style={{ fontFamily: sf, fontSize: 13, color: '#8E815F', marginBottom: 26 }}>{en ? <>WeChat <WeChatId /></> : <>道長微信 <WeChatId /></>}</p>
            <button className="btn-cart" onClick={() => setStage('confirm')} style={{ width: '100%', marginBottom: 12 }}>{en ? 'Try Again' : '重試一次'}</button>
            <button onClick={() => { onClose(); }} style={{ width: '100%', fontFamily: sf, fontSize: 14, color: '#8E815F', textDecoration: 'underline' }}>{en ? 'Close' : '關閉'}</button>
          </div>
        )}
      </aside>
    </>
  );
}

// ============ 页面壳工厂:Nav + 购物车 + toast + 语言,子页只给 section 组合 ============
function makePageApp(renderSections) {
  return function App() {
    // 语言:URL 定语言(__PAGE_LANG 由静态壳注入);无壳页(旧首页行为)回退 localStorage
    const [lang] = useState(() => window.__PAGE_LANG || localStorage.getItem('xj_lang') || 'sc');
    const changeLang = (next) => {
      if (next === lang) return;
      localStorage.setItem('xj_lang', next);
      const url = window.__LANG_URLS && window.__LANG_URLS[next];
      if (url) { location.href = url; } else { location.reload(); }
    };
    useEffect(() => { if (lang === 'sc') window.__t2sEnable(); }, []);
    const [cartOpen, setCartOpen] = useState(false);
    const [items, setItems] = useState([]);
    const [toastMsg, setToastMsg] = useState('');
    const toastTimer = useRef(null);
    const toast = (msg) => {
      setToastMsg(msg);
      clearTimeout(toastTimer.current);
      toastTimer.current = setTimeout(() => setToastMsg(''), 2600);
    };
    const addToCart = (item) => {
      setItems((prev) => {
        const ex = prev.findIndex((p) => p.id === item.id);
        if (ex >= 0) { const n = [...prev]; n[ex] = { ...n[ex], qty: n[ex].qty + item.qty }; return n; }
        return [...prev, item];
      });
      toast(lang === 'en' ? `Added to satchel · ${item.title} ✦` : `已納入緣囊 · ${item.title} ✦`);
    };
    const count = items.reduce((s, it) => s + it.qty, 0);
    return (
      <window.LangContext.Provider value={lang}>
        <Nav cartCount={count} onCart={() => setCartOpen(true)} lang={lang} setLang={changeLang} />
        {renderSections({ addToCart, toast })}
        <CartDrawer open={cartOpen} onClose={() => setCartOpen(false)} items={items} setItems={setItems} lang={lang} />
        <div className={`toast ${toastMsg ? 'show' : ''}`}>{toastMsg}</div>
      </window.LangContext.Provider>
    );
  };
}
window.makePageApp = makePageApp;
