const { Button, Logo, PrismRule, IconButton } = window.PrismDS;

function useLucide(dep){ React.useEffect(()=>{ window.lucide && window.lucide.createIcons(); }); }
const Icon = ({ name, size = 18, color = 'currentColor' }) =>
  <i data-lucide={name} style={{ width: size, height: size, color, display: 'inline-flex' }} />;

// Every string below comes from /content — see CONTENT.md. `PrismContent` and `T` are globals
// installed by content-loader.js.
const NAV = () => PrismContent.pick(PrismContent.nav);

function SiteHeader({ page, go, onGate }) {
  const [scrolled, setScrolled] = React.useState(false);
  React.useEffect(() => {
    const el = document.getElementById('scroller');
    if (!el) return;
    const h = () => setScrolled(el.scrollTop > 12);
    el.addEventListener('scroll', h); return () => el.removeEventListener('scroll', h);
  }, []);
  const dark = page === 'home' && !scrolled;
  return (
    <header style={{
      position: 'sticky', top: 0, zIndex: 40, height: 88, display: 'flex', alignItems: 'center',
      padding: '0 40px', gap: 40,
      background: dark ? 'transparent' : 'var(--glass-bg)',
      backdropFilter: dark ? 'none' : 'var(--glass-blur)',
      borderBottom: '1px solid ' + (dark ? 'transparent' : 'var(--border-hairline)'),
      transition: 'background-color var(--dur-slow) var(--ease-standard), border-color var(--dur-slow) var(--ease-standard)'
    }}>
      <a onClick={() => go('home')} style={{ cursor: 'pointer', display: 'flex', alignItems: 'center' }}>
        {/* align="center"：两行文字共用同一水平中轴、左右对称（英文行相对中文行居中）。
            此前是 "left"（两行左对齐）。只影响 Logo 内部文字列的横向对齐，
            图标仍按中文行顶 ink / 英文行底 ink 计算 top 与高度，顶/底对齐关系不变。 */}
        <Logo size={46} align="center" enFirst={PrismContent.lang === 'en'} enColor="#3E76AC" tone={dark ? 'light' : 'dark'} src={window.RES('../../assets/logo-mark-glass.png')} />
      </a>
      <nav style={{ display: 'flex', gap: 32, marginLeft: 'auto' }}>
        {NAV().map(n => (
          <a key={n.id} onClick={() => go(n.id)} style={{
            cursor: 'pointer', font: 'var(--type-body)',
            color: page === n.id ? (dark ? '#fff' : 'var(--brand-primary)') : (dark ? 'rgba(255,255,255,.72)' : 'var(--text-muted)'),
            fontWeight: page === n.id ? 'var(--fw-medium)' : 'var(--fw-regular)',
            paddingBottom: 4, borderBottom: '2px solid ' + (page === n.id ? (dark ? 'var(--brand-accent)' : 'var(--brand-secondary)') : 'transparent'),
            transition: 'var(--transition-base)'
          }}>{T(n.label)}</a>
        ))}
      </nav>
      {/* 英文版暂未上线：按钮 UI 与占位位置原样保留，仅点击不生效（开关见 content-loader.js
          的 PrismContent.EN_ENABLED）。开关置 true 即自动恢复切换，无需改这里。 */}
      <Button size="sm" variant={dark ? 'onDark' : 'primary'} aria-disabled={!PrismContent.EN_ENABLED}
        onClick={() => { if (!PrismContent.EN_ENABLED) return; PrismContent.setLang(PrismContent.lang === 'en' ? 'zh' : 'en'); }}>{T(PrismContent.langToggleLabel)}</Button>
    </header>
  );
}

