// 在线预约 / 咨询页
const BookingPage = () => {
  const t = useT();
  const lang = useLang();
  const b = t.bk;
  const auth = (typeof window.useAuth === 'function') ? window.useAuth() : null;
  const [type, setType] = React.useState(2);
  const [advisor, setAdvisor] = React.useState(0);
  const [day, setDay] = React.useState(2);
  const [slot, setSlot] = React.useState(3);

  // Step 4 contact form (M5.E2) — controlled inputs so we can POST them
  const [contact, setContact] = React.useState({ name: '', phone: '', wechat: '', grade: '', note: '' });
  React.useEffect(() => {
    if (!auth?.user) return;
    setContact((c) => ({
      name: c.name || auth.user.name || '',
      phone: c.phone || auth.user.phone || '',
      wechat: c.wechat,
      grade: c.grade,
      note: c.note,
    }));
  }, [auth?.user]);
  const setField = (k) => (e) => setContact((c) => ({ ...c, [k]: e.target.value }));

  const [submitting, setSubmitting] = React.useState(false);
  const [bookingResult, setBookingResult] = React.useState(null);  // server-returned booking on success
  const [bookingError, setBookingError] = React.useState(null);
  const [fieldErrors, setFieldErrors] = React.useState({});

  const onConfirm = async () => {
    setBookingError(null);
    setFieldErrors({});
    if (!auth?.user) {
      // Send unauthenticated user to login, return here after
      navigateTo('/login?next=' + encodeURIComponent('#/booking'));
      return;
    }
    if (!contact.name || !contact.name.trim()) {
      setFieldErrors({ name: lang === 'zh' ? '此项必填' : 'Required' });
      setBookingError(lang === 'zh' ? '请填写联系姓名' : 'Please enter your name');
      return;
    }
    setSubmitting(true);
    try {
      const r = await fetch('/api/booking/create', {
        method: 'POST',
        credentials: 'same-origin',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          typeIdx: type, advisorIdx: advisor, dayIdx: day, slotIdx: slot,
          name: contact.name.trim(), phone: contact.phone.trim(),
          wechat: contact.wechat.trim(), grade: contact.grade.trim(),
          note: contact.note.trim(),
        }),
      });
      if (r.status === 401) {
        navigateTo('/login?next=' + encodeURIComponent('#/booking'));
        return;
      }
      let data = {};
      try { data = await r.json(); } catch (_) { data = {}; }
      if (r.status === 201 && data.booking) {
        setBookingResult(data.booking);
        return;
      }
      if (r.status === 400 && data.fields) {
        setFieldErrors(data.fields);
        setBookingError(lang === 'zh' ? '请检查表单字段' : 'Please review the form');
        return;
      }
      if (r.status === 429) {
        setBookingError(lang === 'zh' ? '请求过于频繁,请稍后再试' : 'Too many requests, try again later');
        return;
      }
      setBookingError(lang === 'zh' ? '提交失败,请稍后再试' : 'Submission failed, please try again');
    } catch (err) {
      setBookingError(lang === 'zh' ? '网络错误,请检查连接' : 'Network error, please check your connection');
    } finally {
      setSubmitting(false);
    }
  };

  const days = [
    { d: '5/2', dow: lang === 'zh' ? '周五' : 'Fri', label: lang === 'zh' ? '今天' : 'Today' },
    { d: '5/3', dow: lang === 'zh' ? '周六' : 'Sat' },
    { d: '5/4', dow: lang === 'zh' ? '周日' : 'Sun' },
    { d: '5/5', dow: lang === 'zh' ? '周一' : 'Mon' },
    { d: '5/6', dow: lang === 'zh' ? '周二' : 'Tue' },
    { d: '5/7', dow: lang === 'zh' ? '周三' : 'Wed' },
    { d: '5/8', dow: lang === 'zh' ? '周四' : 'Thu' },
  ];

  const slots = ['10:00', '11:00', '14:00', '15:00', '16:00', '17:00', '19:00', '20:00', '21:00'];
  const unavailable = [0, 4, 7];

  const advisors = [
    { name: lang === 'zh' ? '王思琪' : 'Siqi Wang', tag: lang === 'zh' ? 'MIT MS · 美国 CS' : 'MIT MS · US CS', rating: 4.97, slots: 12 },
    { name: lang === 'zh' ? '陈墨然' : 'Moran Chen', tag: lang === 'zh' ? 'Oxford · 英国 G5' : 'Oxford · UK G5', rating: 4.95, slots: 8 },
    { name: lang === 'zh' ? '林皓' : 'Hao Lin', tag: lang === 'zh' ? 'Stanford · 美研 STEM' : 'Stanford · US Grad STEM', rating: 4.92, slots: 15 },
    { name: lang === 'zh' ? '孟韫' : 'Yun Meng', tag: lang === 'zh' ? '高考志愿主任' : 'Gaokao Director', rating: 4.96, slots: 6 },
  ];

  return (
    <div className="pb-scroll">
      <PBNav active="home" />

      <section style={{ padding: '64px 48px 40px', background: 'var(--pb-paper)', borderBottom: '1px solid var(--pb-border)' }}>
        <div style={{ maxWidth: 1280, margin: '0 auto' }}>
          <div className="pb-eyebrow" style={{ marginBottom: 16 }}>{b.eyebrow}</div>
          <h1 className="pb-h1" style={{ fontSize: 56, whiteSpace: 'pre-line', maxWidth: 880, marginBottom: 20 }}>{b.title}</h1>
          <p style={{ fontSize: 17, color: 'var(--pb-fg-muted)', maxWidth: 760, lineHeight: 1.65 }}>{b.sub}</p>
        </div>
      </section>

      <section style={{ padding: '48px 48px 96px' }}>
        <div style={{ maxWidth: 1280, margin: '0 auto', display: 'grid', gridTemplateColumns: '1fr 380px', gap: 32, alignItems: 'start' }}>
          <div className="pb-col pb-gap-24">
            {/* Step 1: type */}
            <div className="pb-card" style={{ padding: 32 }}>
              <div className="pb-row" style={{ alignItems: 'baseline', gap: 12, marginBottom: 20 }}>
                <span style={{ width: 28, height: 28, borderRadius: '50%', background: 'var(--pb-navy-900)', color: 'var(--pb-gold-500)', display: 'grid', placeItems: 'center', fontFamily: 'var(--pb-serif)', fontWeight: 600, fontSize: 13 }}>1</span>
                <h3 style={{ fontFamily: 'var(--pb-serif)', fontSize: 22, fontWeight: 600, margin: 0 }}>{b.step1}</h3>
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 12 }}>
                {b.types.map((tt, i) => (
                  <div key={i} onClick={() => setType(i)} style={{
                    padding: 20,
                    border: type === i ? '2px solid var(--pb-navy-900)' : '1px solid var(--pb-border)',
                    background: type === i ? 'var(--pb-navy-50)' : 'var(--pb-surface)',
                    borderRadius: 'var(--pb-radius)',
                    cursor: 'pointer'
                  }}>
                    <div className="pb-row" style={{ justifyContent: 'space-between', marginBottom: 6 }}>
                      <h4 style={{ fontFamily: 'var(--pb-serif)', fontSize: 18, fontWeight: 600, margin: 0 }}>{tt.name}</h4>
                      {type === i && <svg width="18" height="18" viewBox="0 0 24 24" fill="var(--pb-gold-500)" stroke="white" strokeWidth="2.5"><circle cx="12" cy="12" r="10" stroke="var(--pb-navy-900)" fill="var(--pb-navy-900)"/><path d="M8 12l3 3 5-6" stroke="var(--pb-gold-500)"/></svg>}
                    </div>
                    <p style={{ fontSize: 13, color: 'var(--pb-fg-muted)', margin: '0 0 10px' }}>{tt.desc}</p>
                    <div style={{ fontFamily: 'var(--pb-mono)', fontSize: 12, color: 'var(--pb-gold-700)', fontWeight: 600 }}>{tt.price}</div>
                  </div>
                ))}
              </div>
            </div>

            {/* Step 2: counselor */}
            <div className="pb-card" style={{ padding: 32 }}>
              <div className="pb-row" style={{ alignItems: 'baseline', gap: 12, marginBottom: 20 }}>
                <span style={{ width: 28, height: 28, borderRadius: '50%', background: 'var(--pb-navy-900)', color: 'var(--pb-gold-500)', display: 'grid', placeItems: 'center', fontFamily: 'var(--pb-serif)', fontWeight: 600, fontSize: 13 }}>2</span>
                <h3 style={{ fontFamily: 'var(--pb-serif)', fontSize: 22, fontWeight: 600, margin: 0 }}>{b.step2}</h3>
                <span style={{ fontSize: 12, color: 'var(--pb-fg-muted)', marginLeft: 'auto' }}>{lang === 'zh' ? '系统已根据你的方向推荐' : 'Pre-filtered by your direction'}</span>
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 10 }}>
                {advisors.map((a, i) => (
                  <div key={i} onClick={() => setAdvisor(i)} style={{
                    padding: 16,
                    border: advisor === i ? '2px solid var(--pb-navy-900)' : '1px solid var(--pb-border)',
                    background: advisor === i ? 'var(--pb-navy-50)' : 'var(--pb-surface)',
                    borderRadius: 'var(--pb-radius)',
                    cursor: 'pointer',
                    display: 'flex', gap: 14, alignItems: 'center'
                  }}>
                    <div className="pb-img-placeholder" style={{ width: 44, height: 44, borderRadius: '50%', flexShrink: 0, fontSize: 9 }}>{a.name.slice(0, 2).toUpperCase()}</div>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontFamily: 'var(--pb-serif)', fontSize: 16, fontWeight: 600 }}>{a.name}</div>
                      <div style={{ fontSize: 11, color: 'var(--pb-fg-muted)' }}>{a.tag}</div>
                    </div>
                    <div style={{ textAlign: 'right' }}>
                      <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--pb-gold-700)' }}>★ {a.rating}</div>
                      <div style={{ fontSize: 10, color: 'var(--pb-fg-muted)' }}>{a.slots} {lang === 'zh' ? '可约' : 'open'}</div>
                    </div>
                  </div>
                ))}
              </div>
            </div>

            {/* Step 3: time */}
            <div className="pb-card" style={{ padding: 32 }}>
              <div className="pb-row" style={{ alignItems: 'baseline', gap: 12, marginBottom: 20 }}>
                <span style={{ width: 28, height: 28, borderRadius: '50%', background: 'var(--pb-navy-900)', color: 'var(--pb-gold-500)', display: 'grid', placeItems: 'center', fontFamily: 'var(--pb-serif)', fontWeight: 600, fontSize: 13 }}>3</span>
                <h3 style={{ fontFamily: 'var(--pb-serif)', fontSize: 22, fontWeight: 600, margin: 0 }}>{b.step3}</h3>
                <span style={{ fontSize: 12, color: 'var(--pb-fg-muted)', marginLeft: 'auto', fontFamily: 'var(--pb-mono)' }}>GMT+8 · {lang === 'zh' ? '北京时间' : 'Beijing'}</span>
              </div>

              {/* Day picker */}
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 8, marginBottom: 24 }}>
                {days.map((dy, i) => (
                  <div key={i} onClick={() => setDay(i)} style={{
                    padding: '14px 0',
                    textAlign: 'center',
                    border: day === i ? '2px solid var(--pb-navy-900)' : '1px solid var(--pb-border)',
                    background: day === i ? 'var(--pb-navy-900)' : 'var(--pb-surface)',
                    color: day === i ? 'var(--pb-gold-500)' : 'var(--pb-fg)',
                    borderRadius: 'var(--pb-radius)',
                    cursor: 'pointer'
                  }}>
                    <div style={{ fontSize: 11, opacity: 0.7 }}>{dy.dow}</div>
                    <div style={{ fontFamily: 'var(--pb-serif)', fontSize: 22, fontWeight: 600, marginTop: 4 }}>{dy.d}</div>
                    {dy.label && <div style={{ fontSize: 10, color: day === i ? 'var(--pb-gold-500)' : 'var(--pb-gold-700)', marginTop: 2 }}>{dy.label}</div>}
                  </div>
                ))}
              </div>

              {/* Time slots */}
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 10 }}>
                {slots.map((s, i) => {
                  const isUnavail = unavailable.includes(i);
                  const isSel = slot === i;
                  return (
                    <div key={i} onClick={() => !isUnavail && setSlot(i)} style={{
                      padding: '10px',
                      textAlign: 'center',
                      border: isSel ? '2px solid var(--pb-gold-500)' : '1px solid var(--pb-border)',
                      background: isSel ? 'var(--pb-gold-100)' : isUnavail ? 'var(--pb-surface-alt)' : 'var(--pb-surface)',
                      color: isUnavail ? 'var(--pb-fg-muted)' : isSel ? 'var(--pb-gold-700)' : 'var(--pb-fg)',
                      borderRadius: 'var(--pb-radius)',
                      cursor: isUnavail ? 'not-allowed' : 'pointer',
                      fontFamily: 'var(--pb-mono)',
                      fontSize: 14,
                      fontWeight: 600,
                      textDecoration: isUnavail ? 'line-through' : 'none'
                    }}>
                      {s}
                    </div>
                  );
                })}
              </div>
            </div>

            {/* Step 4: details */}
            <div className="pb-card" style={{ padding: 32 }}>
              <div className="pb-row" style={{ alignItems: 'baseline', gap: 12, marginBottom: 20 }}>
                <span style={{ width: 28, height: 28, borderRadius: '50%', background: 'var(--pb-navy-900)', color: 'var(--pb-gold-500)', display: 'grid', placeItems: 'center', fontFamily: 'var(--pb-serif)', fontWeight: 600, fontSize: 13 }}>4</span>
                <h3 style={{ fontFamily: 'var(--pb-serif)', fontSize: 22, fontWeight: 600, margin: 0 }}>{b.step4}</h3>
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
                <div>
                  <label className="pb-label">{lang === 'zh' ? '姓名' : 'Name'}</label>
                  <input className="pb-input" placeholder={lang === 'zh' ? '陈同学' : 'Chen'} value={contact.name} onChange={setField('name')} data-testid="booking-name"/>
                  {fieldErrors.name && <div style={{ fontSize: 12, color: 'var(--pb-danger)', marginTop: 4 }}>{lang === 'zh' ? '此项必填' : 'Required'}</div>}
                </div>
                <div>
                  <label className="pb-label">{lang === 'zh' ? '手机' : 'Phone'}</label>
                  <input className="pb-input" placeholder="+86 138 ****" value={contact.phone} onChange={setField('phone')} data-testid="booking-phone"/>
                  {fieldErrors.phone && <div style={{ fontSize: 12, color: 'var(--pb-danger)', marginTop: 4 }}>{lang === 'zh' ? '电话号码格式不正确' : 'Invalid phone'}</div>}
                </div>
                <div>
                  <label className="pb-label">{lang === 'zh' ? '微信号' : 'WeChat'}</label>
                  <input className="pb-input" placeholder="ChenXX_2026" value={contact.wechat} onChange={setField('wechat')} data-testid="booking-wechat"/>
                </div>
                <div>
                  <label className="pb-label">{lang === 'zh' ? '当前年级' : 'Grade'}</label>
                  <select className="pb-select" value={contact.grade} onChange={setField('grade')} data-testid="booking-grade">
                    <option value="">{lang === 'zh' ? '请选择' : 'Select'}</option>
                    <option value={lang === 'zh' ? '高三' : 'Senior 3 / 12th'}>{lang === 'zh' ? '高三' : 'Senior 3 / 12th'}</option>
                    <option value={lang === 'zh' ? '高二' : 'Senior 2 / 11th'}>{lang === 'zh' ? '高二' : 'Senior 2 / 11th'}</option>
                    <option value={lang === 'zh' ? '高一' : 'Senior 1 / 10th'}>{lang === 'zh' ? '高一' : 'Senior 1 / 10th'}</option>
                    <option value={lang === 'zh' ? '大学在读' : 'In college'}>{lang === 'zh' ? '大学在读' : 'In college'}</option>
                    <option value={lang === 'zh' ? '已毕业' : 'Graduated'}>{lang === 'zh' ? '已毕业' : 'Graduated'}</option>
                  </select>
                </div>
                <div style={{ gridColumn: 'span 2' }}>
                  <label className="pb-label">{lang === 'zh' ? '简单描述你的情况（可选）' : 'Briefly describe your situation (optional)'}</label>
                  <textarea className="pb-input" rows="3" placeholder={lang === 'zh' ? '比如：物化生选科，目标美国 CS 硕士，TOEFL 108…' : 'e.g. Physics+Chem+Bio, aiming US CS Master\'s, TOEFL 108…'} value={contact.note} onChange={setField('note')} data-testid="booking-note"/>
                </div>
              </div>
            </div>
          </div>

          {/* Sticky summary */}
          <div className="pb-card" style={{ padding: 28, position: 'sticky', top: 100 }}>
            <div className="pb-eyebrow" style={{ marginBottom: 14 }}>{lang === 'zh' ? '预约小结' : 'Booking summary'}</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 14, marginBottom: 24 }}>
              <div>
                <div style={{ fontSize: 11, color: 'var(--pb-fg-muted)', marginBottom: 4 }}>{lang === 'zh' ? '类型' : 'Type'}</div>
                <div style={{ fontFamily: 'var(--pb-serif)', fontSize: 17, fontWeight: 600 }}>{b.types[type].name}</div>
                <div style={{ fontSize: 12, color: 'var(--pb-fg-muted)' }}>{b.types[type].price}</div>
              </div>
              <div style={{ height: 1, background: 'var(--pb-border)' }}/>
              <div>
                <div style={{ fontSize: 11, color: 'var(--pb-fg-muted)', marginBottom: 4 }}>{lang === 'zh' ? '顾问' : 'Counselor'}</div>
                <div style={{ fontFamily: 'var(--pb-serif)', fontSize: 17, fontWeight: 600 }}>{advisors[advisor].name}</div>
                <div style={{ fontSize: 12, color: 'var(--pb-fg-muted)' }}>{advisors[advisor].tag}</div>
              </div>
              <div style={{ height: 1, background: 'var(--pb-border)' }}/>
              <div>
                <div style={{ fontSize: 11, color: 'var(--pb-fg-muted)', marginBottom: 4 }}>{lang === 'zh' ? '时间' : 'Time'}</div>
                <div style={{ fontFamily: 'var(--pb-serif)', fontSize: 17, fontWeight: 600 }}>{days[day].dow} {days[day].d} · {slots[slot]}</div>
                <div style={{ fontSize: 12, color: 'var(--pb-fg-muted)' }}>{lang === 'zh' ? '腾讯会议（系统自动发送）' : 'Tencent Meeting (auto-sent)'}</div>
              </div>
            </div>

            <div style={{ height: 1, background: 'var(--pb-border)', marginBottom: 20 }}/>

            <div className="pb-row" style={{ justifyContent: 'space-between', marginBottom: 20 }}>
              <span style={{ fontWeight: 600 }}>{lang === 'zh' ? '应付' : 'Total'}</span>
              <span style={{ fontFamily: 'var(--pb-serif)', fontSize: 28, fontWeight: 600, color: 'var(--pb-gold-700)' }}>
                {type === 0 || type === 1 ? (lang === 'zh' ? '免费' : 'Free') : type === 2 ? '¥680' : '¥1,580'}
              </span>
            </div>

            {bookingResult ? (
              <div data-testid="booking-success" style={{ padding: '16px 18px', background: '#e7f5ec', color: '#1f6b3a', border: '1px solid #b8dcc6', borderRadius: 8, marginBottom: 12 }}>
                <div style={{ fontFamily: 'var(--pb-serif)', fontSize: 18, fontWeight: 600, marginBottom: 6 }}>
                  {lang === 'zh' ? '预约已提交 ✓' : 'Booking submitted ✓'}
                </div>
                <div style={{ fontSize: 13, lineHeight: 1.55 }}>
                  {lang === 'zh' ? '5 分钟内顾问助理将与你联系确认。' : 'A coordinator will confirm within 5 minutes.'}
                </div>
                <button
                  className="pb-btn pb-btn-primary"
                  style={{ width: '100%', padding: '12px', marginTop: 14 }}
                  onClick={() => navigateTo('/dashboard')}
                  data-testid="booking-go-dashboard"
                >
                  {lang === 'zh' ? '去我的中心查看' : 'View in dashboard'}
                </button>
              </div>
            ) : (
              <>
                {bookingError && (
                  <div data-testid="booking-error" style={{ padding: '10px 12px', background: '#fdecea', color: '#9b1c1c', border: '1px solid #f3b5b1', borderRadius: 8, marginBottom: 12, fontSize: 13 }}>
                    {bookingError}
                  </div>
                )}
                <button
                  className="pb-btn pb-btn-primary"
                  style={{ width: '100%', padding: '14px' }}
                  onClick={onConfirm}
                  disabled={submitting}
                  data-testid="booking-confirm"
                >
                  {submitting
                    ? (lang === 'zh' ? '提交中…' : 'Submitting…')
                    : (lang === 'zh' ? '确认预约' : 'Confirm booking')}
                  {!submitting && <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M13 5l7 7-7 7"/></svg>}
                </button>
                <div style={{ fontSize: 11, color: 'var(--pb-fg-muted)', textAlign: 'center', marginTop: 12, lineHeight: 1.55 }}>
                  {lang === 'zh' ? '提交后 5 分钟内顾问助理将与你联系确认。可在会议前 12 小时免费改期。' : 'A coordinator will confirm within 5 minutes. Free reschedule up to 12 hours before.'}
                </div>
              </>
            )}
          </div>
        </div>
      </section>

      <PBFooter />
    </div>
  );
};

window.BookingPage = BookingPage;
