/* ============================================================
   ROOY · HOME helpers + 01a 首次登录空状态
   ───────────────────────────────────────────────────────────
   Home 共用 helpers（SegmentedProgress / SeasonStreak / TickUp）+
   01a 空状态屏。helpers 全局挂出，供其它 home 文件复用。

   01a 设计意图：新用户从 onboarding 出来落到 Home。**照搬 01q
   （HomeScreenQ，最终定稿）的近白骨架**——header → 雪季 → ROOY 指数
   hero → 正在学习，逐块降级到"还没发生"：
     · 雪季卡：同 01q SeasonCardF 结构，统计 «—»、skyline 全空、
       最近一次 = 还未开始。
     · ROOY 指数 hero：GhostGem（01q HexGemBadge 的「满量程骨架」层
       单独拎出来当主角 + 虚线 rim = 待激活），浮白卡单行号召「第一趟
       后出指数」。tap → presession（开始第一趟），不是 review。
     · 正在学习：onboarding 选的立刃路径，doneCount=0。
   营造"框架已就位、等你第一趟点亮"，而非"暂无数据"。
   ============================================================ */

/* SegmentedProgress — path bar used on Home + Course.
   Done segments are inked, the current segment is ROOY-color and
   slightly taller (6 vs 4 pt) so it reads as the active step. */
function SegmentedProgress({ nodes, doneCount }) {
  return (
    <div style={{ marginTop: 14, display: 'flex', gap: 5 }}>
      {Array.from({ length: nodes }).map((_, i) => {
        const done = i < doneCount;
        const cur = i === doneCount;
        const h = cur ? 6 : 4;
        const bg = done ? R.ink : cur ? R.rooy : R.hair;
        return (
          <div key={i} style={{
            flex: 1, height: h, borderRadius: h / 2,
            background: bg, alignSelf: 'center',
          }}/>
        );
      })}
    </div>
  );
}

/* SeasonStreak — thin strip of weekly cells across the season.
   24 weeks (Nov → Apr); filled weeks at 55% white, empty at 10%.
   Reads as a "you skied here, here, here" rhythm without labels.
   Pass sessions=new Set() to render an all-empty strip (FirstRun).
   Defaults assume ink hero surface; on white cards (01b) pass
   ink-based onColor / offColor tokens. */
const DEFAULT_SESSIONS = new Set([1, 3, 4, 6, 8, 11, 13, 15, 17, 19, 21, 23]);
function SeasonStreak({
  sessions = DEFAULT_SESSIONS,
  onColor = 'rgba(255,255,255,0.82)',
  offColor = 'rgba(255,255,255,0.12)',
}) {
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 3, height: 24 }}>
      {Array.from({ length: 24 }).map((_, i) => {
        const on = sessions.has(i);
        return (
          <div key={i} style={{
            flex: 1,
            height: on ? 18 : 7,
            borderRadius: 1.5,
            background: on ? onColor : offColor,
          }}/>
        );
      })}
    </div>
  );
}

/* TickUp — count-up animation, used on hero numerals.
   Plays once per mount over ~900ms with ease-out. Honors prefers-
   reduced-motion (skips to final value). */