function SiteFooter({ go }) {
  return (
    <footer style={{ position: 'relative', background: 'var(--bg-inverse)', color: 'var(--text-inverse)', overflow: 'hidden', marginTop: 0 }}>
      <img src={window.RES('../../assets/logo-mark-glass.png')} alt="" style={{ position: 'absolute', right: '6%', top: 0, width: 620, maxWidth: '52%', opacity: .06, pointerEvents: 'none' }} />
      <div style={{ position: 'relative', maxWidth: 'var(--container-max)', margin: '0 auto', padding: '64px 40px 28px' }}>
        <style>{'.prism-ft-grid{display:flex;justify-content:space-between;align-items:flex-start;gap:64px;flex-wrap:wrap}.prism-ft-brand{flex:0 1 auto;min-width:260px;max-width:340px;display:flex;flex-direction:column}.prism-ft-qr{width:fit-content;min-width:120px}.prism-ft-right{display:flex;flex-direction:column;align-items:flex-end;flex:0 0 auto}.prism-ft-cols{display:flex;gap:48px;align-items:flex-start}@media(max-width:1150px){.prism-ft-right{align-items:flex-start}}.prism-ft-contact{white-space:nowrap}@media(max-width:1150px){.prism-ft-grid{display:grid;grid-template-columns:1fr;row-gap:44px}.prism-ft-brand{max-width:none}.prism-ft-contact{white-space:normal}}@media(max-width:900px){.prism-ft-grid{gap:40px}.prism-ft-right{gap:40px}}@media(max-width:620px){.prism-ft-right{flex-direction:column;gap:32px}}.prism-ft-icp,.prism-ft-icp:hover{color:inherit;text-decoration:none}.prism-ft-icp{margin-left:auto}'}</style>
        <div className="prism-ft-grid">
          <div className="prism-ft-brand">
            <div className="prism-ft-qr" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14 }}>
              <div style={{ font: 'var(--type-caption)', letterSpacing: 0, color: 'var(--brand-accent)', whiteSpace: 'nowrap' }}>{T(PrismContent.site.qrCaption)}</div>
              <img src={window.RES(PrismContent.site.qrImage)} alt={T(PrismContent.site.qrCaption)} style={{ width: 120, height: 120, objectFit: 'contain', display: 'block', background: '#fff', padding: 7, boxSizing: 'border-box', borderRadius: 'var(--radius-md)' }} />
            </div>
          </div>
          <div className="prism-ft-right">
          <div className="prism-ft-cols">
          <FooterCol title={T(PrismContent.footerNavTitle)} items={NAV().map(n => T(n.label))} onItem={i => go && go(NAV()[i].id)} />
          <div className="prism-ft-contact">
            <div style={{ font: 'var(--type-caption)', letterSpacing: 0, color: 'var(--brand-accent)' }}>{T(PrismContent.contactLabels.contactColumnTitle)}</div>
            <div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', columnGap: 16, rowGap: 10, marginTop: 16, font: 'var(--type-caption)', color: 'var(--text-inverse)', lineHeight: 1.7 }}>
              <div style={{ color: '#fff', whiteSpace: 'nowrap' }}>{T(PrismContent.contactLabels.addressLabel)}</div><div>{T(PrismContent.contact.primaryAddress)}</div>
              <div style={{ color: '#fff', whiteSpace: 'nowrap' }}>{T(PrismContent.contactLabels.emailLabel)}</div><div>{PrismContent.contact.hrEmail}</div>
            </div>
          </div>
          </div>
        </div>
        </div>
        <div style={{ height: 1, background: 'rgba(255,255,255,.12)', margin: '48px 0 22px' }} />
        <div style={{ display: 'flex', justifyContent: 'space-between', gap: 24, flexWrap: 'wrap', font: 'var(--type-caption)', fontSize: 12, color: 'rgba(255,255,255,.45)' }}>
          {/* 备案号与 © 同处这一行 flex：font / fontSize / color 全部由父容器给，
              两者字体、字号、颜色、基线因此天生完全一致，且与上方分割线同属一个容器、左右端对齐。
              做成 <a> 是工信部的要求（备案号须链接到 beian.miit.gov.cn）；
              .prism-ft-icp 强制 color:inherit 且 hover 不变色，视觉上与纯文本无异。 */}
          <span>{T(PrismContent.site.copyright)}</span>{PrismContent.site.icp && <a className="prism-cn prism-ft-icp" href="https://beian.miit.gov.cn" target="_blank" rel="noreferrer noopener">{PrismContent.site.icp}</a>}
        </div>
        {/* 风险提示行 2026-08-24 由单个 <p> 改为 flex 两端对齐：左侧风险提示不动，
            右侧放公安机关备案号，正好落在上一行 ICP 备案号的正下方（同一父容器、同为
            justify-content:space-between 的右端项，右缘因此与 ICP、与上方分割线严格对齐）。
            备案号取 alignItems:flex-start + 与风险提示相同的 lineHeight，使其与风险提示
            第一行同基线；字号 12 与全区一致，颜色沿用 ICP 的 .45——两个备案号是一对，
            纵向读下来须同色（风险提示本就比它们淡一档 .38，是原有的层级，未改）。
            窄屏 flexWrap 生效时备案号自动换到风险提示下方，不会挤压文本；换行后仅靠
            space-between 会把它甩到最左（单项行的对齐落点），所以 .prism-ft-icp 加了
            margin-left:auto——两个备案号在任何宽度下都保持右对齐、上下成对。 */}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 24, flexWrap: 'wrap', marginTop: 16 }}>
          <p className="prism-cn" style={{ font: 'var(--type-caption)', fontSize: 12, color: 'rgba(255,255,255,.38)', margin: 0, maxWidth: 860, lineHeight: 1.8 }}>
            {T(PrismContent.compliance.riskNotice)}
          </p>
          {PrismContent.site.police && <a className="prism-cn prism-ft-icp" style={{ font: 'var(--type-caption)', fontSize: 12, lineHeight: 1.8, color: 'rgba(255,255,255,.45)', whiteSpace: 'nowrap' }} href={'https://beian.mps.gov.cn/#/query/webSearch?code=' + PrismContent.site.police.replace(/\D/g, '')} target="_blank" rel="noreferrer noopener">{PrismContent.site.police}</a>}
        </div>
      </div>
    </footer>
  );
}

