/* page-timeline.jsx — （4）Timeline：时间条 + 复述 + REMEMBERED THIS DAY
   新增：日历按钮、事件卡片 [ Replay ]、左下角「Replay this day」小电视、Done by AI 筛选（带 HET）、整窗回放 */
/* global React */
window.P21 = window.P21 || {};
(() => {
  const { C, SERIF, MONO, useP, Label, Seg, Tip, D } = window.P21;

  /* 2026 年 9 月 1 日是星期二 */
  const WD = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
  const weekday = (n) => WD[(n) % 7]; // n=1 → Tue
  const dayLabel = (n) => n === D.today ? 'Today' : n === D.today - 1 ? 'Yesterday' : `${weekday(n)}, Sep ${n}`;
  const pct = (t) => ((t - 8) / 15 * 100) + '%';
  const clock = (t) => { const h = Math.floor(t), m = Math.floor((t - h) * 60); return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`; };

  /* 某一天的数据 */
  function dayData(n) {
    if (n === D.today) return { mems: D.todayMems, summary: D.todaySummary, segs: D.segsToday };
    if (n === D.today - 1) return { mems: D.dayMems.filter(m => !m.ai), summary: 'A quiet day: one decision, and an evening of reading.', segs: D.segs };
    if (D.recordDays.includes(n)) return { mems: D.dayMems, summary: D.daySummary, segs: D.segs };
    return null;
  }
  /* 时间条上某一刻的画面 */
  function frameAt(day, t) {
    const dd = dayData(day) || { mems: [], segs: [] };
    const seg = dd.segs.find(([a, b]) => t >= a && t <= b);
    const near = dd.mems.slice().sort((x, y) => Math.abs(x.at - t) - Math.abs(y.at - t))[0];
    if (!seg || !near) return { app: 'Not recorded', color: C.muted, time: clock(t), title: 'Screen was off', body: 'Nothing captured at this moment.' };
    return { app: D.apps[seg[2]][0], color: D.apps[seg[2]][1], time: clock(t), title: near.title, body: near.body };
  }

  /* 小日历面板 */
  function Calendar({ day, onPick }) {
    const cells = [null, ...Array.from({ length: 30 }, (_, i) => i + 1)]; // 前面空 1 格（周一）
    return (
      <div onClick={(e) => e.stopPropagation()}
        style={{ position: 'absolute', top: 40, right: 0, width: 300, background: '#fff', border: `1px solid ${C.border}`, borderRadius: 10, padding: '14px 16px', boxShadow: '0 16px 40px rgba(15,15,15,.16)', zIndex: 10, animation: 'p21pop .15s ease-out' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: 13.5, fontWeight: 500 }}>
          <span title="Earlier months" style={{ color: C.faint, cursor: 'pointer', padding: '0 6px' }}>‹</span><span>September</span><span style={{ color: '#D3D1CB', padding: '0 6px' }}>›</span>
        </div>
        <div style={{ marginTop: 10, display: 'grid', gridTemplateColumns: 'repeat(7,1fr)', textAlign: 'center', fontSize: 10.5, color: C.faint }}>
          {['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'].map(w => <span key={w}>{w}</span>)}
        </div>
        <div style={{ marginTop: 4, display: 'grid', gridTemplateColumns: 'repeat(7,1fr)', gap: 2 }}>
          {cells.map((n, i) => {
            if (!n) return <span key={'e' + i} />;
            const on = n === day, rec = D.recordDays.includes(n);
            return (
              <div key={n} onClick={() => onPick(n)} className={on ? '' : 'p21-h-soft'}
                style={{ height: 34, borderRadius: 6, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', background: on ? C.ink : 'transparent', color: on ? '#fff' : C.ink, fontSize: 13 }}>
                <span>{n}</span>
                <span style={{ width: 4, height: 4, borderRadius: '50%', marginTop: 1, background: rec ? (on ? '#fff' : C.green) : 'transparent' }} />
              </div>
            );
          })}
        </div>
        <div style={{ marginTop: 10, fontSize: 12, color: C.faint, display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{ width: 4, height: 4, borderRadius: '50%', background: C.green }} />has records
        </div>
      </div>
    );
  }

  function TimelinePage({ mainRef }) {
    const { s, set } = useP();
    const [hoverT, setHoverT] = React.useState(null);
    const [hetTip, setHetTip] = React.useState(null);
    const day = s.day, dd = dayData(day);
    const ai = s.tlFilter === 'AI';
    const mems = dd ? (ai ? dd.mems.filter(m => m.ai) : dd.mems) : [];
    const hetSum = dd ? dd.mems.filter(m => m.ai).reduce((a, m) => a + m.het, 0) : 0;
    const cardRefs = React.useRef({});

    /* 从 Home 的最近记忆跳过来：滚到这条事件并闪一下 */
    React.useEffect(() => {
      if (!s.highlight) return;
      const el = cardRefs.current[s.highlight];
      if (el && mainRef.current) mainRef.current.scrollTo({ top: el.offsetTop - 120, behavior: 'smooth' });
      const t = setTimeout(() => set({ highlight: null }), 2400);
      return () => clearTimeout(t);
    }, [s.highlight]);

    const pickDay = (n) => { set({ day: n, cal: false }); setHoverT(null); };

    return (
      <div onClick={() => s.cal && set({ cal: false })} style={{ maxWidth: 900, margin: '0 auto', padding: '52px 48px 260px' }}>
        <div style={{ fontSize: 32, fontWeight: 700, letterSpacing: '-.02em', lineHeight: 1.2 }}>Timeline</div>
        <div style={{ marginTop: 6, fontSize: 15, color: C.muted }}>Day by day, what happened and what it kept.</div>

        {/* 视图切换 + 日期切换 */}
        <div style={{ marginTop: 26, display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 }}>
          <span title="Week and Month are still to be decided" style={{ display: 'inline-flex', padding: 2, background: C.soft, borderRadius: 6, fontSize: 13 }}>
            <span style={{ padding: '5px 14px', borderRadius: 5, background: '#fff', boxShadow: '0 1px 2px rgba(15,15,15,.08)' }}>Day</span>
            <span style={{ padding: '5px 14px', color: '#B5B4B0' }}>Week</span>
            <span style={{ padding: '5px 14px', color: '#B5B4B0' }}>Month</span>
          </span>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, position: 'relative' }}>
            <span onClick={() => day > 1 && pickDay(day - 1)} className="p21-h-soft" style={{ width: 30, height: 30, display: 'flex', alignItems: 'center', justifyContent: 'center', borderRadius: 6, cursor: 'pointer', fontSize: 18, color: day > 1 ? C.ink : '#D3D1CB' }}>‹</span>
            <span onClick={(e) => { e.stopPropagation(); set({ cal: !s.cal }); }} className="p21-h-soft"
              style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '6px 12px', border: `1px solid ${C.border}`, borderRadius: 6, background: '#fff', cursor: 'pointer', fontSize: 13.5, fontWeight: 500 }}>
              <svg width="15" height="15" viewBox="0 0 24 24" style={{ fill: 'none', stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round' }}><path d="M4 6h16v14H4zM4 10h16M8 3v4M16 3v4" /></svg>
              {dayLabel(day)} <span style={{ color: C.faint, fontSize: 11 }}>▾</span>
            </span>
            <span onClick={() => day < D.today && pickDay(day + 1)} className="p21-h-soft" style={{ width: 30, height: 30, display: 'flex', alignItems: 'center', justifyContent: 'center', borderRadius: 6, cursor: 'pointer', fontSize: 18, color: day < D.today ? C.ink : '#D3D1CB' }}>›</span>
            {s.cal && <Calendar day={day} onPick={pickDay} />}
          </div>
        </div>

        {!dd && <div style={{ marginTop: 48, fontSize: 15, color: C.faint }}>No records this day.</div>}

        {dd && (<>
          {/* 时间条：悬停预览画面，点击从那一刻回放 */}
          <div style={{ marginTop: 30, position: 'relative' }}>
            <div style={{ position: 'relative', height: 16, fontSize: 11, color: C.faint }}>
              {[9, 12, 15, 18, 21].map(h => <span key={h} style={{ position: 'absolute', left: pct(h) }}>{String(h).padStart(2, '0')}</span>)}
            </div>
            <div onMouseMove={(e) => { const b = e.currentTarget.getBoundingClientRect(); setHoverT(8 + Math.max(0, Math.min(1, (e.clientX - b.left) / b.width)) * 15); }}
              onMouseLeave={() => setHoverT(null)}
              onClick={() => hoverT !== null && set({ replay: { day, t: hoverT } })}
              style={{ position: 'relative', height: 30, marginTop: 4, background: C.soft, borderRadius: 6, overflow: 'hidden', cursor: 'pointer' }}>
              {dd.segs.map(([a, b, k], i) => <div key={i} style={{ position: 'absolute', top: 0, bottom: 0, left: pct(a), width: ((b - a) / 15 * 100) + '%', background: D.apps[k][1] }} />)}
              {hoverT !== null && <div style={{ position: 'absolute', top: 0, bottom: 0, left: pct(hoverT), width: 2, background: C.ink, opacity: .6 }} />}
            </div>
            <div style={{ position: 'relative', height: 18, marginTop: 4 }}>
              {dd.mems.map(m => <span key={m.id} onClick={() => set({ replay: { day, t: m.at } })} title={m.title} style={{ position: 'absolute', left: pct(m.at), transform: 'translateX(-50%)', fontSize: 12, cursor: 'pointer', color: C.green }}>◆</span>)}
            </div>
            <div style={{ marginTop: 6, display: 'flex', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' }}>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 16, fontSize: 12, color: C.muted }}>
                {Object.values(D.apps).map(([n, c]) => <span key={n} style={{ display: 'flex', alignItems: 'center', gap: 6 }}><span style={{ width: 10, height: 10, borderRadius: 3, background: c }} />{n}</span>)}
                <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}><span style={{ width: 10, height: 10, borderRadius: 3, background: C.soft }} />gap</span>
                <span style={{ color: C.green }}>◆ <span style={{ color: C.muted }}>memory</span></span>
              </div>
              <span style={{ fontSize: 12, color: C.faint }}>Hover the bar to preview that moment, click to replay from there.</span>
            </div>
            {hoverT !== null && (() => {
              const f = frameAt(day, hoverT);
              return (
                <div style={{ position: 'absolute', top: -112, left: pct(hoverT), transform: 'translateX(-50%)', width: 200, background: C.ink, borderRadius: 12, padding: 8, color: '#F3F4F1', pointerEvents: 'none', zIndex: 6, boxShadow: '0 14px 34px rgba(15,15,15,.3)' }}>
                  <div style={{ height: 64, borderRadius: 6, background: '#0F1311', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                    <div style={{ width: '76%', borderRadius: 5, background: '#fff', color: C.ink, padding: '5px 8px' }}>
                      <div style={{ display: 'flex', gap: 4 }}>{['#FF5F57', '#FEBC2E', '#28C840'].map(c => <span key={c} style={{ width: 6, height: 6, borderRadius: '50%', background: c }} />)}</div>
                      <div style={{ marginTop: 4, fontSize: 9.5, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{f.title}</div>
                    </div>
                  </div>
                  <div style={{ marginTop: 6, display: 'flex', justifyContent: 'space-between', fontSize: 10.5, color: '#A9B0AB' }}>
                    <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}><span style={{ width: 7, height: 7, borderRadius: 2, background: f.color }} />{f.app}</span>
                    <span>{f.time} · ▶</span>
                  </div>
                </div>
              );
            })()}
          </div>

          <div style={{ marginTop: 26, fontFamily: SERIF, fontSize: 21, lineHeight: 1.45, maxWidth: 640, textWrap: 'pretty' }}>{dd.summary}</div>

          {/* REMEMBERED THIS DAY + All / Done by AI */}
          <div style={{ marginTop: 40, display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 }}>
            <span style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
              <Label>Remembered this day</Label>
              <Seg small items={[['All', 'All'], ['AI', 'Done by AI']]} value={s.tlFilter} onChange={(k) => set({ tlFilter: k })} />
            </span>
            <span style={{ fontSize: 12, color: C.muted, position: 'relative' }}>
              {ai ? (mems.length ? <>{mems.length} {mems.length === 1 ? 'memory' : 'memories'} · <span onMouseEnter={() => setHetTip('total')} onMouseLeave={() => setHetTip(null)} style={{ color: C.green, cursor: 'help', borderBottom: '1px dotted #9DB8A6' }}>{hetSum.toFixed(1)} h HET</span></> : '') : `${mems.length} memories`}
              {hetTip === 'total' && <Tip style={{ right: 0, top: '100%', marginTop: 6 }}>{D.hetTotalTip}</Tip>}
            </span>
          </div>
          <div style={{ marginTop: 12, display: 'flex', flexDirection: 'column', gap: 12 }}>
            {mems.map(m => (
              <div key={m.id} ref={el => { cardRefs.current[m.id] = el; }} className="p21-h-card"
                style={{ background: s.highlight === m.id ? '#EEF4EF' : '#fff', border: `1px solid ${s.highlight === m.id ? '#BFD3C4' : C.line}`, borderRadius: 10, padding: '18px 22px', transition: 'background .6s, border-color .6s' }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 }}>
                  <span style={{ fontSize: 12, color: C.muted }}>{m.when}</span>
                  <span style={{ display: 'flex', alignItems: 'center', gap: 14, position: 'relative' }}>
                    {ai && m.ai && (
                      <span onMouseEnter={() => setHetTip(m.id)} onMouseLeave={() => setHetTip(null)} style={{ fontSize: 12, color: C.green, cursor: 'help', borderBottom: '1px dotted #9DB8A6' }}>{m.het.toFixed(1)} h HET</span>
                    )}
                    {hetTip === m.id && <Tip style={{ right: 90, top: '100%', marginTop: 6 }}>{D.hetTip}</Tip>}
                    <span onClick={() => set({ replay: { day, t: m.at } })} className="p21-h-soft"
                      style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '5px 12px', borderRadius: 6, border: `1px solid ${C.border}`, fontSize: 12.5, fontWeight: 500, cursor: 'pointer', background: '#fff' }}>▶ Replay</span>
                  </span>
                </div>
                <div style={{ marginTop: 8, fontSize: 17, fontWeight: 500, lineHeight: 1.4 }}>{m.title}</div>
                <div style={{ marginTop: 4, color: C.muted }}>{m.body}</div>
              </div>
            ))}
            {ai && mems.length === 0 && <div style={{ padding: '24px 0', color: C.faint }}>No agent work today</div>}
          </div>
        </>)}
      </div>
    );
  }

  /* 左下角「Replay this day」小电视（由 app 放在窗口层） */
  function ReplayTV() {
    const { s, set } = useP();
    const dd = dayData(s.day);
    if (!dd) return null;
    const startT = dd.segs[0][0];
    const first = frameAt(s.day, startT);
    return (
      <div onClick={() => set({ replay: { day: s.day, t: startT } })}
        onMouseEnter={(e) => { e.currentTarget.style.transform = 'scale(1.05)'; }} onMouseLeave={(e) => { e.currentTarget.style.transform = 'none'; }}
        style={{ position: 'absolute', right: 24, bottom: 84, width: 150, borderRadius: 10, background: C.ink, padding: '9px 10px 10px', color: '#F3F4F1', cursor: 'pointer', boxShadow: '0 20px 50px rgba(15,15,15,.3)', transition: 'transform .2s', transformOrigin: 'bottom right', zIndex: 15 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10.5, fontWeight: 600, color: '#A8A7A3' }}><span>Sep {s.day}</span><span>{dd.mems.length} memories</span></div>
        <div style={{ marginTop: 7, height: 56, borderRadius: 5, background: '#0F1311', display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden' }}>
          <div style={{ width: '82%', borderRadius: 4, background: '#fff', color: C.ink, padding: '5px 7px' }}>
            <div style={{ display: 'flex', gap: 4 }}>{['#FF5F57', '#FEBC2E', '#28C840'].map(c => <span key={c} style={{ width: 6, height: 6, borderRadius: '50%', background: c }} />)}</div>
            <div style={{ marginTop: 4, fontSize: 8.5, color: C.faint }}>{D.apps[dd.segs[0][2]][0]} · {clock(startT)}</div>
            <div style={{ fontSize: 9.5, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{first.title}</div>
          </div>
        </div>
        <div style={{ marginTop: 8, display: 'flex', alignItems: 'center', gap: 7, fontSize: 12.5, fontWeight: 500 }}><span>▶</span>Replay this day</div>
      </div>
    );
  }

  /* 整窗回放（不是系统全屏） */
  function ReplayOverlay() {
    const { s, set } = useP();
    const r = s.replay, dd = dayData(r.day) || { mems: [], segs: [] };
    const f = frameAt(r.day, r.t);
    const jump = (dir) => {
      const arr = dd.mems.map(m => m.at).sort((a, b) => a - b);
      const nx = dir > 0 ? arr.find(a => a > r.t + 0.01) : arr.slice().reverse().find(a => a < r.t - 0.01);
      if (nx !== undefined) set({ replay: { ...r, t: nx } });
    };
    return (
      <div style={{ position: 'absolute', inset: 0, zIndex: 50, background: '#0F1311', display: 'flex', flexDirection: 'column', padding: '20px 28px 22px', color: '#F3F4F1', animation: 'p21fade .2s' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}><span style={{ fontSize: 20, fontWeight: 600 }}>Replay</span><span style={{ fontSize: 12, color: '#A8A7A3' }}>{dayLabel(r.day)} · {f.time} · {f.app}</span></div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            {['1×', 'Fit'].map(x => <span key={x} style={{ padding: '6px 12px', borderRadius: 6, border: '1px solid rgba(255,255,255,.2)', fontSize: 13, cursor: 'pointer' }}>{x}</span>)}
            <span onClick={() => set({ replay: null })} style={{ fontSize: 22, lineHeight: 1, color: '#A9B0AB', cursor: 'pointer', marginLeft: 10 }}>×</span>
          </div>
        </div>
        <div style={{ flex: 1, minHeight: 0, marginTop: 16, borderRadius: 10, background: '#000', position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden' }}>
          {[['‹', -1, { left: 16 }], ['›', 1, { right: 16 }]].map(([g, d, pos]) => (
            <span key={g} onClick={() => jump(d)} style={{ position: 'absolute', top: '50%', transform: 'translateY(-50%)', width: 44, height: 44, borderRadius: '50%', background: 'rgba(255,255,255,.9)', color: C.ink, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', fontSize: 20, ...pos }}>{g}</span>
          ))}
          <div style={{ width: 'min(680px,72%)', borderRadius: 12, background: '#fff', color: C.ink, padding: '14px 18px', boxShadow: '0 30px 80px rgba(0,0,0,.6)' }}>
            <div style={{ display: 'flex', gap: 6 }}>{['#FF5F57', '#FEBC2E', '#28C840'].map(c => <span key={c} style={{ width: 10, height: 10, borderRadius: '50%', background: c }} />)}</div>
            <div style={{ marginTop: 14, fontSize: 12, color: C.faint }}>{f.app}</div>
            <div style={{ marginTop: 4, fontSize: 18, fontWeight: 600 }}>{f.title}</div>
            <div style={{ marginTop: 8, fontSize: 14, color: '#6B6A66', lineHeight: 1.55 }}>{f.body}</div>
          </div>
          <span style={{ position: 'absolute', left: '50%', bottom: 14, transform: 'translateX(-50%)', padding: '6px 12px', borderRadius: 6, background: 'rgba(15,15,15,.85)', fontSize: 12, fontFamily: MONO }}>{dayLabel(r.day)} · {f.time}</span>
        </div>
        <div style={{ marginTop: 16 }}>
          <div style={{ position: 'relative', height: 14, fontSize: 11, color: '#6B716C' }}>
            {[9, 12, 15, 18, 21].map(h => <span key={h} style={{ position: 'absolute', left: pct(h) }}>{String(h).padStart(2, '0')}</span>)}
          </div>
          <div onClick={(e) => { const b = e.currentTarget.getBoundingClientRect(); set({ replay: { ...r, t: 8 + Math.max(0, Math.min(1, (e.clientX - b.left) / b.width)) * 15 } }); }}
            style={{ position: 'relative', height: 26, marginTop: 6, borderRadius: 6, background: '#2B302D', cursor: 'pointer' }}>
            {dd.segs.map(([a, b, k], i) => <div key={i} style={{ position: 'absolute', top: 4, bottom: 4, left: pct(a), width: ((b - a) / 15 * 100) + '%', borderRadius: 3, background: D.apps[k][1] }} />)}
            <div style={{ position: 'absolute', top: -4, bottom: -4, left: pct(r.t), width: 2, background: '#F3F4F1', pointerEvents: 'none' }} />
          </div>
          <div style={{ marginTop: 8, display: 'flex', justifyContent: 'space-between', fontSize: 11, color: '#6B716C' }}><span>‹ › jump between memories</span><span>Click the bar to move</span></div>
        </div>
      </div>
    );
  }

  Object.assign(window.P21, { TimelinePage, ReplayTV, ReplayOverlay, tlDayData: dayData });
})();
