// lvpai-flows.jsx — 支付 / 单组照片页 / 案例详情 / 消息 / 客服 / 绑卡帮助
const { LV_T: F_T, Icon: FIcon, Photo: FPhoto, Btn: FBtn, Card: FCard, Eyebrow: FEye,
  Price: FPrice, FreeTag: FFree, Divider: FDiv, WeChatNav: FNav, Screen: FScreen,
  Sheet: FSheet, StatusChip: FChip } = window;

// ── Payment sheet ────────────────────────────────────────────────
function PaymentSheet({ open, onClose, item, onPaid }) {
  const T = F_T;
  const [paying, setPaying] = React.useState(false);
  const [done, setDone] = React.useState(false);
  React.useEffect(() => { if (open) { setPaying(false); setDone(false); } }, [open]);
  if (!item) return null;
  const pay = () => {
    setPaying(true);
    setTimeout(() => { setPaying(false); setDone(true); setTimeout(() => { onPaid && onPaid(); }, 850); }, 900);
  };
  return (
    <FSheet open={open} onClose={onClose} title={done ? '' : '确认支付'} maxH="62%">
      {done ? (
        <div style={{ padding: '12px 0 30px', textAlign: 'center' }}>
          <div style={{ width: 64, height: 64, borderRadius: 999, background: '#2F6F63', margin: '0 auto 18px', display: 'flex', alignItems: 'center', justifyContent: 'center', animation: 'lvPop .35s cubic-bezier(.2,1.2,.4,1)' }}>
            <FIcon name="check" size={34} color="#fff" stroke={2.4} />
          </div>
          <div style={{ fontFamily: T.sans, fontSize: 18, fontWeight: 700, color: T.ink }}>支付成功</div>
          <div style={{ fontFamily: T.sans, fontSize: 13, color: T.muted, marginTop: 6 }}>正在为你创建订单…</div>
        </div>
      ) : (
        <div style={{ paddingBottom: 8 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 0' }}>
            <div style={{ width: 52, height: 52, borderRadius: 7, overflow: 'hidden', flexShrink: 0 }}><FPhoto src={item.src} pos={item.src ? 'center' : 'center 32%'} seed={window.lvSeed(item.name || 'x')} /></div>
            <div style={{ flex: 1 }}>
              <div style={{ fontFamily: T.sans, fontSize: 15, fontWeight: 700, color: T.ink }}>{item.name}</div>
              {item.sub && <div style={{ fontFamily: T.sans, fontSize: 12, color: T.muted, marginTop: 3 }}>{item.sub}</div>}
            </div>
            <FPrice value={item.amount} size={20} />
          </div>
          <FDiv style={{ background: T.line }} />
          <div style={{ padding: '16px 0' }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '10px 0' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <div style={{ width: 26, height: 26, borderRadius: 5, background: '#1AAD19', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <FIcon name="chat" size={16} color="#fff" stroke={0} fill="#fff" />
                </div>
                <span style={{ fontFamily: T.sans, fontSize: 14, fontWeight: 600, color: T.ink }}>微信支付</span>
              </div>
              <div style={{ width: 20, height: 20, borderRadius: 999, background: T.ink, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <FIcon name="checkSm" size={13} color="#fff" stroke={2.6} />
              </div>
            </div>
          </div>
          <FBtn kind="primary" full size="lg" onClick={pay} disabled={paying} style={{ marginTop: 4 }}>
            {paying ? '支付中…' : <span style={{ display: 'inline-flex', alignItems: 'baseline', gap: 6 }}>支付 <FPrice value={item.amount} size={17} color="#fff" /></span>}
          </FBtn>
          <div style={{ fontFamily: T.sans, fontSize: 11, color: T.faint, textAlign: 'center', marginTop: 12, lineHeight: 1.6 }}>支付即表示同意《帧集服务协议》<br />数字作品支付成功后可立即查看下载</div>
        </div>
      )}
    </FSheet>
  );
}

// ── 大图预览（仍为缩略图画质，引导购买高清原片） ─────────────────────
function PhotoLightbox({ open, photos, index, statusOf, spot, onIndex, onClose, onDownload, onSave }) {
  const T = F_T;
  const list = photos || [];
  const count = list.length;
  const { dx, dragging, handlers } = window.lvUseSwipe({
    enabled: count > 1,
    onPrev: () => onIndex && onIndex(Math.max(0, index - 1)),
    onNext: () => onIndex && onIndex(Math.min(count - 1, index + 1)) });
  if (!open || index == null || !list[index]) return null;
  const photo = list[index];
  const status = statusOf ? statusOf(photo.id, index) : null;
  const img = photo.src || window.pickPhoto(window.lvSeed(photo.id));
  const owned = status === 'bought';
  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 220, background: 'rgba(14,15,13,0.97)', display: 'flex', flexDirection: 'column', animation: 'lvFade .2s ease' }}>
      {/* top bar */}
      <div style={{ flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '56px 16px 6px' }}>
        <button onClick={onClose} style={{ width: 34, height: 34, borderRadius: 999, background: 'rgba(255,255,255,0.12)', border: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
          <FIcon name="close" size={18} color="#fff" stroke={2} />
        </button>
        <span style={{ fontFamily: T.sans, fontSize: 13, fontWeight: 500, color: 'rgba(255,255,255,0.7)' }}>{spot}{count > 1 ? '  ·  ' + (index + 1) + ' / ' + count : ''}</span>
        <span style={{ width: 34 }} />
      </div>
      {/* image (preview quality) */}
      <div {...handlers} style={{ flex: 1, minHeight: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '4px 0', position: 'relative', touchAction: 'pan-y', cursor: count > 1 ? 'grab' : 'default' }}>
        {window.lvNavArrow({ dir: 'prev', show: count > 1 && index > 0, onClick: () => onIndex(Math.max(0, index - 1)) })}
        {window.lvNavArrow({ dir: 'next', show: count > 1 && index < count - 1, onClick: () => onIndex(Math.min(count - 1, index + 1)) })}
        <div style={{ position: 'relative', display: 'block', width: '100%', transform: 'translateX(' + dx + 'px)', transition: dragging ? 'none' : 'transform .22s ease' }}>
          <img src={window.lvAsset(img)} alt="" draggable="false" style={{ display: 'block', width: '100%', maxHeight: '74vh', objectFit: 'contain' }} />
          {!owned && (
            <div style={{ position: 'absolute', left: 10, bottom: 10 }}>
              <span style={{ fontFamily: T.sans, fontSize: 10.5, fontWeight: 500, color: 'rgba(255,255,255,0.45)', letterSpacing: 0.3 }}>AI 创作</span>
            </div>
          )}
        </div>
      </div>
      {/* bottom action */}
      <div style={{ flexShrink: 0, padding: '14px 18px calc(22px + env(safe-area-inset-bottom))' }}>
        {owned ? (
          <FBtn kind="primary" full size="lg" icon="download" onClick={onSave}>保存高清原图到相册</FBtn>
        ) : (
          <>
            <FBtn kind="primary" full size="lg" icon="download" onClick={onDownload}>下载高清原图</FBtn>
            <div style={{ fontFamily: T.sans, fontSize: 11.5, color: 'rgba(255,255,255,0.55)', textAlign: 'center', marginTop: 11, lineHeight: 1.6 }}>当前显示为预览图，高清无标识原片需购买后下载</div>
          </>
        )}
      </div>
    </div>
  );
}

// ── 单组照片页 ────────────────────────────────────────────────────
function GroupPhotoScreen({ store, nav, groupId }) {
  const T = F_T;
  const g = groupId === window.LV_DATA.PHOTO_GROUP_2.id ? window.LV_DATA.PHOTO_GROUP_2 : store.group;
  const isMain = g.id === store.group.id;
  // photo status map (only main group tracked in store; others demo as locked)
  const statusOf = (pid, i) => {
    if (!isMain) return 'locked';
    return store.photos[pid] || 'locked';
  };
  const [sel, setSel] = React.useState(new Set());
  const [pay, setPay] = React.useState(null);
  const [view, setView] = React.useState(null);   // {p, st} 当前查看大图的照片
  const [dl, setDl] = React.useState(false);       // 下载高清原图选择面板
  const freeClaimed = isMain && (store.stage === 'claimed' || store.stage === 'bought');

  const toggle = (pid, i) => {
    if (statusOf(pid, i) !== 'locked') return;
    setSel(prev => { const n = new Set(prev); n.has(pid) ? n.delete(pid) : n.add(pid); return n; });
  };
  const n = sel.size;
  const singleTotal = (n * 12.9).toFixed(1).replace('.0', '');

  const claimFree = () => {
    const pid = n === 1 ? [...sel][0] : g.photos.find(p => statusOf(p.id) === 'locked')?.id;
    store.set({ photos: { ...store.photos, [pid]: 'free' }, stage: store.stage === 'arrived' ? 'claimed' : store.stage });
    setSel(new Set());
  };
  const buySingles = () => setPay({ name: `单张现场原片 ×${n}`, sub: g.spot, amount: singleTotal, tone: g.tone, kind: '原片', _ids: [...sel] });
  const buyOne = (pid) => setPay({ name: '单张现场原片 ×1', sub: g.spot, amount: '12.9', tone: g.tone, kind: '原片', _ids: [pid] });
  const buyAll = () => setPay({ name: '本机位本次全部现场原片', sub: `${g.spot} · ${g.photos.length} 张`, amount: '29.9', tone: g.tone, kind: '原片', _all: true });

  const onPaid = () => {
    const it = pay;
    if (it._all) {
      const np = {}; g.photos.forEach(p => np[p.id] = 'bought');
      store.set({ photos: { ...store.photos, ...np }, stage: 'bought' });
    } else if (it._ids) {
      const np = { ...store.photos }; it._ids.forEach(id => np[id] = 'bought');
      store.set({ photos: np });
    }
    const oid = store.addOrder({ cat: '原片', name: it.name, tone: g.tone, amount: +it.amount,
      state: '已完成', group: 'done', eta: '支付成功后可下载',
      timeline: [{ t: '待付款', done: true, time: '刚刚' }, { t: '支付成功', done: true, time: '刚刚' }, { t: '已完成', done: true, time: '刚刚', cur: true }] });
    setPay(null); setSel(new Set());
    nav.push('orderDetail', { orderId: oid });
  };

  return (
    <>
    <FScreen
      nav={<FNav title={g.spot} onBack={() => nav.pop()} rightIcons={[{ name: 'share', onClick: () => {} }]} />}
      body={<div style={{ padding: '6px 18px 130px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 7, padding: '10px 13px', borderRadius: 7, background: T.ink, marginBottom: 16 }}>
          <FIcon name="check" size={16} color="#fff" stroke={2} />
          <span style={{ fontFamily: T.sans, fontSize: 12.5, color: '#fff', lineHeight: 1.4 }}>本机位可<b>免费领取 1 张</b>，更多照片自愿购买</span>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
          {g.photos.map((p, i) => {
            const st = statusOf(p.id, i);
            const selected = sel.has(p.id);
            return (
              <div key={p.id} onClick={() => toggle(p.id, i)} style={{ position: 'relative', borderRadius: 8, overflow: 'hidden' }}>
                <FPhoto src={p.src} seed={window.lvSeed(p.id)} ratio="3 / 4" locked={st === 'locked'} selected={selected}
                  tag={st === 'free' ? { text: '已免费领取', bg: window.lvAccent(), color: '#fff' } : st === 'bought' ? { text: '已购买', bg: 'rgba(20,22,20,0.7)', color: '#fff', style: { backdropFilter: 'blur(4px)' } } : null} />
                <button onClick={(e) => { e.stopPropagation(); setView(i); }}
                  style={{ position: 'absolute', right: 8, bottom: 8, width: 30, height: 30, borderRadius: 999, border: 'none', cursor: 'pointer',
                    background: 'rgba(20,22,20,0.5)', backdropFilter: 'blur(5px)', WebkitBackdropFilter: 'blur(5px)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <FIcon name="search" size={16} color="#fff" stroke={1.9} />
                </button>
              </div>
            );
          })}
        </div>
        <div style={{ marginTop: 18, fontFamily: T.sans, fontSize: 12, color: T.muted, lineHeight: 1.7, textAlign: 'center' }}>
          点照片右下角可查看大图。未购买仅可预览，不提供高清保存，但不使用遮脸水印。<br />免费照片确认领取后原则上不再更换，质量问题走客服。
        </div>
      </div>}
      footer={
        <div style={{ flexShrink: 0, background: T.card, padding: '12px 16px calc(14px + env(safe-area-inset-bottom))', boxShadow: '0 -0.5px 0 ' + T.line + ', 0 -6px 20px rgba(26,25,22,0.05)' }}>
          {n >= 2 && <div style={{ fontFamily: T.sans, fontSize: 11.5, color: window.lvAccent(), fontWeight: 600, textAlign: 'center', marginBottom: 8 }}>已选 {n} 张 · 单张合计 ¥{singleTotal}，本组全部仅 ¥29.9 更划算 →</div>}
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <div style={{ flex: 1 }}>
              {n === 0
                ? <span style={{ fontFamily: T.sans, fontSize: 12.5, color: T.muted }}>{freeClaimed ? '选择照片购买，或整组购买' : '选 1 张免费领取，或整组购买'}</span>
                : <div><span style={{ fontFamily: T.sans, fontSize: 11.5, color: T.muted }}>已选 {n} 张 · 单张合计</span><div><FPrice value={singleTotal} size={19} /></div></div>}
            </div>
            {!freeClaimed && n <= 1 && <FBtn kind="ghost" size="md" onClick={claimFree}>免费领取{n === 1 ? '这张' : ' 1 张'}</FBtn>}
            {n >= 1 && <FBtn kind="soft" size="md" onClick={buySingles}>购买所选</FBtn>}
            <FBtn kind="primary" size="md" onClick={buyAll}><span style={{ display: 'inline-flex', alignItems: 'baseline', gap: 5 }}>全部 <FPrice value="29.9" size={16} color="#fff" /></span></FBtn>
          </div>
        </div>
      }
    />
    <PhotoLightbox open={view != null} photos={g.photos} index={view} statusOf={statusOf} spot={g.spot}
      onIndex={setView}
      onClose={() => setView(null)}
      onDownload={() => setDl(true)}
      onSave={() => { setView(null); nav.push('assetList', { kind: 'yuanpian' }); }} />
    <FSheet open={dl} onClose={() => setDl(false)} title="下载高清原图" maxH="64%">
      <div style={{ paddingBottom: 8 }}>
        <div style={{ fontFamily: T.sans, fontSize: 12.5, color: T.muted, lineHeight: 1.6, margin: '2px 2px 14px' }}>选择一种方式获取高清无标识原片。</div>
        {/* 仅下载本张 */}
        <button onClick={() => { const pid = view != null && g.photos[view] && g.photos[view].id; setDl(false); setView(null); if (pid) buyOne(pid); }}
          style={{ width: '100%', textAlign: 'left', background: T.card, border: 'none', boxShadow: 'inset 0 0 0 1px ' + T.line, borderRadius: 8, padding: 16, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 13, marginBottom: 12 }}>
          <div style={{ width: 42, height: 42, borderRadius: 6, background: T.field, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
            <FIcon name="download" size={21} color={T.ink} stroke={1.7} />
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontFamily: T.sans, fontSize: 15, fontWeight: 700, color: T.ink }}>仅下载本张</div>
            <div style={{ fontFamily: T.sans, fontSize: 12, color: T.muted, marginTop: 3 }}>单张现场原片 · 含基础调色与裁切</div>
          </div>
          <FPrice value="12.9" size={20} />
        </button>
        {/* 购买创意摄影套餐 · 赠全部原片 */}
        <button onClick={() => { setDl(false); setView(null); nav.push('product', { cat: 'chuangyi' }); }}
          style={{ width: '100%', textAlign: 'left', background: T.ink, border: 'none', borderRadius: 8, padding: 16, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 13, position: 'relative', overflow: 'hidden' }}>
          <div style={{ position: 'absolute', right: 14, top: 12, fontFamily: T.sans, fontSize: 10.5, fontWeight: 700, letterSpacing: 0.5, color: T.ink, background: window.lvAccent(), padding: '3px 9px', borderRadius: 999 }}>最划算</div>
          <div style={{ width: 42, height: 42, borderRadius: 6, background: 'rgba(255,255,255,0.12)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
            <FIcon name="sparkle" size={21} color="#fff" stroke={1.7} />
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontFamily: T.sans, fontSize: 15, fontWeight: 700, color: '#fff' }}>购创意摄影套餐</div>
            <div style={{ fontFamily: T.sans, fontSize: 12, color: 'rgba(255,255,255,0.66)', marginTop: 3, lineHeight: 1.5 }}>赠送本机位本次全部高清原片 + 主题创作大片</div>
          </div>
        </button>
        <div style={{ fontFamily: T.sans, fontSize: 11, color: T.faint, textAlign: 'center', marginTop: 14, lineHeight: 1.6 }}>创意摄影套餐均含本机位全部现场原片，已购原片可折抵。</div>
      </div>
    </FSheet>
    <PaymentSheet key="pay" open={!!pay} item={pay} onClose={() => setPay(null)} onPaid={onPaid} />
    </>
  );
}

// ── 案例详情 ──────────────────────────────────────────────────────
// ── 作品全屏页（游客创意摄影 · 好评 + 定制同款）────
function WorkPhotoScreen({ nav, item, items, store, variant = 'work' }) {
  const T = F_T;
  const G = window.LV_GOLD || { grad: 'linear-gradient(135deg, #F4DC9A 0%, #E6BE68 46%, #CC9C40 100%)', text: '#4A3209' };
  const isSpot = variant === 'spot';
  const fallback = { theme: '蓝月秘境', by: '小鹿', review: '比想象中还仙，朋友都问我在哪拍的', src: 'assets/p2.jpg', id: 'f1' };
  const list = (items && items.length) ? items : [item || fallback];
  const startIdx = Math.max(0, item ? list.findIndex((x) => x && x.id === item.id) : 0);
  const [cur, setCur] = React.useState(startIdx < 0 ? 0 : startIdx);
  const [buyOpen, setBuyOpen] = React.useState(false);
  const [pay, setPay] = React.useState(null);
  const count = list.length;
  const { dx, dragging, handlers } = window.lvUseSwipe({
    enabled: count > 1,
    onPrev: () => setCur((c) => Math.max(0, c - 1)),
    onNext: () => setCur((c) => Math.min(count - 1, c + 1)) });
  const it = list[cur] || list[0];
  const img = it.src || window.pickPhoto(window.lvSeed(it.id || it.theme || 'work'));
  const onPaid = (p) => {
    if (store && store.addOrder) {
      store.addOrder({ cat: '创意摄影', name: p.name, tone: p.tone || 'lake', amount: p.amount,
        state: '正在制作', group: 'going', eta: '供应商正在为你制作，订单不可再修改内容',
        timeline: [{ t: '已确认内容', done: true, time: '刚刚' }, { t: '正在制作', done: true, time: '刚刚', cur: true }, { t: '已定制', done: false }, { t: '已完成', done: false }] });
    }
    setPay({ name: p.name, sub: p.sub, amount: p.amount, tone: p.tone });
  };
  return (
    <>
    <div style={{ position: 'absolute', inset: 0, zIndex: 40, background: 'rgba(12,13,11,0.98)', display: 'flex', flexDirection: 'column' }}>
      {/* top bar */}
      <div style={{ flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '56px 16px 6px' }}>
        <button onClick={() => nav.pop()} style={{ width: 34, height: 34, borderRadius: 999, background: 'rgba(255,255,255,0.12)', border: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
          <FIcon name="close" size={18} color="#fff" stroke={2} />
        </button>
        <span style={{ fontFamily: T.sans, fontSize: 13, fontWeight: 500, color: 'rgba(255,255,255,0.7)' }}>{it.theme}{count > 1 ? '  ·  ' + (cur + 1) + ' / ' + count : ''}</span>
        <span style={{ width: 34 }} />
      </div>
      {/* image */}
      <div {...handlers} style={{ flex: 1, minHeight: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '4px 0', position: 'relative', touchAction: 'pan-y', cursor: count > 1 ? 'grab' : 'default' }}>
        {window.lvNavArrow({ dir: 'prev', show: count > 1 && cur > 0, onClick: () => setCur((c) => Math.max(0, c - 1)) })}
        {window.lvNavArrow({ dir: 'next', show: count > 1 && cur < count - 1, onClick: () => setCur((c) => Math.min(count - 1, c + 1)) })}
        <img key={img} src={window.lvAsset(img)} alt="" draggable="false" style={{ display: 'block', width: '100%', maxHeight: '62vh', objectFit: 'contain', transform: 'translateX(' + dx + 'px)', transition: dragging ? 'none' : 'transform .22s ease' }} />
      </div>
      {/* caption + CTA */}
      <div style={{ flexShrink: 0, padding: '14px 22px calc(26px + env(safe-area-inset-bottom))' }}>
        <div style={{ fontFamily: T.serif, fontSize: 12.5, color: 'rgba(255,255,255,0.5)', lineHeight: 1.5, textWrap: 'pretty' }}>“{it.review}”</div>
        <div style={{ fontFamily: T.sans, fontSize: 12.5, fontWeight: 600, color: 'rgba(255,255,255,0.78)', marginTop: 7 }}>—— {it.by} · {it.theme}</div>
        {!isSpot &&
        <button onClick={() => setBuyOpen(true)}
          style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: '100%', boxSizing: 'border-box', marginTop: 18, padding: '14px 0', background: G.grad, border: 'none', borderRadius: 7, color: G.text, fontFamily: T.sans, fontSize: 15.5, fontWeight: 700, letterSpacing: 0.4, cursor: 'pointer', boxShadow: '0 8px 22px rgba(204,156,64,0.42), inset 0 1px 0 rgba(255,255,255,0.5)' }}>
          定制我的同款
        </button>}
      </div>
    </div>
    {window.ChuangyiBuySheet && <window.ChuangyiBuySheet open={buyOpen} onClose={() => setBuyOpen(false)} store={store} onPaid={onPaid} />}
    {window.PaymentSheet && <window.PaymentSheet open={!!pay} item={pay} onClose={() => setPay(null)} onPaid={() => { setPay(null); nav.reset('orders'); }} />}
    </>
  );
}

function CaseDetailScreen({ nav, item, items, store }) {
  const T = F_T;
  const G = window.LV_GOLD || { grad: 'linear-gradient(135deg, #F4DC9A 0%, #E6BE68 46%, #CC9C40 100%)', text: '#4A3209' };
  const fallback = { tone: 'lake', kind: '现场原片', title: '蓝月谷', src: 'assets/p2.jpg', id: 'case-f' };
  const list = (items && items.length) ? items : [item || fallback];
  const startIdx = item ? list.findIndex((x) => x && x.id === item.id) : 0;
  const [cur, setCur] = React.useState(startIdx < 0 ? 0 : startIdx);
  const [buyOpen, setBuyOpen] = React.useState(false);
  const [pay, setPay] = React.useState(null);
  const count = list.length;
  const { dx, dragging, handlers } = window.lvUseSwipe({
    enabled: count > 1,
    onPrev: () => setCur((c) => Math.max(0, c - 1)),
    onNext: () => setCur((c) => Math.min(count - 1, c + 1)) });
  const it = list[cur] || list[0];
  const img = it.src || window.pickPhoto(window.lvSeed(it.id || it.title || 'case'));
  const isSpot = (it.kind || '').includes('机位');
  const onPaid = (p) => {
    if (store && store.addOrder) {
      store.addOrder({ cat: '创意摄影', name: p.name, tone: p.tone || 'lake', amount: p.amount,
        state: '正在制作', group: 'going', eta: '供应商正在为你制作，订单不可再修改内容',
        timeline: [{ t: '已确认内容', done: true, time: '刚刚' }, { t: '正在制作', done: true, time: '刚刚', cur: true }, { t: '已定制', done: false }, { t: '已完成', done: false }] });
    }
    setPay({ name: p.name, sub: p.sub, amount: p.amount, tone: p.tone });
  };
  return (
    <>
    <div style={{ position: 'absolute', inset: 0, zIndex: 40, background: 'rgba(12,13,11,0.98)', display: 'flex', flexDirection: 'column' }}>
      {/* top bar */}
      <div style={{ flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '56px 16px 6px' }}>
        <button onClick={() => nav.pop()} style={{ width: 34, height: 34, borderRadius: 999, background: 'rgba(255,255,255,0.12)', border: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
          <FIcon name="close" size={18} color="#fff" stroke={2} />
        </button>
        <span style={{ fontFamily: T.sans, fontSize: 13, fontWeight: 500, color: 'rgba(255,255,255,0.7)' }}>{it.kind}{count > 1 ? '  ·  ' + (cur + 1) + ' / ' + count : ''}</span>
        <span style={{ width: 34 }} />
      </div>
      {/* image */}
      <div {...handlers} style={{ flex: 1, minHeight: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '4px 0', position: 'relative', touchAction: 'pan-y', cursor: count > 1 ? 'grab' : 'default' }}>
        {window.lvNavArrow({ dir: 'prev', show: count > 1 && cur > 0, onClick: () => setCur((c) => Math.max(0, c - 1)) })}
        {window.lvNavArrow({ dir: 'next', show: count > 1 && cur < count - 1, onClick: () => setCur((c) => Math.min(count - 1, c + 1)) })}
        <img key={img} src={window.lvAsset(img)} alt="" draggable="false" style={{ display: 'block', width: '100%', maxHeight: '62vh', objectFit: 'contain', transform: 'translateX(' + dx + 'px)', transition: dragging ? 'none' : 'transform .22s ease' }} />
      </div>
      {/* caption + CTA */}
      <div style={{ flexShrink: 0, padding: '14px 22px calc(26px + env(safe-area-inset-bottom))' }}>
        <div style={{ fontFamily: T.sans, fontSize: 12.5, color: 'rgba(255,255,255,0.5)', letterSpacing: 0.3 }}>{it.kind}</div>
        <div style={{ fontFamily: T.sans, fontSize: 16, fontWeight: 700, color: '#fff', marginTop: 5 }}>{it.title}</div>
        {!isSpot &&
        <button onClick={() => setBuyOpen(true)}
          style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: '100%', boxSizing: 'border-box', marginTop: 16, padding: '14px 0', background: G.grad, border: 'none', borderRadius: 7, color: G.text, fontFamily: T.sans, fontSize: 15.5, fontWeight: 700, letterSpacing: 0.4, cursor: 'pointer', boxShadow: '0 8px 22px rgba(204,156,64,0.42), inset 0 1px 0 rgba(255,255,255,0.5)' }}>
          定制我的同款
        </button>}
      </div>
    </div>
    {window.ChuangyiBuySheet && <window.ChuangyiBuySheet open={buyOpen} onClose={() => setBuyOpen(false)} store={store} onPaid={onPaid} />}
    {window.PaymentSheet && <window.PaymentSheet open={!!pay} item={pay} onClose={() => setPay(null)} onPaid={() => { setPay(null); nav.reset('orders'); }} />}
    </>
  );
}

// ── 消息中心 ──────────────────────────────────────────────────────
function MessagesScreen({ nav }) {
  const T = F_T;
  const msgs = [
    { t: '照片已到达', d: '玉液湖机位 6 张已上传完成，去看看吧', time: '刚刚', tone: 'lake', unread: true },
    { t: '精修完成 · 待确认', d: '本组全部人工精修已交付，请确认或申请修改', time: '18:30', tone: 'snow', unread: true },
    { t: '文创可自提', d: '冰箱贴已制作完成，今天 21:00 前到服务点领取', time: '15:05', tone: 'gold' },
    { t: '创意摄影进度', d: '蓝月秘境已进入创作阶段', time: '14:20', tone: 'dusk' },
  ];
  return (
    <FScreen nav={<FNav title="消息通知" onBack={() => nav.pop()} />}
      body={<div style={{ padding: '8px 16px 24px' }}>
        <div style={{ fontFamily: T.sans, fontSize: 11.5, color: T.faint, padding: '4px 4px 12px' }}>交易与交付通知 · 与营销消息分开</div>
        {msgs.map((m, i) => (
          <FCard key={i} pad={14} style={{ marginBottom: 10 }} onClick={() => nav.reset('orders')}>
            <div style={{ display: 'flex', gap: 12 }}>
              <div style={{ width: 44, height: 44, borderRadius: 6, overflow: 'hidden', flexShrink: 0 }}><FPhoto seed={window.lvSeed(m.t)} /></div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                  <span style={{ fontFamily: T.sans, fontSize: 14.5, fontWeight: 700, color: T.ink }}>{m.t}</span>
                  {m.unread && <span style={{ width: 7, height: 7, borderRadius: 6, background: '#C0492F' }} />}
                  <span style={{ marginLeft: 'auto', fontFamily: T.sans, fontSize: 11, color: T.faint }}>{m.time}</span>
                </div>
                <div style={{ fontFamily: T.sans, fontSize: 12.5, color: T.muted, marginTop: 4, lineHeight: 1.5 }}>{m.d}</div>
              </div>
            </div>
          </FCard>
        ))}
      </div>} />
  );
}

// ── 客服中心 ──────────────────────────────────────────────────────
function ServiceScreen({ nav }) {
  const T = F_T;
  const cats = ['照片未到', '绑错卡', '付款后无法下载', '精修修改', '创意摄影异常', '文创自提/质量', '退款'];
  return (
    <FScreen nav={<FNav title="在线客服" onBack={() => nav.pop()} />}
      body={<div style={{ padding: '12px 18px 24px' }}>
        <FCard pad={18} style={{ background: T.ink, marginBottom: 18 }}>
          <div style={{ fontFamily: T.sans, fontSize: 16, fontWeight: 700, color: '#fff' }}>遇到问题了？</div>
          <div style={{ fontFamily: T.sans, fontSize: 12.5, color: 'rgba(255,255,255,0.65)', margin: '7px 0 16px', lineHeight: 1.6 }}>选择问题类型，我们尽快为你处理。照片相关问题请备好取片卡号。</div>
          <FBtn kind="primary" icon="chat" style={{ background: '#fff', color: T.ink }} onClick={() => {}}>开始对话</FBtn>
        </FCard>
        <FEye style={{ margin: '0 2px 12px' }}>常见问题分类</FEye>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10 }}>
          {cats.map(c => (
            <button key={c} style={{ fontFamily: T.sans, fontSize: 13, color: T.inkSoft, background: T.card, border: 'none', boxShadow: 'inset 0 0 0 1px ' + T.line, padding: '10px 14px', borderRadius: 7, cursor: 'pointer' }}>{c}</button>
          ))}
        </div>
      </div>} />
  );
}

// ── 绑卡帮助 ──────────────────────────────────────────────────────
function BindHelpScreen({ nav }) {
  const T = F_T;
  const faqs = [
    ['照片还没到？', '相机通过 Wi-Fi 自动上传，通常几分钟内到达。可订阅到达提醒，无需一直停留。'],
    ['卡已被其他账户绑定', '为保护隐私不展示照片，请联系客服核验身份。'],
    ['卡号错误', '请核对取片卡上的卡号后重新输入，区分易混字符。'],
    ['丢卡了', '可按拍摄机位与时间找回，必要时授权人脸辅助找回。'],
    ['绑定期限', '取片卡 7 天内可绑定，过期请联系客服。'],
  ];
  return (
    <FScreen nav={<FNav title="常见问题" onBack={() => nav.pop()} />}
      body={<div style={{ padding: '14px 20px 28px' }}>
        {faqs.map(([q, a], i) => (
          <div key={q} style={{ padding: '16px 0', borderTop: i ? '1px solid ' + T.line : 'none' }}>
            <div style={{ fontFamily: T.sans, fontSize: 14.5, fontWeight: 700, color: T.ink }}>{q}</div>
            <div style={{ fontFamily: T.sans, fontSize: 13, color: T.muted, marginTop: 7, lineHeight: 1.75 }}>{a}</div>
          </div>
        ))}
        <button onClick={() => nav.push('service')} style={{ display: 'block', marginTop: 20, background: 'none', border: 'none', padding: 0, cursor: 'pointer', fontFamily: T.sans, fontSize: 13.5, color: '#576B95' }}>联系在线客服</button>
      </div>} />
  );
}

Object.assign(window, { PaymentSheet, GroupPhotoScreen, WorkPhotoScreen, CaseDetailScreen, MessagesScreen, ServiceScreen, BindHelpScreen });
