// pages/booking-flow.jsx — 4-step booking flow (選時間→選項目→明細→結帳) + success.
// 服務者已於 provider-detail 選定，直接從選時間開始。選項目 is a [多貓] × [多服務] matrix.
const { useState: uSB } = React;

const STEPS = ['選時間', '選項目', '明細', '結帳'];

// the owner's cats + the bookable services (price each)
const BFCATS = [
  { id: 'c1', name: '米克斯 · 公', sub: '3 歲 · 需餵藥' },
  { id: 'c2', name: '英短 · 母', sub: '5 歲' },
];
const EXTRAS = [['litter', '清貓砂 + 換水', 150], ['play', '陪玩 30 分', 200], ['med', '餵藥服務', 100]];
const FEED_PRICE = 420, PLATFORM_FEE = 50;

const catTotal = (p) => p.on ? (p.feed * FEED_PRICE + EXTRAS.reduce((s, [k, , pr]) => s + (p[k] ? pr : 0), 0)) : 0;
const bookingSubtotal = (picks) => BFCATS.reduce((s, c) => s + catTotal(picks[c.id]), 0) + PLATFORM_FEE;
const money = (n) => '$' + n.toLocaleString();
const WD = ['日', '一', '二', '三', '四', '五', '六'];
const pad2 = (n) => String(n).padStart(2, '0');
const timeDayLabel = (t) => {
  if (!t || !t.day) return '';
  const [y, m, d] = t.day.split('-').map(Number);
  return `${m + 1}/${d}（${WD[new Date(y, m, d).getDay()]}）`;
};
const timeFullLabel = (t) => {
  if (!t || !t.day || !t.slots.length) return timeDayLabel(t);
  return `${timeDayLabel(t)} ${pad2(Math.min(...t.slots))}:00`;
};
const summarize = (p) => {
  const parts = [];
  if (p.feed) parts.push(`到府餵食 ×${p.feed}`);
  EXTRAS.forEach(([k, l]) => { if (p[k]) parts.push(l.split(' ')[0]); });
  return parts.join('、') || '尚未選服務';
};

function StepBar({ cur }) {
  return A('div', { style: { display: 'flex', alignItems: 'center', padding: '6px 18px 14px', flexShrink: 0 } },
    STEPS.map((s, i) => A(React.Fragment, { key: i },
      A('div', { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 5 } },
        A('div', { style: { width: 22, height: 22, borderRadius: 11, display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'Nunito', fontSize: 11, fontWeight: 800,
          background: i <= cur ? 'var(--accent)' : 'var(--surface)', color: i <= cur ? '#fff' : 'var(--ink3)', border: i > cur ? '1.5px solid var(--line)' : 'none' } },
          i < cur ? A(Icon, { name: 'check', size: 12, sw: 3 }) : i + 1),
        A('span', { style: { fontSize: 9.5, fontWeight: i === cur ? 800 : 600, color: i <= cur ? 'var(--ink)' : 'var(--ink3)', whiteSpace: 'nowrap' } }, s)),
      i < STEPS.length - 1 && A('div', { style: { flex: 1, height: 2, background: i < cur ? 'var(--accent)' : 'var(--line)', margin: '0 4px', marginBottom: 16 } }))));
}

