/* wechat.jsx — 关注公众号登录
   订阅号无网页授权(OAuth)权限，故采用「带参二维码 + 关注事件回调」：
   后端生成 ticket → 换取带参临时二维码 → 微信推送 subscribe/SCAN 事件 → 轮询/长连接拿到 openid → 建立会话
   前端只展示四态状态机；真实实现见架构文档时序图。
*/

/* 登录态 Context */
const AuthCtx = React.createContext(null);
function useAuth() { return React.useContext(AuthCtx); }

function AuthProvider({ children }) {
  const [user, setUser] = React.useState(null);
  const [gate, setGate] = React.useState(null); // {reason, onDone}

  // 功能性门禁：只有需要时才弹登录
  const requireAuth = React.useCallback((reason, onDone) => {
    if (user) { onDone && onDone(); return true; }
    setGate({ reason, onDone });
    return false;
  }, [user]);

  const value = React.useMemo(() => ({ user, setUser, requireAuth }), [user, requireAuth]);
  return (
    <AuthCtx.Provider value={value}>
      {children}
      {gate && (
        <WechatLogin reason={gate.reason}
          onClose={() => setGate(null)}
          onSuccess={(u) => { setUser(u); const cb = gate.onDone; setGate(null); cb && setTimeout(cb, 60); }} />
      )}
    </AuthCtx.Provider>
  );
}

/* 四种状态：wait / scanned / subscribed(待确认) / ok */
const REASON_COPY = {
  favorite: ['先关注，再收藏', '收藏夹会同步到你的公众号，换设备也能找回。'],
  enroll: ['报名前确认一下身份', '关注后我们才能把课程通知、场地与材料发到你手上。'],
  book: ['预约需要留下联系方式', '关注后可接收催眠师的确认与提醒，也方便改期。'],
  download: ['资料仅向关注者开放', '操作手册、资源清单会直接推送到公众号。'],
  profile: ['登录你的账号', '查看预约、报名与收藏记录。'],
};

