/* page-you.jsx — （3）You：画像 + Graph 缩略图、WHAT STAYS TRUE、YOUR WORLD、YOUR SKILLS
   以及展开后的 Graph（整页画成一棵树）和相关弹窗 */
/* global React */
window.P21 = window.P21 || {};
(() => {
  const { C, SERIF, useP, Label, More, Btn, Pill, Modal, X, AgentTags, SRC_MARK, MiniCard, Av, Ico, D } = window.P21;

  /* ───────── 页面 ───────── */
  function YouPage({ mainRef }) {
    const { s, set, go, openModal } = useP();
    const worldRef = React.useRef(null);
    const [allTraits, setAllTraits] = React.useState(false);
    const traits = D.traits.filter(t => !(s.hiddenTraits || []).includes(t.id));
    const shownTraits = allTraits ? traits : traits.slice(0, 5);
    const ents = D.entities.filter(e => e.type === s.youTab);

    /* 从 Home 跳过来：实体数字定位到 YOUR WORLD */
    React.useEffect(() => {
      if (s.scrollTo === 'world' && worldRef.current && mainRef.current) {
        mainRef.current.scrollTo({ top: worldRef.current.offsetTop - 24, behavior: 'smooth' });
        set({ scrollTo: null });
      }
    }, [s.scrollTo]);

    if (s.graph) return <GraphView />;

    return (
      <div style={{ maxWidth: 900, margin: '0 auto', padding: '52px 48px 140px' }}>
        <div style={{ fontSize: 32, fontWeight: 700, letterSpacing: '-.02em', lineHeight: 1.2 }}>You</div>
        <div style={{ marginTop: 6, fontSize: 15, color: C.muted }}>Your portrait and your world, as your memories draw them.</div>

        {/* 身份行：左边头像、名字、起始日期；右边天数与 Memories 两块小数字（Home 个人卡片 More › 跳过来看的完整版） */}
        <div style={{ marginTop: 28, display: 'flex', alignItems: 'center', gap: 14 }}>
          <Av size={48} uploaded={s.avatar} />
          <span style={{ fontSize: 20, fontWeight: 600, letterSpacing: '-.01em' }}>{D.user.name}</span>
          <span style={{ fontSize: 13, color: C.muted }}>Known since {D.user.knownSince}</span>
          {/* 右侧两块小数字：参考 Home 的浅灰数字块，字号缩小 */}
          <div style={{ marginLeft: 'auto', display: 'flex', gap: 8 }}>
            {[[D.user.days, 'Days'], [D.memories, `Memories · +${D.memoriesToday} today`]].map(([n, l]) => (
              <div key={l} style={{ padding: '9px 14px 8px', borderRadius: 10, background: C.soft, minWidth: 64 }}>
                <div style={{ fontFamily: SERIF, fontSize: 26, lineHeight: 1 }}>{n}</div>
                <div style={{ marginTop: 5, fontSize: 11.5, color: C.muted, whiteSpace: 'nowrap' }}>{l}</div>
              </div>
            ))}
          </div>
        </div>

        {/* HOW PERSOM SEES YOU + Graph 缩略图 */}
        <div style={{ marginTop: 28, display: 'grid', gridTemplateColumns: 'minmax(0,1fr) 290px', gap: 32, alignItems: 'start' }}>
          <div>
            <Label>How Persom sees you</Label>
            <div style={{ marginTop: 14, fontFamily: SERIF, fontSize: 22, lineHeight: 1.45, textWrap: 'pretty' }}>{D.portrait}</div>
          </div>
          <div onClick={() => set({ graph: true })} className="p21-h-soft"
            style={{ background: '#fff', border: `1px solid ${C.line}`, borderRadius: 10, padding: '14px 16px', cursor: 'pointer' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <span style={{ fontSize: 13.5, fontWeight: 500 }}>Graph</span>
              <span title="Expand" style={{ color: C.muted, display: 'inline-flex' }}><Ico name="expand" size={16} /></span>
            </div>
            <svg viewBox="0 0 250 100" width="100%" style={{ display: 'block', marginTop: 10 }}>
              <g fill="none" stroke="#D3D1CB" strokeWidth="1.2">
                <path d="M23 50h29M52 18v64M52 18h38M52 50h38M52 82h38M112 18h28M112 50h28M112 82h28" />
              </g>
              <circle cx="16" cy="50" r="7" fill={C.green} />
              {[18, 50, 82].map(y => <rect key={y} x="96" y={y - 6} width="12" height="12" transform={`rotate(45 102 ${y})`} fill={C.leaf} />)}
              <g fill="#fff" stroke={C.green} strokeWidth="1.5">
                {[148, 168, 188].map(x => <circle key={'a' + x} cx={x} cy="18" r="5" />)}
                {[148, 168, 188, 208, 228].map(x => <circle key={'b' + x} cx={x} cy="50" r="5" />)}
                {[148, 168].map(x => <circle key={'c' + x} cx={x} cy="82" r="5" />)}
              </g>
            </svg>
          </div>
        </div>

        {/* WHAT STAYS TRUE */}
        <div style={{ marginTop: 44, display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <Label>What stays true</Label>
          {traits.length > 5 && <More onClick={() => setAllTraits(!allTraits)}>{allTraits ? 'Show less' : 'See all ›'}</More>}
        </div>
        <div style={{ marginTop: 8, borderBottom: `1px solid ${C.line}` }}>
          {shownTraits.map(t => (
            <div key={t.id} onClick={() => openModal({ type: 'sources', id: t.id })} className="p21-h-soft"
              style={{ display: 'flex', justifyContent: 'space-between', gap: 12, alignItems: 'center', padding: '12px 10px', margin: '0 -10px', borderTop: `1px solid ${C.line}`, cursor: 'pointer', borderRadius: 6 }}>
              <span style={{ fontSize: 15 }}>· {t.claim}</span>
              <span style={{ fontSize: 12, color: C.muted, whiteSpace: 'nowrap' }}>{t.n} sources ›</span>
            </div>
          ))}
        </div>

        {/* YOUR WORLD */}
        <div ref={worldRef}>
          <Label style={{ marginTop: 44 }}>Your world</Label>
          <div style={{ marginTop: 12, display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {D.types.map(t => (
              <Pill key={t} on={s.youTab === t} onClick={() => set({ youTab: t })}>{t} <span style={{ opacity: .6 }}>{D.counts.find(c => c.key === t).n}</span></Pill>
            ))}
          </div>
          <div style={{ marginTop: 16, display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0,1fr))', gap: 14 }}>
            {ents.map(e => (
              <MiniCard key={e.name} title={e.name} desc={e.desc} meta={`${e.count} memories · ${e.last}`} onClick={() => openModal({ type: 'entity', id: e.name })} />
            ))}
          </div>
        </div>

        {/* YOUR SKILLS：精简版，默认 6 张 */}
        <div style={{ marginTop: 44, display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <Label>Your skills</Label>
          <More onClick={() => go('Playbook', { pbView: 'mine', mineTab: 'Installed' })}>See all ›</More>
        </div>
        <div style={{ marginTop: 12, display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0,1fr))', gap: 14 }}>
          {s.skills.slice(0, 6).map(k => (
            <MiniCard key={k.id} serif={false} title={k.name} desc={k.desc} right={<AgentTags ids={k.agents} />} onClick={() => openModal({ type: 'skill', mode: 'installed', id: k.id })} />
          ))}
        </div>
      </div>
    );
  }

  /* ───────── 展开后的 Graph：一棵树 ───────── */
  const LINE = '#D3D1CB';
  function HLine({ w }) { return <div style={{ width: w, height: 1, background: LINE, flexShrink: 0 }} />; }
  /* 竖线：连接同一层的兄弟节点，首尾各截一半 */
  function VLine({ i, n }) {
    return <div style={{ position: 'absolute', left: 0, top: n === 1 || i === 0 ? '50%' : 0, bottom: n === 1 || i === n - 1 ? '50%' : 0, width: 1, background: LINE }} />;
  }
  function Node({ onClick, dot, children, meta, small }) {
    return (
      <div onClick={onClick} className="p21-h-soft"
        style={{ display: 'flex', alignItems: 'center', gap: 9, padding: small ? '5px 12px' : '7px 14px', border: `1px solid ${C.line}`, background: '#fff', borderRadius: 6, cursor: 'pointer', flexShrink: 0, fontSize: small ? 13 : 13.5, whiteSpace: 'nowrap' }}>
        {dot}{children}{meta !== undefined && <span style={{ color: C.faint, fontSize: 12 }}>{meta}</span>}
      </div>
    );
  }
  const ring = (filled) => <span style={{ width: 8, height: 8, borderRadius: '50%', border: `1.5px solid ${C.green}`, background: filled ? C.green : '#fff', flexShrink: 0 }} />;
  const solid = <span style={{ width: 7, height: 7, borderRadius: '50%', background: C.green, flexShrink: 0 }} />;

  function Leaves({ items }) {
    return (
      <div style={{ display: 'flex', flexDirection: 'column' }}>
        {items.map((it, i) => (
          <div key={it.key} style={{ position: 'relative', display: 'flex', alignItems: 'center', padding: '4px 0' }}>
            <VLine i={i} n={items.length} /><HLine w={28} />
            {it.node}
            {it.kids && it.kids.length > 0 && (<><HLine w={28} /><Leaves items={it.kids} /></>)}
          </div>
        ))}
      </div>
    );
  }

  function GraphView() {
    const { s, set, openModal } = useP();
    const gx = s.gx || {};
    const toggle = (k) => set({ gx: { ...gx, [k]: !gx[k] } });
    const traits = D.traits.filter(t => !(s.hiddenTraits || []).includes(t.id)).slice(0, 5);

    const branches = [
      { label: 'What stays true', items: traits.map(t => ({ key: t.id, node: <Node onClick={() => openModal({ type: 'sources', id: t.id })} dot={ring(false)} meta={`${t.n} sources`}>{t.claim}</Node> })) },
      { label: 'Your world', items: D.types.map(t => {
          const ents = D.entities.filter(e => e.type === t);
          return { key: t, node: <Node onClick={() => toggle(t)} dot={ring(gx[t])} meta={D.counts.find(c => c.key === t).n}>{t}</Node>,
            kids: gx[t] ? ents.map(e => ({ key: e.name, node: <Node small onClick={() => openModal({ type: 'entity', id: e.name })} dot={solid}>{e.name}</Node> })) : [] };
        }) },
      { label: 'Your skills', items: [{ key: 'skills', node: <Node onClick={() => toggle('skills')} dot={ring(gx.skills)} meta={s.skills.length}>Skills</Node>,
          kids: gx.skills ? s.skills.map(k => ({ key: k.id, node: <Node small onClick={() => openModal({ type: 'skill', mode: 'installed', id: k.id })} dot={solid}>{k.name}</Node> })) : [] }] },
    ];

    return (
      <div style={{ padding: '26px 40px 140px', minHeight: '100%' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: 14, color: C.muted }}>
          <span style={{ display: 'inline-flex', alignItems: 'center' }}><span onClick={() => set({ graph: false })} style={{ cursor: 'pointer', color: C.ink, display: 'inline-flex', alignItems: 'center', gap: 2 }}><Ico name="back" size={16} />You</span><span style={{ margin: '0 8px' }}>/</span>Graph</span>
          <span onClick={() => set({ graph: false })} style={{ cursor: 'pointer', fontSize: 13.5, display: 'inline-flex', alignItems: 'center', gap: 6 }}><Ico name="collapse" size={16} />Close</span>
        </div>
        <div className="p21-scroll" style={{ marginTop: 48, display: 'flex', alignItems: 'center', overflowX: 'auto', paddingBottom: 20 }}>
          <div onClick={() => openModal({ type: 'portrait' })} className="p21-h-soft"
            style={{ width: 230, flexShrink: 0, background: '#fff', border: `1px solid ${C.line}`, borderRadius: 10, padding: '14px 16px', cursor: 'pointer' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}><span style={{ width: 12, height: 12, borderRadius: '50%', background: C.green }} /><span style={{ fontSize: 12, fontWeight: 600, color: C.faint }}>You</span></div>
            <div style={{ marginTop: 8, fontFamily: SERIF, fontSize: 15, lineHeight: 1.45, display: '-webkit-box', WebkitLineClamp: 3, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>{D.portrait}</div>
          </div>
          <HLine w={40} />
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            {branches.map((b, i) => (
              <div key={b.label} style={{ position: 'relative', display: 'flex', alignItems: 'center', padding: '14px 0' }}>
                <VLine i={i} n={branches.length} /><HLine w={40} />
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '9px 15px', border: `1px solid ${C.line}`, background: '#fff', borderRadius: 12, flexShrink: 0 }}>
                  <span style={{ width: 10, height: 10, transform: 'rotate(45deg)', background: C.leaf, borderRadius: 2 }} />
                  <span style={{ fontSize: 12, fontWeight: 600, color: C.faint, whiteSpace: 'nowrap' }}>{b.label}</span>
                </div>
                <HLine w={36} />
                <Leaves items={b.items} />
              </div>
            ))}
          </div>
        </div>
      </div>
    );
  }

  /* ───────── 弹窗 ───────── */
  /* 判断的依据：Memory 列表，点任意一条跳到 Timeline 当天；底部可以标记「不对」 */
  function SourcesModal({ m, onClose }) {
    const { s, set, go } = useP();
    const t = D.traits.find(x => x.id === m.id);
    return (
      <Modal onClose={onClose}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 16 }}>
          <span style={{ fontFamily: SERIF, fontSize: 24, lineHeight: 1.25 }}>{t.claim}</span><X onClick={onClose} />
        </div>
        <div style={{ marginTop: 6, fontSize: 13, color: C.muted }}>Based on {t.n} memories · latest first</div>
        <div style={{ marginTop: 16, borderBottom: `1px solid ${C.line2}` }}>
          {D.traitSources.map(([d, title, day]) => (
            <div key={d} onClick={() => go('Timeline', { day, highlight: null })} className="p21-h-link"
              style={{ display: 'grid', gridTemplateColumns: '56px 1fr auto', gap: 12, padding: '10px 0', borderTop: `1px solid ${C.line2}`, cursor: 'pointer', alignItems: 'center' }}>
              <span style={{ fontSize: 12, color: C.muted }}>{d}</span><span>{title}</span><span style={{ color: C.faint }}>›</span>
            </div>
          ))}
          <div style={{ padding: '8px 0', fontSize: 12.5, color: C.faint, borderTop: `1px solid ${C.line2}` }}>+ {t.n - D.traitSources.length} more</div>
        </div>
        <div style={{ marginTop: 18, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <span style={{ fontSize: 12.5, color: C.faint }}>Wrong? Persom will stop using it.</span>
          <Btn kind="danger" onClick={() => set({ hiddenTraits: [...(s.hiddenTraits || []), t.id], modal: null, toast: 'Marked as not right · removed from You' })}>This isn't right</Btn>
        </div>
      </Modal>
    );
  }

  /* 实体详情：沿用 2.0 的 Wiki */
  function EntityModal({ m, onClose }) {
    const { go, set } = useP();
    const e = D.entities.find(x => x.name === m.id);
    const recent = e.recent || [['Sep 26', `Mentioned ${e.name} while writing the 2.1 spec`, 26], ['Sep 22', `Worked on something related to ${e.name}`, 22]];
    return (
      <Modal onClose={onClose}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
          <span style={{ fontFamily: SERIF, fontSize: 28, lineHeight: 1.2 }}>{e.name}</span><X onClick={onClose} />
        </div>
        <div style={{ marginTop: 4, fontSize: 13, color: C.muted }}>{e.type.replace(/s$/, '')} · {e.count} memories · Last seen {e.last}</div>
        <div style={{ marginTop: 16, fontSize: 15, lineHeight: 1.55 }}>{e.long || e.desc}</div>
        {e.related && (
          <>
            <div style={{ marginTop: 20, fontSize: 13, fontWeight: 500 }}>Related</div>
            <div style={{ marginTop: 6, display: 'grid', gridTemplateColumns: '90px 1fr', gap: '6px 12px' }}>
              {e.related.map(([k, v]) => <React.Fragment key={k}><span style={{ color: C.muted }}>{k}</span><span>{v}</span></React.Fragment>)}
            </div>
          </>
        )}
        <div style={{ marginTop: 20, fontSize: 13, fontWeight: 500 }}>Recent memories</div>
        <div style={{ marginTop: 4 }}>
          {recent.map(([d, t, day]) => (
            <div key={d + t} onClick={() => go('Timeline', { day })} className="p21-h-link"
              style={{ display: 'grid', gridTemplateColumns: '56px 1fr auto', gap: 12, padding: '8px 0', borderTop: `1px solid ${C.line2}`, cursor: 'pointer', alignItems: 'center' }}>
              <span style={{ fontSize: 12, color: C.muted }}>{d}</span><span>{t}</span><span style={{ color: C.faint }}>›</span>
            </div>
          ))}
        </div>
        <div style={{ marginTop: 22, display: 'flex', justifyContent: 'space-between' }}>
          <Btn>Edit</Btn>
          <Btn kind="danger" onClick={() => set({ modal: null, toast: 'Marked as not right' })}>This isn't right</Btn>
        </div>
      </Modal>
    );
  }

  function PortraitModal({ onClose }) {
    return (
      <Modal onClose={onClose}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}><Label>How Persom sees you</Label><X onClick={onClose} /></div>
        <div style={{ marginTop: 14, fontFamily: SERIF, fontSize: 22, lineHeight: 1.45 }}>{D.portrait}</div>
      </Modal>
    );
  }

  Object.assign(window.P21, { YouPage, SourcesModal, EntityModal, PortraitModal });
})();