// ===== 選時間: 跨月月曆 + 1 小時時段區間 =====
function StepTime({ time, setTime }) {
  const moveMonth = (delta) => setTime(t => {
    let nm = t.ym.m + delta, ny = t.ym.y;
    if (nm < 0) { nm = 11; ny -= 1; }
    if (nm > 11) { nm = 0; ny += 1; }
    return { ...t, ym: { y: ny, m: nm } };
  });
  const { y, m } = time.ym;
  const first = new Date(y, m, 1).getDay();
  const dim = new Date(y, m + 1, 0).getDate();
  const cells = [];
  for (let i = 0; i < first; i++) cells.push(null);
  for (let d = 1; d <= dim; d++) cells.push(d);
  const dayOk = (d) => new Date(y, m, d).getDay() !== 0; // demo: Sundays off

  const HOURS = [8, 9, 10, 11, 13, 14, 15, 16, 18, 19];
  const hourOff = new Set([11, 16]);
  const toggleSlot = (h) => setTime(t => ({ ...t, slots: t.slots.includes(h) ? t.slots.filter(x => x !== h) : [...t.slots, h] }));
  const navBtn = { width: 30, height: 30, borderRadius: '50%', border: 'none', background: 'var(--bgSoft)', color: 'var(--ink2)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', flexShrink: 0 };

  return A('div', null,
    // who you're booking
    A(Card, { pad: 12, style: { display: 'flex', gap: 10, alignItems: 'center', marginBottom: 14 } },
      A(Avatar, { size: 40, kind: 'person', style: { borderRadius: 12 } }),
      A('div', { style: { flex: 1 } }, A('div', { style: { fontSize: 14, fontWeight: 700 } }, '林依婷'), A('div', { style: { fontSize: 11, color: 'var(--ink3)' } }, '到府保姆 · ★ 4.9'))),
    // calendar
    A(Card, { pad: 16 },
      A('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 } },
        A('button', { className: 'ccaTap', onClick: () => moveMonth(-1), style: navBtn }, A(Icon, { name: 'chevL', size: 18 })),
        A('div', { className: 'num', style: { fontSize: 14.5, fontWeight: 800 } }, `${y} 年 ${m + 1} 月`),
        A('button', { className: 'ccaTap', onClick: () => moveMonth(1), style: navBtn }, A(Icon, { name: 'chevR', size: 18 }))),
      A('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(7,1fr)', gap: 4, marginBottom: 6 } },
        WD.map(d => A('div', { key: d, style: { textAlign: 'center', fontSize: 10.5, color: 'var(--ink3)', fontWeight: 700 } }, d))),
      A('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(7,1fr)', gap: 4 } },
        cells.map((d, i) => {
          if (!d) return A('div', { key: 'b' + i });
          const key = `${y}-${m}-${d}`;
          const ok = dayOk(d);
          const isSel = time.day === key;
          return A('button', { key: i, disabled: !ok, className: ok ? 'ccaTap' : '', onClick: () => setTime(t => ({ ...t, day: key })), style: {
            aspectRatio: '1', border: 'none', borderRadius: 10, fontFamily: 'inherit', padding: 0,
            background: isSel ? 'var(--accent)' : ok ? 'var(--accentSoft)' : 'transparent',
            color: isSel ? '#fff' : ok ? 'var(--accentDeep)' : 'var(--neutral)',
            cursor: ok ? 'pointer' : 'default', opacity: ok ? 1 : .55 } },
            A('span', { className: 'num', style: { fontSize: 13, fontWeight: 700 } }, d));
        })),
      // time ranges
      A('div', { style: { marginTop: 16, paddingTop: 14, borderTop: '1px solid var(--line2)' } },
        A('div', { style: { display: 'flex', alignItems: 'baseline', gap: 8 } },
          A('div', { style: { fontSize: 13.5, fontWeight: 800 } }, time.day ? `${timeDayLabel(time)} 時間區段` : '時間區段'),
          A('span', { style: { fontSize: 11, fontWeight: 600, color: 'var(--ink3)' } }, '每段 1 小時 · 可複選')),
        time.day
          ? A('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 10 } },
              HOURS.map(h => {
                const off = hourOff.has(h);
                const on = time.slots.includes(h);
                return A('button', { key: h, disabled: off, className: off ? '' : 'ccaTap', onClick: () => toggleSlot(h), style: {
                  display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '11px 0', borderRadius: 12, border: 'none', fontFamily: 'inherit',
                  background: on ? 'var(--accentSoft)' : off ? 'var(--bgSoft)' : 'var(--surface)',
                  boxShadow: on ? 'inset 0 0 0 1.5px var(--accent)' : off ? 'none' : 'inset 0 0 0 1px var(--line)',
                  color: on ? 'var(--accentDeep)' : off ? 'var(--neutral)' : 'var(--ink)', opacity: off ? .55 : 1, textDecoration: off ? 'line-through' : 'none', cursor: off ? 'default' : 'pointer' } },
                  A('span', { className: 'num', style: { fontSize: 13, fontWeight: 700 } }, `${pad2(h)}:00–${pad2(h + 1)}:00`));
              }))
          : A('div', { style: { fontSize: 12.5, color: 'var(--ink3)', padding: '10px 2px 2px' } }, '先在上方月曆選一天，再挑時間區段'))));
}