function WechatLogin({ reason = 'favorite', onClose, onSuccess }) {
  const [state, setState] = React.useState('wait'); // wait → scanned → subscribed → ok
  const [ticket] = React.useState(() => Math.random().toString(36).slice(2, 10).toUpperCase());
  const [copied, setCopied] = React.useState(false);
  const [name, setName] = React.useState('');
  const [err, setErr] = React.useState('');
  const [count, setCount] = React.useState(0);

  // 原型演示：模拟扫码推进（真实实现靠轮询 /api/auth/ticket/:id）
  React.useEffect(() => {
    if (state === 'ok') return;
    const seq = ['wait', 'scanned', 'subscribed'];
    const i = seq.indexOf(state);
    if (i < 0) return;
    const t = setTimeout(() => setState(seq[Math.min(i + 1, 2)]), state === 'wait' ? 3200 : 2600);
    return () => clearTimeout(t);
  }, [state]);

  React.useEffect(() => {
    if (state !== 'subscribed' && state !== 'ok') return;
    const t = setInterval(() => setCount((c) => c + 1), 1000);
    return () => clearInterval(t);
  }, [state]);

  const copy = REASON_COPY[reason] || REASON_COPY.favorite;

  const confirm = () => {
    if (!name.trim()) { setErr('请填写一个称呼，方便催眠师联系你'); return; }
    setState('ok');
    setTimeout(() => onSuccess({ name: name.trim(), openid: 'o' + ticket.toLowerCase(), joined: '2026-10-30', reason }), 1500);
  };

  return (
    <Modal onClose={onClose} max={440}>
      <div className="modal-hd">
        <div>
          <Eyebrow tone="gold" plain>{reason === 'profile' ? '账号' : '关注公众号 · 继续'}</Eyebrow>
          <h3 style={{ marginTop: 12, fontSize: 24, lineHeight: 1.28 }}>{copy[0]}</h3>
          <p style={{ marginTop: 8, fontSize: 13.5, color: 'var(--txt-2)', lineHeight: 1.65, fontWeight: 300 }}>{copy[1]}</p>
        </div>
        <button className="x-btn" onClick={onClose} aria-label="关闭">{Ico.close()}</button>
      </div>

      <div className="modal-bd">
        {state === 'ok' ? (
          <div style={{ textAlign: 'center', padding: '10px 0 4px' }}>
            <div className="checked">{Ico.check()}</div>
            <h4 style={{ marginTop: 18, fontSize: 20 }}>已关注 · 正在登录</h4>
            <p style={{ marginTop: 8, fontSize: 13.5, color: 'var(--txt-2)', fontWeight: 300 }}>
              欢迎，{name || '朋友'}。你的收藏、预约与报名会同步到这里。
            </p>
            <div style={{ marginTop: 18, display: 'flex', justifyContent: 'center', gap: 8 }}>
              <span className="tag wx">微信已绑定</span>
              <span className="tag ink">订阅号</span>
            </div>
          </div>
        ) : state === 'subscribed' ? (
          <div>
            <div className="checked" style={{ background: 'rgba(192,154,94,.12)', color: 'var(--gold-deep)' }}>
              <svg viewBox="0 0 24 24" width="26" height="26" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M12 3v13M7 11l5 5 5-5" strokeLinecap="round" strokeLinejoin="round" /></svg>
            </div>
            <h4 style={{ marginTop: 16, textAlign: 'center', fontSize: 18 }}>已关注，最后一步</h4>
            <p style={{ textAlign: 'center', marginTop: 8, fontSize: 13, color: 'var(--txt-2)', fontWeight: 300 }}>
              留一个称呼，方便催眠师与客服联系你。
            </p>
            <div className="field" style={{ marginTop: 22 }}>
              <label>你的称呼</label>
              <input value={name} onChange={(e) => { setName(e.target.value); setErr(''); }}
                placeholder="例如：王女士 / 小林" autoFocus />
              {err && <span className="hint" style={{ color: '#b4543f' }}>{err}</span>}
            </div>
            <div className="field">
              <label>希望被联系的时间（可选）</label>
              <select defaultValue="any">
                <option value="any">都可以</option>
                <option value="day">工作日白天</option>
                <option value="night">工作日晚间</option>
                <option value="weekend">周末</option>
              </select>
            </div>
            <Btn kind="primary" block onClick={confirm}>完成登录</Btn>
            <p style={{ marginTop: 12, fontSize: 11.5, color: 'var(--txt-3)', textAlign: 'center', lineHeight: 1.6 }}>
              我们只在你授权的范围内使用微信信息，不会在站内公开。
            </p>
          </div>
        ) : (
          <div>
            <div className="qr-frame">
              <QrCanvas ticket={ticket} />
              {state === 'scanned' && (
                <div className="qr-mask">
                  <div className="qr-ring" />
                  <div style={{ lineHeight: 1.6 }}>已扫码<br /><b style={{ fontWeight: 500 }}>请在微信中点击「关注」</b></div>
                </div>
              )}
            </div>

            <div className="steps">
              <span className={'step ' + (state === 'wait' ? 'on' : 'on')} />
              <span className={'step ' + (state !== 'wait' ? 'on' : '')} />
              <span className={'step ' + (state === 'scanned' ? 'on' : '')} />
            </div>

            <div style={{ textAlign: 'center', marginTop: 14, fontFamily: 'var(--f-mono)', fontSize: 10.5, letterSpacing: '.14em', color: 'var(--txt-3)' }}>
              {state === 'wait' ? '等待扫码' : '已扫码 · 等待关注'}
            </div>

            <ol style={{ marginTop: 20, display: 'flex', flexDirection: 'column', gap: 12 }}>
              {[
                ['打开微信', '扫一扫上面的二维码'],
                ['关注「量子催眠中国」', '关注后自动完成登录，无需填写密码'],
                ['回到本页', '页面会自己跳转，不用刷新'],
              ].map(([a, b], i) => (
                <li key={i} style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}>
                  <span style={{ flex: 'none', width: 19, height: 19, borderRadius: '50%', background: 'var(--cloud-2)', display: 'grid', placeItems: 'center', fontFamily: 'var(--f-mono)', fontSize: 10, color: 'var(--teal-700)', marginTop: 2 }}>{i + 1}</span>
                  <span style={{ fontSize: 13, lineHeight: 1.6, fontWeight: 300 }}>
                    <b style={{ fontWeight: 500, color: 'var(--ink)' }}>{a}</b>
                    <span style={{ color: 'var(--txt-3)' }}> — {b}</span>
                  </span>
                </li>
              ))}
            </ol>

            <div className="step-hint">
              <span style={{ flex: 'none', color: 'var(--teal-500)', marginTop: 1 }}>{Ico.wechat()}</span>
              <span>
                二维码 <b>3 分钟内有效</b>，过期请点下方刷新。已关注过的朋友扫码会直接登录。
              </span>
            </div>

            <div style={{ display: 'flex', gap: 10, marginTop: 16 }}>
              <Btn kind="ghost" size="sm" block onClick={() => setState('wait')}>{Ico.sync()}　刷新二维码</Btn>
            </div>

            {/* 原型演示用：手动推进状态 */}
            <div style={{ marginTop: 16, paddingTop: 14, borderTop: '1px solid var(--line-soft)' }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10 }}>
                <span style={{ fontFamily: 'var(--f-mono)', fontSize: 9.5, letterSpacing: '.14em', color: 'var(--txt-3)', textTransform: 'uppercase' }}>Prototype · 走完流程</span>
                <button onClick={() => setState(state === 'wait' ? 'scanned' : 'subscribed')}
                  style={{ border: 0, background: 'none', fontFamily: 'var(--f-mono)', fontSize: 10, letterSpacing: '.1em', color: 'var(--teal-700)', textTransform: 'uppercase', padding: 0 }}>
                  模拟下一步 →
                </button>
              </div>
            </div>
          </div>
        )}
      </div>
    </Modal>
  );
}