function TickUp({ to, duration = 900 }) {
  const [n, setN] = React.useState(to);
  React.useEffect(() => {
    if (typeof window === 'undefined') return;
    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    let raf;
    const start = performance.now();
    setN(0);
    const tick = (now) => {
      const t = Math.min(1, (now - start) / duration);
      const eased = 1 - Math.pow(1 - t, 3);
      setN(Math.round(eased * to));
      if (t < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [to, duration]);
  return n;
}

/* GhostGem — 01a 空状态的「待激活」宝石。直接照搬 01q HexGemBadge 的
   「满量程骨架」层（细 rooy rim + 6 轴心连线）+ rooy 辉光底盘——即 01q
   里被琢面盖住、只在负空间露出的那层骨架，这里单独拎出来当主角：脚手架
   已就位、数据还没填。rim 用虚线（pending 信号），不加琢面/高光（那是
   「已有数据」才有的光彩）。concept：六轴框架等你第一趟来点亮。 */
function GhostGem({ size = 116 }) {
  const uid = React.useId().replace(/[:]/g, '');
  const cx = 50, cy = 50, rOut = 47;
  const ang = (i) => -Math.PI / 2 + i * (Math.PI / 3);
  const poly = (r) => Array.from({ length: 6 }, (_, i) =>
    [cx + Math.cos(ang(i)) * r, cy + Math.sin(ang(i)) * r].map(n => n.toFixed(2)).join(',')).join(' ');
  const rim = 'color-mix(in srgb, var(--r-rooy) 42%, transparent)';
  const spoke = 'color-mix(in srgb, var(--r-rooy) 26%, transparent)';
  return (
    <svg width={size} height={size} viewBox="0 0 100 100" style={{ flexShrink: 0, display: 'block', overflow: 'visible' }}>
      <defs>
        <radialGradient id={`gg${uid}`} cx="50" cy="50" r="54" gradientUnits="userSpaceOnUse">
          <stop offset="0%"   stopColor="var(--r-rooy)" stopOpacity="0.15"/>
          <stop offset="60%"  stopColor="var(--r-rooy)" stopOpacity="0.04"/>
          <stop offset="100%" stopColor="var(--r-rooy)" stopOpacity="0"/>
        </radialGradient>
      </defs>
      {/* rooy 辉光底盘 — 同 01q，浮起感（更弱） */}
      <circle cx={cx} cy={cy} r="54" fill={`url(#gg${uid})`}/>
      {/* 满量程骨架：极淡填底 + 虚线 rim（pending）+ 6 轴心连线 */}
      <polygon points={poly(rOut)} fill="color-mix(in srgb, var(--r-rooy) 6%, transparent)"/>
      <polygon points={poly(rOut)} fill="none" stroke={rim} strokeWidth="1.1"
        strokeDasharray="3 3.5" strokeLinejoin="round"/>
      {Array.from({ length: 6 }, (_, i) => {
        const a = ang(i);
        return <line key={i} x1={cx} y1={cy}
          x2={cx + Math.cos(a) * rOut} y2={cy + Math.sin(a) * rOut}
          stroke={spoke} strokeWidth="0.7"/>;
      })}
    </svg>
  );
}

/* EmptySkyline — 01a 雪季卡的空 skyline：24 根 hair2 细条（全空周），
   对位 01q SeasonSkylineF 的 24 格节奏，但无任何 data 色——读作「地面
   已画好、还没滑过」。 */
function EmptySkyline() {
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 3, height: 36 }}>
      {Array.from({ length: 24 }, (_, i) => (
        <div key={i} style={{ flex: 1, height: 3, borderRadius: 1.5, background: R.hair2 }}/>
      ))}
    </div>
  );
}

/* SeasonCardEmpty — 01a 雪季卡：照搬 01q SeasonCardF 结构（SectionTitle
   + 白卡 + 3-up 统计 + skyline + 最近一次），每格降级到空态——统计 «—»、
   skyline 全空、最近一次 = 还未开始。tap → 09 history。 */
function SeasonCardEmpty({ onNav }) {
  return (
    <React.Fragment>
      <SectionTitle meta="2025 — 26" action={true} onAction={() => onNav && onNav('history')}>
        雪季
      </SectionTitle>
      <div style={{ height: 8 }}/>
      <InsetGroup style={{ boxShadow: Shadow.cardSoft }}>
        <div onClick={() => onNav && onNav('history')} style={{ padding: '16px 20px', cursor: 'pointer' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
            <CCond l="滑行" v="—" c={R.ink4} lc={R.ink3}/>
            <CCond l="里程" v="—" c={R.ink4} lc={R.ink3}/>
            <CCond l="垂降" v="—" c={R.ink4} lc={R.ink3}/>
          </div>
          <div style={{ marginTop: 18 }}>
            <EmptySkyline/>
            <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 6 }}>
              <span style={{ ...T.caption1, color: R.ink3 }}>11 月</span>
              <span style={{ ...T.caption1, color: R.ink3 }}>4 月</span>
            </div>
          </div>
          <div style={{ margin: '14px 0 12px' }}><Hair/></div>
          <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
            <span style={{ ...T.footnote, color: R.ink3 }}>最近一次</span>
            <span style={{ ...T.footnote, color: R.ink3 }}>还未开始</span>
          </div>
        </div>
      </InsetGroup>
    </React.Fragment>
  );
}

/* IQHeroEmpty — 01a 的 ROOY 指数 hero，照搬 01q IQHeroQ 的三段（pill 行 +
   主体 + 浮白卡），无数据态：
   - 主体：GhostGem 居中（占 01q 里 173 数字 + 徽章的视觉位置）+ 下方铭牌
     「六项能力 / 第一趟后测出」。
   - 浮白卡：单行 ROOY 号召（rooy pip + 一句话），替 01q 的立刃/压力 +
     判断行——新用户还没有分项可展示。
   tap 整块 → presession（开始第一趟），不是 review（还没得复盘）。 */