function FooterCol({ title, items, onItem }) {
  return (
    <div>
      <div style={{ font: 'var(--type-caption)', letterSpacing: 'var(--ls-caps)', textTransform: 'uppercase', color: 'var(--brand-accent)' }}>{title}</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginTop: 16 }}>
        {items.map((it, i) => <a key={it} onClick={() => onItem && onItem(i)} style={{ font: 'var(--type-caption)', color: 'var(--text-inverse)', cursor: 'pointer', textDecoration: 'none' }}>{it}</a>)}
      </div>
    </div>
  );
}

function Section({ eyebrow, title, lead, children, tone = 'light', tight, style, titleWeight = 600 }) {
  return (
    <section style={{
      background: tone === 'subtle' ? 'var(--bg-subtle)' : tone === 'wash' ? 'var(--gradient-wash)' : 'var(--bg-page)',
      padding: (tight ? 64 : 96) + 'px 40px', ...style
    }}>
      <div style={{ maxWidth: 'var(--container-max)', margin: '0 auto' }}>
        {(eyebrow || title) && (
          <div style={{ maxWidth: 720, marginBottom: 48 }}>
            <PrismRule />
            {eyebrow && <div style={{ font: 'var(--type-label)', letterSpacing: 'var(--ls-caps)', textTransform: 'uppercase', color: 'var(--brand-secondary)', margin: '18px 0 10px', fontSize: 11 }}>{eyebrow}</div>}
            {title && <h2 style={{ font: 'var(--type-h2)', fontWeight: titleWeight || undefined, color: 'var(--text-heading)', margin: 0 }}>{title}</h2>}
            {lead && <p style={{ font: 'var(--type-body-lg)', color: 'var(--text-muted)', margin: '16px 0 0' }}>{lead}</p>}
          </div>
        )}
        {children}
      </div>
    </section>
  );
}