/* 页脚 / 文末的关注引导条 */
function FollowStrip({ compact }) {
  const { user } = useAuth();
  const [open, setOpen] = React.useState(false);
  return (
    <>
      <div className="dark noise" style={{ borderRadius: compact ? 'var(--radius)' : 0, padding: compact ? '26px 24px' : 'clamp(30px,4vw,54px) clamp(24px,4vw,52px)' }}>
        <div style={{ display: 'flex', gap: 28, alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap' }}>
          <div style={{ maxWidth: 560 }}>
            <Eyebrow>{user ? '已关注' : '订阅号 · 每周一篇'}</Eyebrow>
            <h3 style={{ marginTop: 14, fontSize: compact ? 19 : 'clamp(21px,2.2vw,28px)', lineHeight: 1.36 }}>
              {user ? '新的文章会推送到你的微信' : '关注公众号，新文章不必再来找'}
            </h3>
            <p style={{ marginTop: 10, fontSize: 13.5, color: 'var(--on-dark-2)', fontWeight: 300, lineHeight: 1.7 }}>
              {user ? '你也可以在公众号里直接回复"预约"，客服会在工作时间内答复。' : '文章、课程排期、来访者记录，都会先发在公众号。也顺手完成登录。'}
            </p>
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
            <div style={{ width: 74, height: 74, background: '#fff', borderRadius: 3, padding: 5, flex: 'none' }}>
              <QrCanvas ticket="FOLLOW01" />
            </div>
            {!user && <Btn kind="gold" size="sm" onClick={() => setOpen(true)}>扫码关注</Btn>}
          </div>
        </div>
      </div>
      {open && <WechatLogin reason="favorite" onClose={() => setOpen(false)} onSuccess={() => setOpen(false)} />}
    </>
  );
}

Object.assign(window, { AuthCtx, AuthProvider, useAuth, WechatLogin, FollowStrip });