// ===== 選項目: 多貓 × 多服務 =====
function StepItems({ picks, setPicks }) {
  const upd = (cid, patch) => setPicks(s => ({ ...s, [cid]: { ...s[cid], ...patch } }));
  const onCount = BFCATS.filter(c => picks[c.id].on).length;
  return A('div', null,
    A('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 } },
      A('div', { style: { fontSize: 12, color: 'var(--ink3)' } }, '選擇要照顧的貓咪，並分別挑選服務'),
      A('span', { style: { fontSize: 11.5, fontWeight: 800, color: 'var(--brandDeep)', background: 'var(--brandSoft)', padding: '3px 10px', borderRadius: 'var(--rpill)' } }, `已選 ${onCount} 隻`)),
    A('div', { style: { display: 'flex', flexDirection: 'column', gap: 12 } },
      BFCATS.map(c => {
        const p = picks[c.id];
        return A(Card, { key: c.id, pad: 0, style: { overflow: 'hidden', boxShadow: p.on ? 'inset 0 0 0 1.5px var(--brand)' : 'inset 0 0 0 1px var(--line2)' } },
          // cat header — toggles whether this cat is included
          A('div', { className: 'ccaTap', onClick: () => upd(c.id, { on: !p.on }), style: { display: 'flex', alignItems: 'center', gap: 12, padding: '13px 14px', background: p.on ? 'var(--brandSoft)' : 'transparent' } },
            A(Ph, { w: 42, h: 42, r: 12, icon: 'paw' }),
            A('div', { style: { flex: 1, minWidth: 0 } },
              A('div', { style: { fontSize: 14.5, fontWeight: 700 } }, c.name),
              A('div', { style: { fontSize: 11.5, color: p.on ? 'var(--brandDeep)' : 'var(--ink3)', marginTop: 1, fontWeight: p.on ? 700 : 400 } }, p.on ? money(catTotal(p)) : c.sub)),
            A(Toggle, { on: p.on, onClick: () => upd(c.id, { on: !p.on }) })),
          // per-cat services
          p.on && A('div', { style: { borderTop: '1px solid var(--line2)' } },
            A('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '13px 16px' } },
              A('div', null, A('div', { style: { fontSize: 13.5, fontWeight: 700 } }, '到府餵食'), A('div', { style: { fontSize: 11, color: 'var(--ink3)', marginTop: 1 } }, `${money(FEED_PRICE)} / 次`)),
              A(Stepper, { value: p.feed, onChange: v => upd(c.id, { feed: v }), min: 1 })),
            EXTRAS.map(([k, l, pr]) => A('div', { key: k, style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '13px 16px', borderTop: '1px solid var(--line2)' } },
              A('div', null, A('div', { style: { fontSize: 13.5, fontWeight: 700 } }, l), A('div', { style: { fontSize: 11, color: 'var(--ink3)', marginTop: 1 } }, `+${money(pr)}`)),
              A(Toggle, { on: p[k], onClick: () => upd(c.id, { [k]: !p[k] }) }))),
            // per-cat note for the sitter (純文字，選填) — 會隨預約傳給貓人力
            A('div', { style: { padding: '13px 16px', borderTop: '1px solid var(--line2)' } },
              A('div', { style: { display: 'flex', alignItems: 'center', gap: 6, fontSize: 13.5, fontWeight: 700, marginBottom: 8 } },
                A(Icon, { name: 'edit', size: 14, color: 'var(--ink3)' }), `給保姆的備註（選填）`),
              A('textarea', { value: p.note || '', onChange: e => upd(c.id, { note: e.target.value }), rows: 2,
                placeholder: `例：${c.name.split(' ')[0]} 怕生、藥放冰箱第二層…`,
                style: { width: '100%', boxSizing: 'border-box', resize: 'none', border: '1px solid var(--line)', borderRadius: 12, background: 'var(--bg)',
                  padding: '10px 12px', fontFamily: 'inherit', fontSize: 13, lineHeight: 1.5, color: 'var(--ink)', outline: 'none' } }))));
      })),
    A('div', { style: { fontSize: 11.5, color: 'var(--ink3)', textAlign: 'center', marginTop: 14 } }, '可同時為多隻貓咪預約，費用會合併計算'));
}