// 揭示动画用 animation + animation-delay（不用 transition/transition-delay），播完即由 JS 卸下类与内联延迟，
// 元素回到自身样式 —— 否则残留的错峰延迟会拖慢该元素后续所有 hover 过渡。
const REVEAL_CSS = '@keyframes prismRv{from{opacity:0;transform:translate3d(0,20px,0)}to{opacity:1;transform:none}}@keyframes prismEnter{from{opacity:0;transform:translate3d(0,10px,0)}to{opacity:1;transform:none}}.prism-rv{opacity:0}.prism-rv.is-rv{animation:prismRv .56s var(--ease-out) both}.prism-enter{animation:prismEnter .46s var(--ease-out) both}@media(prefers-reduced-motion:reduce){.prism-rv,.prism-rv.is-rv{opacity:1;animation:none}.prism-enter{animation:none}}';

function Reveal({ page, children }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const root = ref.current;
    if (!root) return;
    if (page === 'contact') return;
    const reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    const targets = [];
    root.querySelectorAll('section').forEach(sec => {
      const box = sec.firstElementChild;
      if (!box) return;
      const blocks = Array.from(box.children);
      const group = [];
      blocks.forEach(b => {
        if (b.tagName === 'STYLE' || b.querySelector('canvas') || b.querySelector('.prism-vtl')) return;
        const kids = Array.from(b.children).filter(k => k.tagName !== 'STYLE');
        const gridish = kids.length > 1 && /grid|flex/.test(getComputedStyle(b).display);
        if (gridish) kids.forEach(k => group.push(k));
        else group.push(b);
      });
      group.forEach((el, i) => targets.push([el, i]));
    });
    if (reduce || !('IntersectionObserver' in window)) return;
    // progressive enhancement: nothing is hidden until we know it starts below the fold.
    // Anything already in the first screen just plays a short staggered entrance instead.
    const vh = window.innerHeight || 800;
    let above = 0;
    const below = [];
    targets.forEach(([el, i]) => {
      if (el.getBoundingClientRect().top < vh * 0.95) {
        el.style.animationDelay = Math.min(above++, 6) * 70 + 'ms';
        el.classList.add('prism-enter');
      } else {
        el.style.animationDelay = Math.min(i, 5) * 90 + 'ms';
        el.classList.add('prism-rv');
        below.push(el);
      }
    });
    // 动画结束即清除类与内联延迟，元素不留任何残余样式
    const clean = (e) => {
      const el = e.currentTarget;
      el.classList.remove('prism-rv', 'is-rv', 'prism-enter');
      el.style.animationDelay = '';
      el.removeEventListener('animationend', clean);
    };
    targets.forEach(([el]) => el.addEventListener('animationend', clean));
    const io = new IntersectionObserver(es => es.forEach(e => {
      if (e.isIntersecting) { e.target.classList.add('is-rv'); io.unobserve(e.target); }
    }), { root: document.getElementById('scroller'), rootMargin: '0px 0px -10% 0px', threshold: 0 });
    below.forEach(t => io.observe(t));
    // safety net: after 3s force-show anything that is on screen but still hidden (a silently
    // broken observer) — elements still below the fold stay hidden so they keep their scroll reveal
    const bail = setTimeout(() => below.forEach(t => {
      if (t.classList.contains('is-rv')) return;
      const r = t.getBoundingClientRect();
      if (r.top < window.innerHeight && r.bottom > 0) t.classList.add('is-rv');
    }), 3000);
    return () => { clearTimeout(bail); io.disconnect(); targets.forEach(([el]) => el.removeEventListener('animationend', clean)); };
  }, [page]);
  return <div ref={ref}><style>{REVEAL_CSS}</style>{children}</div>;
}

Object.assign(window, { Reveal, SiteHeader, SiteFooter, Section, FooterCol, Icon, useLucide, NAV });
