// 用户仪表盘
const DashboardPage = () => {
  const t = useT();
  const lang = useLang();
  const d = t.db;
  // PrivateRoute guarantees user is non-null by the time this renders, but keep
  // a soft fallback so a brief render race during sign-out doesn't crash.
  const auth = (typeof window.useAuth === 'function') ? window.useAuth() : null;
  const displayName = auth?.user?.name || (lang === 'zh' ? '同学' : 'there');

  // Reports list — fetched from /api/user/reports on mount. null = loading,
  // [] = empty (show CTA), [items] = render list. (M1.2)
  const [reports, setReports] = React.useState(null);
  React.useEffect(() => {
    let cancelled = false;
    fetch('/api/user/reports', { credentials: 'same-origin' })
      .then((r) => (r.ok ? r.json() : { reports: [] }))
      .then((data) => { if (!cancelled) setReports(Array.isArray(data.reports) ? data.reports : []); })
      .catch(() => { if (!cancelled) setReports([]); });
    return () => { cancelled = true; };
  }, []);

  // Bookings list — same pattern as reports. Empty until Phase 5 wires the
  // booking-create flow (M1.5).
  const [bookings, setBookings] = React.useState(null);
  React.useEffect(() => {
    let cancelled = false;
    fetch('/api/user/bookings', { credentials: 'same-origin' })
      .then((r) => (r.ok ? r.json() : { bookings: [] }))
      .then((data) => { if (!cancelled) setBookings(Array.isArray(data.bookings) ? data.bookings : []); })
      .catch(() => { if (!cancelled) setBookings([]); });
    return () => { cancelled = true; };
  }, []);

  return (
    <div className="pb-scroll" style={{ background: 'var(--pb-bg)' }}>
      <PBNav active="dashboard" />

      <section style={{ padding: '40px 48px 96px' }}>
        <div style={{ maxWidth: 1280, margin: '0 auto' }}>
          {/* Welcome strip */}
          <div className="pb-row" style={{ justifyContent: 'space-between', alignItems: 'flex-end', marginBottom: 32 }}>
            <div>
              <div className="pb-mono" style={{ fontSize: 11, color: 'var(--pb-gold-700)', letterSpacing: '0.1em', marginBottom: 8 }}>{lang === 'zh' ? '2026 年 4 月 30 日 · 周三' : 'WED · APR 30, 2026'}</div>
              <h1 className="pb-h1" style={{ fontSize: 44 }} data-testid="dashboard-greeting">
                {d.welcome}, <span style={{ fontStyle: 'italic' }}>{displayName}</span>
              </h1>
              <p style={{ color: 'var(--pb-fg-muted)', fontSize: 15, marginTop: 8 }}>
                {lang === 'zh' ? '距离美研秋季申请季开放还剩 142 天 · 你的申请准备度：68%' : '142 days until US grad apps open · Your readiness: 68%'}
              </p>
            </div>
            <div className="pb-row pb-gap-12">
              <button className="pb-btn pb-btn-ghost">{lang === 'zh' ? '生成新报告' : 'New report'}</button>
              <button className="pb-btn pb-btn-primary">{lang === 'zh' ? '联系主顾问' : 'Message lead'}</button>
            </div>
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 24 }}>
            <div className="pb-col pb-gap-24">
              {/* Progress + Timeline */}
              <div className="pb-card" style={{ padding: 28 }}>
                <div className="pb-row" style={{ justifyContent: 'space-between', marginBottom: 20 }}>
                  <h3 style={{ fontFamily: 'var(--pb-serif)', fontSize: 22, fontWeight: 600, margin: 0 }}>{d.progressTitle}</h3>
                  <span style={{ fontSize: 12, color: 'var(--pb-fg-muted)' }}>{lang === 'zh' ? '总进度' : 'Total'} 68%</span>
                </div>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 12 }}>
                  {[
                    { name: lang === 'zh' ? '初步评估' : 'Assessment', pct: 100 },
                    { name: lang === 'zh' ? '选校定位' : 'School list', pct: 100 },
                    { name: lang === 'zh' ? '标化考试' : 'Testing', pct: 90 },
                    { name: lang === 'zh' ? '科研活动' : 'Activities', pct: 60 },
                    { name: lang === 'zh' ? '文书材料' : 'Essays', pct: 25 },
                    { name: lang === 'zh' ? '申请投递' : 'Submit', pct: 0 },
                  ].map((s, i) => (
                    <div key={i}>
                      <div className="pb-progress-track" style={{ height: 5 }}>
                        <div className={`pb-progress-fill ${s.pct === 100 ? '' : 'gold'}`} style={{ width: `${s.pct}%`, background: s.pct === 100 ? 'var(--pb-success)' : s.pct > 0 ? 'var(--pb-gold-500)' : 'var(--pb-ink-100)' }}/>
                      </div>
                      <div style={{ fontSize: 12, marginTop: 8, fontWeight: 500 }}>{s.name}</div>
                      <div className="pb-mono" style={{ fontSize: 11, color: 'var(--pb-fg-muted)' }}>{s.pct}%</div>
                    </div>
                  ))}
                </div>
              </div>

              {/* Timeline */}
              <div className="pb-card" style={{ padding: 28 }}>
                <div className="pb-row" style={{ justifyContent: 'space-between', marginBottom: 20 }}>
                  <h3 style={{ fontFamily: 'var(--pb-serif)', fontSize: 22, fontWeight: 600, margin: 0 }}>{d.timeline}</h3>
                  <span style={{ fontSize: 12, color: 'var(--pb-fg-muted)' }}>2026 · {lang === 'zh' ? '12 个月规划' : '12-month plan'}</span>
                </div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
                  {[
                    { date: lang === 'zh' ? '5 月 · 本月' : 'MAY · this month', items: [lang === 'zh' ? '完成主文书初稿（PS）' : 'Finish PS draft', lang === 'zh' ? 'TOEFL 二刷' : 'TOEFL retake', lang === 'zh' ? '联络第二位推荐人' : 'Contact 2nd recommender'], status: 'active' },
                    { date: lang === 'zh' ? '6–7 月' : 'JUN–JUL', items: [lang === 'zh' ? '海外暑研项目（UCLA）' : 'Summer research at UCLA', lang === 'zh' ? '主文书第 3–5 稿' : 'PS rev 3–5'], status: 'upcoming' },
                    { date: lang === 'zh' ? '8 月' : 'AUG', items: [lang === 'zh' ? '小文书启动 · 8 所院校' : 'Supplements · 8 schools', lang === 'zh' ? '推荐信定稿' : 'Finalize rec letters'], status: 'upcoming' },
                    { date: lang === 'zh' ? '9 月 · 申请季开放' : 'SEP · App opens', items: [lang === 'zh' ? '提交早申院校（ED/EA）' : 'Submit ED/EA', lang === 'zh' ? '面试模拟轮一' : 'Mock interview round 1'], status: 'future' },
                    { date: lang === 'zh' ? '12 月 · ED 放榜' : 'DEC · ED results', items: [lang === 'zh' ? 'ED 录取或转 RD' : 'ED admit / pivot to RD'], status: 'future' },
                  ].map((row, i) => (
                    <div key={i} style={{ display: 'grid', gridTemplateColumns: '160px 1fr', gap: 16, padding: '12px 0', borderBottom: i < 4 ? '1px dashed var(--pb-border)' : 'none' }}>
                      <div className="pb-mono" style={{ fontSize: 11, fontWeight: 600, color: row.status === 'active' ? 'var(--pb-gold-700)' : 'var(--pb-fg-muted)', letterSpacing: '0.06em', alignSelf: 'flex-start', paddingTop: 4 }}>
                        {row.status === 'active' && <span style={{ display: 'inline-block', width: 6, height: 6, background: 'var(--pb-gold-500)', borderRadius: '50%', marginRight: 6 }}/>}
                        {row.date}
                      </div>
                      <ul style={{ margin: 0, padding: 0, listStyle: 'none', display: 'flex', flexDirection: 'column', gap: 6 }}>
                        {row.items.map((it, j) => (
                          <li key={j} style={{ display: 'flex', gap: 8, fontSize: 14, color: row.status === 'future' ? 'var(--pb-fg-muted)' : 'var(--pb-fg)' }}>
                            <span style={{ color: 'var(--pb-gold-700)' }}>·</span>{it}
                          </li>
                        ))}
                      </ul>
                    </div>
                  ))}
                </div>
              </div>

              {/* Tasks */}
              <div className="pb-card" style={{ padding: 28 }}>
                <div className="pb-row" style={{ justifyContent: 'space-between', marginBottom: 20 }}>
                  <h3 style={{ fontFamily: 'var(--pb-serif)', fontSize: 22, fontWeight: 600, margin: 0 }}>{d.tasks}</h3>
                  <span style={{ fontSize: 12, color: 'var(--pb-fg-muted)' }}>4 / 7 {lang === 'zh' ? '已完成' : 'done'}</span>
                </div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                  {[
                    { done: true, task: lang === 'zh' ? '与王老师 1v1 周会（已完成 4/30）' : '1:1 with Wang (done 4/30)', tag: lang === 'zh' ? '会议' : 'Meeting' },
                    { done: true, task: lang === 'zh' ? '提交 PS 第 2 稿' : 'Submit PS draft v2', tag: lang === 'zh' ? '文书' : 'Essay' },
                    { done: true, task: lang === 'zh' ? '回复 UCLA 暑研接收邮件' : 'Reply to UCLA summer-research offer', tag: lang === 'zh' ? '科研' : 'Research' },
                    { done: true, task: lang === 'zh' ? '更新选校列表（去掉 UCSD）' : 'Update school list (drop UCSD)', tag: lang === 'zh' ? '选校' : 'Schools' },
                    { done: false, task: lang === 'zh' ? '联系第二位推荐人（张教授）' : 'Contact 2nd recommender (Prof. Zhang)', tag: lang === 'zh' ? '推荐信' : 'Rec letter' },
                    { done: false, task: lang === 'zh' ? '完成 TOEFL 模考一套' : 'Take 1 TOEFL mock', tag: lang === 'zh' ? '考试' : 'Test' },
                    { done: false, task: lang === 'zh' ? '签证材料预审 · 上传护照' : 'Visa prep · upload passport', tag: lang === 'zh' ? '签证' : 'Visa' },
                  ].map((t, i) => (
                    <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '10px 14px', background: t.done ? 'var(--pb-surface-alt)' : 'transparent', border: '1px solid var(--pb-border)', borderRadius: 'var(--pb-radius)' }}>
                      <div style={{
                        width: 18, height: 18, borderRadius: 4,
                        border: `1.5px solid ${t.done ? 'var(--pb-success)' : 'var(--pb-border-strong)'}`,
                        background: t.done ? 'var(--pb-success)' : 'transparent',
                        display: 'grid', placeItems: 'center', flexShrink: 0
                      }}>
                        {t.done && <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="3"><path d="M20 6 9 17l-5-5"/></svg>}
                      </div>
                      <span style={{ flex: 1, fontSize: 14, textDecoration: t.done ? 'line-through' : 'none', color: t.done ? 'var(--pb-fg-muted)' : 'var(--pb-fg)' }}>{t.task}</span>
                      <span className="pb-tag" style={{ fontSize: 10 }}>{t.tag}</span>
                    </div>
                  ))}
                </div>
              </div>
            </div>

            {/* Right column */}
            <div className="pb-col pb-gap-24">
              {/* Lead counselor */}
              <div className="pb-card" style={{ padding: 24 }}>
                <div className="pb-eyebrow" style={{ marginBottom: 14 }}>{d.consultants}</div>
                <div className="pb-row pb-gap-12" style={{ marginBottom: 16 }}>
                  <div className="pb-img-placeholder" style={{ width: 56, height: 56, borderRadius: '50%' }}>WS</div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontFamily: 'var(--pb-serif)', fontSize: 18, fontWeight: 600 }}>{lang === 'zh' ? '王思琪' : 'Siqi Wang'}</div>
                    <div style={{ fontSize: 12, color: 'var(--pb-gold-700)' }}>{lang === 'zh' ? '主顾问 · MIT MS' : 'Lead · MIT MS'}</div>
                    <div style={{ fontSize: 11, color: 'var(--pb-success)', marginTop: 4 }}>● {lang === 'zh' ? '在线' : 'Online'}</div>
                  </div>
                </div>
                <div style={{ display: 'flex', gap: 8 }}>
                  <button className="pb-btn pb-btn-primary pb-btn-sm" style={{ flex: 1 }}>{lang === 'zh' ? '消息' : 'Message'}</button>
                  <button className="pb-btn pb-btn-ghost pb-btn-sm" style={{ flex: 1 }}>{lang === 'zh' ? '预约会议' : 'Book'}</button>
                </div>
                <div style={{ height: 1, background: 'var(--pb-border)', margin: '20px 0' }}/>
                <div style={{ fontSize: 12, color: 'var(--pb-fg-muted)' }}>
                  <div style={{ marginBottom: 8 }}>{lang === 'zh' ? '文书顾问' : 'Writing coach'} · {lang === 'zh' ? '苏宛清' : 'Wanqing Su'}</div>
                  <div>{lang === 'zh' ? '面试教练' : 'Interview coach'} · {lang === 'zh' ? '林皓' : 'Hao Lin'}</div>
                </div>
              </div>

              {/* Messages */}
              <div className="pb-card" style={{ padding: 24 }}>
                <div className="pb-row" style={{ justifyContent: 'space-between', marginBottom: 14 }}>
                  <div className="pb-eyebrow">{d.messages}</div>
                  <span style={{ fontSize: 11, color: 'var(--pb-danger)', fontWeight: 600 }}>3 {lang === 'zh' ? '未读' : 'unread'}</span>
                </div>
                {[
                  { who: lang === 'zh' ? '王思琪' : 'Siqi Wang', msg: lang === 'zh' ? '看了你 PS 第二稿，结构稳了。我们周五讨论…' : 'Read your PS v2 — structure is solid. Let\'s discuss Friday…', time: '14:32', unread: true },
                  { who: lang === 'zh' ? '苏宛清' : 'Wanqing Su', msg: lang === 'zh' ? '推荐信策略文档已发送，注意查收。' : 'Rec strategy doc sent, please check.', time: '12:08', unread: true },
                  { who: lang === 'zh' ? '系统通知' : 'System', msg: lang === 'zh' ? 'UCLA 暑研接收信已回复确认。' : 'UCLA summer offer confirmed.', time: '昨天', unread: true },
                ].map((m, i) => (
                  <div key={i} style={{ padding: '12px 0', borderTop: i > 0 ? '1px solid var(--pb-border)' : 'none' }}>
                    <div className="pb-row" style={{ justifyContent: 'space-between', marginBottom: 4 }}>
                      <span style={{ fontSize: 13, fontWeight: 600 }}>{m.who} {m.unread && <span style={{ display: 'inline-block', width: 6, height: 6, background: 'var(--pb-gold-500)', borderRadius: '50%', marginLeft: 4 }}/>}</span>
                      <span style={{ fontSize: 11, color: 'var(--pb-fg-muted)' }}>{m.time}</span>
                    </div>
                    <div style={{ fontSize: 12, color: 'var(--pb-fg-muted)', lineHeight: 1.4 }}>{m.msg}</div>
                  </div>
                ))}
              </div>

              {/* Reports — driven by /api/user/reports (M1.2) */}
              <div className="pb-card" style={{ padding: 24 }} data-testid="dashboard-reports">
                <div className="pb-eyebrow" style={{ marginBottom: 14 }}>{d.reports}</div>
                {reports === null ? (
                  <div data-testid="dashboard-reports-loading" style={{ fontSize: 12, color: 'var(--pb-fg-muted)', padding: '12px 0' }}>
                    {d.reportsLoading}
                  </div>
                ) : reports.length === 0 ? (
                  <div data-testid="dashboard-reports-empty" style={{ padding: '8px 0' }}>
                    <div style={{ fontFamily: 'var(--pb-serif)', fontSize: 16, fontWeight: 600, marginBottom: 6 }}>
                      {d.reportsEmpty.title}
                    </div>
                    <div style={{ fontSize: 12, color: 'var(--pb-fg-muted)', lineHeight: 1.55, marginBottom: 14 }}>
                      {d.reportsEmpty.hint}
                    </div>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                      <button
                        type="button"
                        className="pb-btn pb-btn-primary pb-btn-sm"
                        onClick={() => navigateTo('/gaokao')}
                        data-testid="dashboard-reports-cta-gaokao"
                      >{d.reportsEmpty.ctaGaokao}</button>
                      <button
                        type="button"
                        className="pb-btn pb-btn-ghost pb-btn-sm"
                        onClick={() => navigateTo('/eval')}
                        data-testid="dashboard-reports-cta-eval"
                      >{d.reportsEmpty.ctaEval}</button>
                    </div>
                  </div>
                ) : (
                  reports.map((r, i) => (
                    <div key={r.id || i} style={{ padding: '12px 0', borderTop: i > 0 ? '1px solid var(--pb-border)' : 'none', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                      <div>
                        <div style={{ fontSize: 13, fontWeight: 500 }}>{r.name}</div>
                        <div className="pb-mono" style={{ fontSize: 11, color: 'var(--pb-fg-muted)' }}>{r.date}</div>
                      </div>
                      <span style={{ padding: '2px 8px', fontSize: 10, fontWeight: 700, borderRadius: 3, background: r.tag === 'PAID' ? 'var(--pb-gold-100)' : 'var(--pb-navy-50)', color: r.tag === 'PAID' ? 'var(--pb-gold-700)' : 'var(--pb-navy-700)', fontFamily: 'var(--pb-mono)' }}>{r.tag}</span>
                    </div>
                  ))
                )}
              </div>

              {/* Bookings — driven by /api/user/bookings (M1.5) */}
              <div className="pb-card" style={{ padding: 24 }} data-testid="dashboard-bookings">
                <div className="pb-eyebrow" style={{ marginBottom: 14 }}>{d.bookings}</div>
                {bookings === null ? (
                  <div data-testid="dashboard-bookings-loading" style={{ fontSize: 12, color: 'var(--pb-fg-muted)', padding: '12px 0' }}>
                    {d.bookingsLoading}
                  </div>
                ) : bookings.length === 0 ? (
                  <div data-testid="dashboard-bookings-empty" style={{ padding: '8px 0' }}>
                    <div style={{ fontFamily: 'var(--pb-serif)', fontSize: 16, fontWeight: 600, marginBottom: 6 }}>
                      {d.bookingsEmpty.title}
                    </div>
                    <div style={{ fontSize: 12, color: 'var(--pb-fg-muted)', lineHeight: 1.55, marginBottom: 14 }}>
                      {d.bookingsEmpty.hint}
                    </div>
                    <button
                      type="button"
                      className="pb-btn pb-btn-primary pb-btn-sm"
                      onClick={() => navigateTo('/booking')}
                      data-testid="dashboard-bookings-cta"
                      style={{ width: '100%' }}
                    >{d.bookingsEmpty.cta}</button>
                  </div>
                ) : (
                  bookings.map((b, i) => {
                    // booking shape (from /api/booking/create): advisorName/typeName are { zh, en } objects
                    const advisorLabel = (b.advisorName && (b.advisorName[lang] || b.advisorName.zh)) || b.advisor || '';
                    const typeLabel = (b.typeName && (b.typeName[lang] || b.typeName.zh)) || '';
                    const when = [b.date, b.time].filter(Boolean).join(' · ') || b.time || b.date || '';
                    return (
                      <div key={b.id || i} style={{ padding: '12px 0', borderTop: i > 0 ? '1px solid var(--pb-border)' : 'none', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8 }}>
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <div style={{ fontSize: 13, fontWeight: 500, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                            {advisorLabel}{typeLabel ? <span style={{ color: 'var(--pb-fg-muted)', fontWeight: 400 }}> · {typeLabel}</span> : null}
                          </div>
                          <div className="pb-mono" style={{ fontSize: 11, color: 'var(--pb-fg-muted)' }}>{when}</div>
                        </div>
                        <span style={{ padding: '2px 8px', fontSize: 10, fontWeight: 700, borderRadius: 3, background: 'var(--pb-navy-50)', color: 'var(--pb-navy-700)', fontFamily: 'var(--pb-mono)' }}>{b.status || 'BOOKED'}</span>
                      </div>
                    );
                  })
                )}
              </div>
            </div>
          </div>
        </div>
      </section>

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

window.DashboardPage = DashboardPage;