function StepDetail({ picks, time, addrId, setAddrId }) {
  const sel = BFCATS.filter(c => picks[c.id].on);
  const BOOK = (window.ADDRESSES || []);
  const cur = BOOK.find(a => a.id === addrId) || BOOK[0];
  const [picker, setPicker] = React.useState(false);
  return A('div', null,
    A(Card, { pad: 14, style: { marginBottom: 12, display: 'flex', gap: 11, alignItems: 'center' } },
      A(Avatar, { size: 42, kind: 'person', style: { borderRadius: 12 } }),
      A('div', { style: { flex: 1 } }, A('div', { style: { fontSize: 14, fontWeight: 700 } }, '林依婷 · 到府保姆'), A('div', { style: { fontSize: 11.5, color: 'var(--ink3)' } }, `${timeFullLabel(time)} · 到府`)),
      A(Icon, { name: 'edit', size: 18, color: 'var(--ink3)' })),
    // 本次照顧的貓咪與服務
    A('div', { style: { fontSize: 13, fontWeight: 700, margin: '0 2px 8px' } }, `本次照顧 · ${sel.length} 隻`),
    A(Card, { pad: 0, style: { marginBottom: 12 } },
      sel.map((c, i) => A('div', { key: c.id, style: { padding: '12px 14px', borderTop: i ? '1px solid var(--line2)' : 'none' } },
        A('div', { style: { display: 'flex', gap: 11, alignItems: 'center' } },
          A(Ph, { w: 38, h: 38, r: 11, icon: 'paw' }),
          A('div', { style: { flex: 1, minWidth: 0 } },
            A('div', { style: { fontSize: 13.5, fontWeight: 700 } }, c.name),
            A('div', { style: { fontSize: 11.5, color: 'var(--ink3)', marginTop: 1 } }, summarize(picks[c.id]))),
          A('span', { className: 'num', style: { fontSize: 13.5, fontWeight: 800, color: 'var(--accentDeep)' } }, money(catTotal(picks[c.id])))),
        picks[c.id].note && picks[c.id].note.trim() && A('div', { style: { display: 'flex', gap: 7, alignItems: 'flex-start', marginTop: 9, padding: '9px 11px', borderRadius: 10, background: 'var(--bgSoft)' } },
          A(Icon, { name: 'edit', size: 13, color: 'var(--ink3)', style: { flexShrink: 0, marginTop: 2 } }),
          A('div', { style: { flex: 1, fontSize: 12, color: 'var(--ink2)', lineHeight: 1.5 } }, picks[c.id].note))))),
    // address book picker
    A('div', { style: { display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', margin: '0 2px 8px' } },
      A('div', { style: { fontSize: 13, fontWeight: 700 } }, '到府地址'),
      cur && A('button', { className: 'ccaTap', onClick: () => setPicker(p => !p), style: { border: 'none', background: 'transparent', color: 'var(--accentDeep)', fontSize: 12.5, fontWeight: 700, fontFamily: 'inherit', padding: 0 } }, picker ? '收合' : '更換地址')),
    A(Card, { pad: 0, style: { marginBottom: 16, overflow: 'hidden' } },
      // currently-selected address
      cur && A('div', { style: { display: 'flex', gap: 11, alignItems: 'flex-start', padding: '13px 14px' } },
        A('div', { style: { width: 38, height: 38, borderRadius: 11, background: 'var(--brandSoft)', color: 'var(--brandDeep)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 } }, A(Icon, { name: cur.icon, size: 19 })),
        A('div', { style: { flex: 1, minWidth: 0 } },
          A('div', { style: { display: 'flex', alignItems: 'center', gap: 7 } }, A('span', { style: { fontSize: 14, fontWeight: 800 } }, cur.label), cur.def && A(Tag, { color: 'ok', icon: 'check' }, '預設')),
          A('div', { style: { fontSize: 12.5, color: 'var(--ink2)', marginTop: 3, lineHeight: 1.5 } }, `${cur.city}${cur.line}`),
          A('div', { style: { fontSize: 11.5, color: 'var(--ink3)', marginTop: 2 } }, `${cur.name} · ${cur.phone}`)),
        A(Tag, { color: 'brand', icon: 'check' }, '使用中')),
      // expandable picker: other saved addresses + add
      picker && A('div', { style: { borderTop: '1px solid var(--line2)', background: 'var(--bgSoft)' } },
        BOOK.filter(a => a.id !== cur.id).map(a => A('div', { key: a.id, className: 'ccaTap', onClick: () => { setAddrId(a.id); setPicker(false); }, style: { display: 'flex', gap: 11, alignItems: 'center', padding: '12px 14px', borderBottom: '1px solid var(--line2)' } },
        A('div', { style: { width: 32, height: 32, borderRadius: 10, background: 'var(--surface)', color: 'var(--ink2)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, boxShadow: 'inset 0 0 0 1px var(--line2)' } }, A(Icon, { name: a.icon, size: 17 })),
        A('div', { style: { flex: 1, minWidth: 0 } }, A('div', { style: { fontSize: 13, fontWeight: 700 } }, a.label), A('div', { style: { fontSize: 11.5, color: 'var(--ink3)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' } }, `${a.city}${a.line}`)),
        A(Icon, { name: 'chevR', size: 16, color: 'var(--ink3)' }))),
        A('div', { style: { display: 'flex', alignItems: 'center', gap: 8, padding: '13px 14px', color: 'var(--accentDeep)', fontSize: 13, fontWeight: 700 } }, A(Icon, { name: 'plus', size: 17 }), '新增地址'))),
    // fee summary — per cat + platform fee
    A('div', { style: { fontSize: 13, fontWeight: 700, margin: '0 2px 8px' } }, '費用明細'),
    A(Card, { pad: 14 },
      sel.map((c, i) => A('div', { key: c.id, style: { display: 'flex', justifyContent: 'space-between', padding: '6px 0', fontSize: 13.5 } },
        A('span', { style: { color: 'var(--ink2)', fontWeight: 400, fontSize: 14, margin: '0 50px 0 0' } }, `${c.name}（${summarize(picks[c.id])}）`), A('span', { className: 'num', style: { fontWeight: 700 } }, money(catTotal(picks[c.id]))))),
      A('div', { style: { display: 'flex', justifyContent: 'space-between', padding: '6px 0', fontSize: 13.5 } },
        A('span', { style: { color: 'var(--ink2)' } }, '平台服務費'), A('span', { className: 'num', style: { fontWeight: 700 } }, money(PLATFORM_FEE))),
      A('div', { style: { display: 'flex', justifyContent: 'space-between', padding: '10px 0 2px', marginTop: 6, borderTop: '1px solid var(--line2)' } },
        A('span', { style: { fontSize: 14, fontWeight: 800 } }, '小計'), A('span', { className: 'num', style: { fontSize: 16, fontWeight: 800, color: 'var(--accentDeep)' } }, money(bookingSubtotal(picks))))));
}

function StepPay({ pay, setPay, total }) {
  return A('div', null,
    A('div', { style: { textAlign: 'center', padding: '4px 0 18px' } },
      A('div', { style: { fontSize: 12, color: 'var(--ink3)' } }, '應付總額'),
      A('div', { className: 'num', style: { fontSize: 38, fontWeight: 900, color: 'var(--ink)', letterSpacing: -1 } }, money(total))),
    A('div', { style: { fontSize: 13, fontWeight: 700, marginBottom: 10 } }, '付款方式'),
    !pay
      ? A('div', { style: { border: '1.5px dashed var(--brand)', borderRadius: 'var(--rlg)', padding: 16, background: 'var(--surface)' } },
        A('div', { style: { fontSize: 14, fontWeight: 800, marginBottom: 4 } }, '新增付款方式'),
        A('div', { style: { fontSize: 11.5, color: 'var(--ink3)', marginBottom: 14 } }, '資料由你本人輸入 · 平台不留存卡號'),
        A('div', { style: { display: 'flex', flexDirection: 'column', gap: 10 } },
          [['wallet', '信用卡 / 金融卡'], ['phone', '行動支付（Apple / Google Pay）']].map(([ic, l], i) =>
            A('button', { key: i, className: 'ccaTap', onClick: () => setPay(true), style: { display: 'flex', alignItems: 'center', gap: 11, padding: '13px 14px', borderRadius: 14, border: '1px solid var(--line)', background: 'var(--bg)', fontFamily: 'inherit', textAlign: 'left' } },
              A('div', { style: { width: 34, height: 34, borderRadius: 10, background: 'var(--surface)', color: 'var(--accentDeep)', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: 'inset 0 0 0 1px var(--line2)' } }, A(Icon, { name: ic, size: 18 })),
              A('span', { style: { flex: 1, fontSize: 14, fontWeight: 700 } }, l), A(Icon, { name: 'chevR', size: 17, color: 'var(--ink3)' })))))
      : A(Card, { pad: 14, style: { display: 'flex', gap: 11, alignItems: 'center' } },
        A('div', { style: { width: 38, height: 38, borderRadius: 11, background: 'var(--brandSoft)', color: 'var(--brandDeep)', display: 'flex', alignItems: 'center', justifyContent: 'center' } }, A(Icon, { name: 'wallet', size: 19 })),
        A('div', { style: { flex: 1 } }, A('div', { className: 'num', style: { fontSize: 14, fontWeight: 700 } }, '•••• 4271'), A('div', { style: { fontSize: 11.5, color: 'var(--ink3)' } }, '信用卡 · 預設')),
        A(Tag, { color: 'ok', icon: 'check' }, '已選')),
    A('label', { style: { display: 'flex', alignItems: 'center', gap: 10, marginTop: 18, fontSize: 12.5, color: 'var(--ink2)' } },
      A('div', { style: { width: 20, height: 20, borderRadius: 6, background: 'var(--accent)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 } }, A(Icon, { name: 'check', size: 13, color: '#fff', sw: 3 })),
      '我已閱讀並同意服務條款與取消政策'));
}

function Success({ go, picks, time }) {
  const sel = BFCATS.filter(c => picks[c.id].on);
  return A('div', { style: { flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 } },
    A('div', { style: { flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '0 28px', textAlign: 'center' } },
      A('div', { className: 'ccaPop', style: { width: 88, height: 88, borderRadius: '50%', background: 'var(--ok)', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 18, boxShadow: '0 10px 30px rgba(111,169,120,.4)' } }, A(Icon, { name: 'check', size: 46, color: '#fff', sw: 2.4 })),
      A('h1', { style: { fontSize: 24, fontWeight: 800, margin: '0 0 6px' } }, '預約成功！'),
      A('p', { style: { fontSize: 13.5, color: 'var(--ink3)', margin: 0 } }, '寵答已通知林依婷，等待保姆確認'),
      A(Card, { pad: 16, style: { width: '100%', marginTop: 22, textAlign: 'left' } },
        [['保姆', '林依婷 · 到府保姆'], ['時間', timeFullLabel(time)], ['貓咪', sel.map(c => c.name).join('、')], ['金額', money(bookingSubtotal(picks))]].map(([k, v], i) =>
          A('div', { key: i, style: { display: 'flex', justifyContent: 'space-between', padding: '8px 0', borderTop: i ? '1px solid var(--line2)' : 'none' } },
            A('span', { style: { fontSize: 13, color: 'var(--ink3)' } }, k), A('span', { style: { fontSize: 13, fontWeight: 700, textAlign: 'right', maxWidth: 200 } }, v)))) ),
    A('div', { style: { flexShrink: 0, padding: '12px 24px 8px', display: 'flex', flexDirection: 'column', gap: 10 } },
      A(Btn, { full: true, onClick: () => go('bkdetail'), style: { padding: '15px' } }, '查看預約詳情'),
      A(Btn, { full: true, variant: 'ghost', icon: 'message', onClick: () => go('personChat'), style: { padding: '14px' } }, '與保姆對話')),
    A(HomeBar, {}));
}

function BookingFlow({ start = 0, onBack = () => {}, go = () => {} }) {
  const [step, setStep] = uSB(start);
  const [time, setTime] = uSB({ ym: { y: 2025, m: 5 }, day: '2025-5-4', slots: [9] });
  const [picks, setPicks] = uSB({
    c1: { on: true, feed: 3, litter: true, play: false, med: true, note: '怕生，第一次見面請慢慢來；餵藥在冰箱第二層' },
    c2: { on: false, feed: 1, litter: false, play: false, med: false, note: '' },
  });
  const [addrId, setAddrId] = uSB('a1');
  const [pay, setPay] = uSB(false);

  if (step === 4) return A(Success, { go, picks, time });

  const subtotal = bookingSubtotal(picks);
  const canNext = (step !== 0 || (time.day && time.slots.length > 0)) && (step !== 1 || BFCATS.some(c => picks[c.id].on));
  const labels = ['下一步', '下一步', '前往結帳', '確認預約並付款'];
  return A('div', { style: { flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0, background: 'var(--bg)' } },
    A('div', { style: { display: 'flex', alignItems: 'center', gap: 8, padding: '4px 14px 0', flexShrink: 0 } },
      A('button', { className: 'ccaTap', onClick: () => step === 0 ? onBack() : setStep(s => s - 1), style: { width: 38, height: 38, borderRadius: '50%', border: 'none', background: 'var(--surface)', boxShadow: 'inset 0 0 0 1px var(--line2)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--ink)' } }, A(Icon, { name: 'chevL', size: 20 })),
      A('div', { style: { flex: 1, textAlign: 'center', fontSize: 15, fontWeight: 700 } }, '預約 · 林依婷'),
      A('div', { style: { width: 38 } })),
    A(StepBar, { cur: step }),
    A('div', { style: { flex: 1, overflowY: 'auto', padding: '4px 20px 16px' } },
      step === 0 && A(StepTime, { time, setTime }),
      step === 1 && A(StepItems, { picks, setPicks }),
      step === 2 && A(StepDetail, { picks, time, addrId, setAddrId }),
      step === 3 && A(StepPay, { pay, setPay, total: subtotal })),
    A('div', { style: { flexShrink: 0, background: 'var(--surface)', borderTop: '1px solid var(--line2)', padding: '10px 20px 8px' } },
      step >= 1 && step <= 2 && A('div', { style: { display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', padding: '2px 2px 10px' } },
        A('span', { style: { fontSize: 12.5, color: 'var(--ink3)', fontWeight: 600 } }, '小計'),
        A('span', { className: 'num', style: { fontSize: 20, fontWeight: 800, color: 'var(--ink)', letterSpacing: -0.3 } }, money(subtotal))),
      A(Btn, { full: true, iconR: step < 4 ? 'arrowR' : undefined, disabled: !canNext, onClick: () => setStep(s => s + 1), style: { padding: '15px' } }, labels[step])),
    A(HomeBar, {}));
}

window.BookingScreens = {
  section() {
    const W = 390, H = 844;
    const AB = (id, label, node) => A(DCArtboard, { id, label, width: W, height: H, key: id }, A(Phone, null, node));
    return A(DCSection, { id: 'booking', title: '飼主端 · 預約流程', subtitle: '選時間→選項目（多貓 × 多服務）→明細（懶人補地址）→結帳 · 可一路點到底' },
      AB('flow', 'booking-flow.jsx · 預約流程 · 選時間起 4 步可操作 ★▶', A(BookingFlow, { start: 0 })),
      AB('flowAI', 'booking-flow.jsx · 選項目 · 多貓 × 多服務 ▶', A(BookingFlow, { start: 1 })),
      AB('detailStep', 'booking-flow.jsx · 明細 · 多貓費用合併', A(BookingFlow, { start: 2 })),
      AB('pay', 'booking-flow.jsx · 結帳 · 延後補付款方式', A(BookingFlow, { start: 3 })),
      AB('success', 'booking-flow.jsx · 預約成功', A(BookingFlow, { start: 4 })));
  },
};