function IQHeroEmpty({ onNav }) {
  return (
    <div onClick={() => onNav && onNav('presession')} style={{ cursor: 'pointer' }}>
      <div style={{ margin: '0 20px 8px 16px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <StatusBadge tone="rooy">ROOY 指数</StatusBadge>
        <span style={{ ...T.subhead, color: R.ink3 }}>›</span>
      </div>

      <div style={{ margin: '0 16px', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
        <GhostGem size={116}/>
        <div style={{ ...T.subhead, fontWeight: 600, color: R.ink2, marginTop: 4 }}>六项能力</div>
        <div style={{ ...T.caption1, color: R.ink3, marginTop: 2 }}>第一趟后测出</div>
      </div>

      <InsetGroup style={{ marginTop: 12, boxShadow: Shadow.lift }}>
        <div style={{ padding: '14px 16px', display: 'flex', gap: 10, alignItems: 'flex-start' }}>
          <span style={{
            display: 'inline-block', width: 6, height: 6, borderRadius: '50%',
            background: R.rooy, flexShrink: 0, marginTop: 7,
          }}/>
          <p style={{ ...T.subhead, color: R.ink2, flex: 1 }}>
            第一趟滑行后，ROOY 给你<span style={{ color: R.ink, fontWeight: 600 }}>第一份指数</span>。
          </p>
        </div>
      </InsetGroup>
    </div>
  );
}

/* LearningCardEmpty — 01a 正在学习卡：照搬 01q LearningCardF（SectionTitle
   + 白卡 + 课程头 + SegmentedProgress + 说明），空态绑定 onboarding 选的
   立刃路径，doneCount=0（将开始）。tap → 06 course。 */
function LearningCardEmpty({ onNav }) {
  return (
    <React.Fragment>
      <SectionTitle action={true} onAction={() => onNav && onNav('course')}>正在学习</SectionTitle>
      <div style={{ height: 8 }}/>
      <div onClick={() => onNav && onNav('course')} style={{ cursor: 'pointer' }}>
        <InsetGroup style={{ boxShadow: Shadow.cardSoft }}>
          <div style={{ padding: '14px 16px 16px' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span style={{ ...T.headline, color: R.ink }}>立刃路径</span>
              <StatusBadge tone="rooy" size="md">ROOY 推荐</StatusBadge>
            </div>
            <div style={{ marginTop: 4 }}>
              <SegmentedProgress nodes={5} doneCount={0}/>
            </div>
            <p style={{ ...T.body, color: R.ink3, marginTop: 12 }}>
              起步时把更多重心放在脚趾，感受雪板的反馈
            </p>
          </div>
        </InsetGroup>
      </div>
    </React.Fragment>
  );
}

/* HomeScreenFirstRun — 01a 首次登录空状态。
   骨架与 01q HomeScreenQ 1:1：header → 雪季 → ROOY 指数 hero → 正在学习，
   每块换成空态变体（SeasonCardEmpty / IQHeroEmpty / LearningCardEmpty）。 */
function HomeScreenFirstRun({ onNav }) {
  return (
    <div style={{
      height: '100%', display: 'flex', flexDirection: 'column',
      background: R.bg, position: 'relative', color: R.ink, ...T.subhead,
    }}>
      <StatusBar/>

      <div style={{ flex: 1, overflowY: 'auto', position: 'relative', paddingBottom: 100 }}>

        {/* ── Header — 同 01q ────────────────── */}
        <div style={{
          padding: '8px 20px 0',
          display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start',
        }}>
          <div style={{ paddingTop: 4 }}>
            <p style={{ ...T.footnote, color: R.ink3, marginBottom: 4 }}>5 月 3 日 · 周五</p>
            <h1 style={{ ...T.title, color: R.ink }}>你好，Yuki</h1>
          </div>
          <UserAvatar onClick={() => onNav && onNav('settings')} style={{ marginTop: 12 }}/>
        </div>

        <div style={{ height: 18 }}/>

        <SeasonCardEmpty onNav={onNav}/>
        <div style={{ height: 24 }}/>

        <IQHeroEmpty onNav={onNav}/>
        <div style={{ height: 24 }}/>

        <LearningCardEmpty onNav={onNav}/>
        <div style={{ height: 24 }}/>
      </div>

      <TabBar active="home" onTab={(tab) => onNav && onNav(tab)}/>
    </div>
  );
}

Object.assign(window, {
  HomeScreenFirstRun, SegmentedProgress, SeasonStreak, TickUp,
  GhostGem, EmptySkyline, SeasonCardEmpty, IQHeroEmpty, LearningCardEmpty,
});
