/* home.jsx — 咔嗒Lab 首页 · Hero v16 星座连线 + 全页统一极光玻璃风 */

function Chev() { return <span className="chev">›</span>; }

/* 首页展示数据：优先用爬虫静态数据（data/crawled-*.js），没有则回退 KSITE 演示数据 */
const HOME_COMMUNITY = (window.CRAWLED_EVENTS && Array.isArray(window.CRAWLED_EVENTS.events) && window.CRAWLED_EVENTS.events.length)
  ? window.CRAWLED_EVENTS.events
  : ((window.KSITE && KSITE.community && KSITE.community.events) || []);
const HOME_ENTERPRISE = (window.CRAWLED_ENTERPRISE && Array.isArray(window.CRAWLED_ENTERPRISE.events) && window.CRAWLED_ENTERPRISE.events.length)
  ? window.CRAWLED_ENTERPRISE.events
  : ((window.KSITE && KSITE.enterprise && KSITE.enterprise.events) || []);

/* 社区与企业数据源都含 Devpost 黑客松，首条会重叠。首页按各自的代表形式挑选，
   让「社区活动」优先展示线下聚会/分享会/工作坊，「企业活动」优先展示发布会/开发者大会，
   两个板块互不重复、各归其类。保留原始下标用于活动详情跳转。 */
const COMMUNITY_PREF = ['Meetup', '分享会', '工作坊'];
const ENTERPRISE_PREF = ['发布会', '开发者大会', '训练营', '招聘'];
function pickEvents(list, prefer, key, n) {
  const withIdx = (list || []).map((e, i) => ({ e, i }));
  const want = withIdx.filter((o) => prefer.includes(o.e[key]));
  const rest = withIdx.filter((o) => !prefer.includes(o.e[key]));
  return want.concat(rest).slice(0, n);
}
const HOME_COMMUNITY_PICK = pickEvents(HOME_COMMUNITY, COMMUNITY_PREF, 'tag', 6);
const HOME_ENTERPRISE_PICK = pickEvents(HOME_ENTERPRISE, ENTERPRISE_PREF, 'type', 6);

/* lightweight "product shot" preview per module */
function Preview({ which }) {
  if (which === 'community') {
    const evs = HOME_COMMUNITY_PICK.slice(0, 3).map((o) => o.e);
    return (
      <div className="ahp">
        <div className="ahp-h"><span className="t">近期社区活动</span><span className="m">开放报名</span></div>
        {evs.map((e) => (
          <div className="ahp-row" key={e.title}>
            <span className="d">{e.date}</span>
            <span className="x"><div className="a">{e.title}</div><div className="b">{e.org}</div></span>
            <span className="ahp-chip">{e.mode === '线上' ? '线上' : e.city}</span>
          </div>
        ))}
      </div>
    );
  }
  if (which === 'enterprise') {
    const es = HOME_ENTERPRISE_PICK.slice(0, 3).map((o) => o.e);
    return (
      <div className="ahp">
        <div className="ahp-h"><span className="t">企业动态</span><span className="m">产业更新</span></div>
        {es.map((e) => (
          <div className="ahp-row" key={e.title}>
            <span className="d">{e.date}</span>
            <span className="x"><div className="a">{e.title}</div><div className="b">{e.company}</div></span>
            <span className="ahp-chip">{e.type}</span>
          </div>
        ))}
      </div>
    );
  }
  if (which === 'demo') {
    const its = KSITE.demo.items.slice(0, 4);
    return (
      <div className="ahp">
        <div className="ahp-h"><span className="t">技术广场</span><span className="m">可体验</span></div>
        <div className="ahp-grid">
          {its.map((it) => (
            <div className="ahp-mini" key={it.name}>
              <span className="cat"><i style={{ background: `linear-gradient(150deg, hsl(${it.hue} 62% 58%), hsl(${it.hue + 26} 60% 46%))` }} />{it.type}</span>
              <div className="nm">{it.name}</div>
              <div className="bl">{it.blurb}</div>
            </div>
          ))}
        </div>
      </div>
    );
  }
  // post
  const ps = KSITE.posts.feed.slice(0, 3);
  return (
    <div className="ahp">
      <div className="ahp-h"><span className="t">社区讨论</span><span className="m">开放讨论</span></div>
      {ps.map((p) => (
        <div className="ahp-post" key={p.title}>
          <span className="av" style={{ background: `linear-gradient(150deg, hsl(${p.hue} 58% 58%), hsl(${p.hue + 24} 56% 48%))` }} />
          <span><div className="nm">{p.author} · {p.kind}</div><div className="tt">{p.title}</div></span>
        </div>
      ))}
    </div>
  );
}

const FEATURES = [
  { key: 'community', href: '#community', eyebrow: '社区活动', h: '发现值得参加的 AI 社区活动', sub: 'Meetup、分享会、工作坊与黑客松集中呈现。按城市与形式筛选，找到适合你的下一场活动。' },
  { key: 'enterprise', href: '#enterprise', eyebrow: '企业活动', h: '跟进行业里的关键企业动态', sub: '发布会、黑客松、开放日与训练营统一入口。关注产业节奏，按需报名与投递。' },
  { key: 'demo', href: '#demo', eyebrow: '技术广场', h: '先看懂，再体验与交流', sub: '用清楚的语言说明模型、工具、Skill、数据集与 Agent 能做什么，再决定是否运行与反馈。' },
  { key: 'post', href: '#post', eyebrow: '社区讨论', h: '把观察、作品与问题写下来', sub: '分享实践复盘、发布作品进展，或提出具体问题。用清晰的讨论，连接真正相关的人。' },
];

/* ══ HERO v16 · 星座连线粒子场 + 拼图 ══ */
function HeroKata() {
  const heroRef = React.useRef(null);
  const starsRef = React.useRef(null);
  const jigRef = React.useRef(null);

  /* 星座连线粒子场（读取站点 --accent，主题/调色变更时同步） */
  React.useEffect(() => {
    const cv = starsRef.current, hero = heroRef.current;
    if (!cv || !hero) return;
    const ctx = cv.getContext('2d');
    let W, H, dpr, pts = [], raf = 0, colors = ['#2f6df0', '#8b5cf6', '#0ea5e9'];
    const mouse = { x: -9999, y: -9999 };
    /* kept for fallback; sitewide TechNetBG is primary and CSS hides this canvas on SPA home */
    const N_BASE = 70, LINK = 110, MLINK = 190;

    function readColors() {
      const ACC = getComputedStyle(document.documentElement).getPropertyValue('--accent').trim() || '#2f6df0';
      /* 三色粒子：accent 蓝 / 紫 / 青 */
      colors = [ACC, '#8b5cf6', '#0ea5e9'];
      return colors;
    }

    function resize() {
      dpr = Math.min(devicePixelRatio || 1, 2);
      W = hero.clientWidth; H = hero.clientHeight;
      cv.width = W * dpr; cv.height = H * dpr;
      cv.style.width = W + 'px'; cv.style.height = H + 'px';
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      const palette = readColors();
      const n = Math.round(N_BASE * Math.min(W / 1200, 1.3));
      pts = Array.from({ length: n }, () => ({
        x: Math.random() * W, y: Math.random() * H,
        vx: (Math.random() - .5) * .28, vy: (Math.random() - .5) * .28,
        r: 1.2 + Math.random() * 1.6,
        c: palette[Math.random() * 3 | 0],
        tw: Math.random() * Math.PI * 2          /* 闪烁相位 */
      }));
    }
    resize();
    const onResize = () => resize();
    window.addEventListener('resize', onResize);

    /* 主题 accent / data-theme 变化时刷新粒子色 */
    const mo = new MutationObserver(() => {
      const palette = readColors();
      pts.forEach((p) => { p.c = palette[Math.random() * 3 | 0]; });
    });
    mo.observe(document.documentElement, { attributes: true, attributeFilter: ['style', 'data-theme'] });

    const onMove = (e) => {
      const r = hero.getBoundingClientRect();
      mouse.x = e.clientX - r.left; mouse.y = e.clientY - r.top;
    };
    const onLeave = () => { mouse.x = mouse.y = -9999; };
    hero.addEventListener('pointermove', onMove);
    hero.addEventListener('pointerleave', onLeave);

    function frame(t) {
      ctx.clearRect(0, 0, W, H);
      for (const p of pts) {
        p.x += p.vx; p.y += p.vy;
        if (p.x < -10) p.x = W + 10; if (p.x > W + 10) p.x = -10;
        if (p.y < -10) p.y = H + 10; if (p.y > H + 10) p.y = -10;
        /* 粒子：更轻的闪烁光点 */
        const a = .22 + .2 * Math.sin(t / 900 + p.tw);
        ctx.globalAlpha = a; ctx.fillStyle = p.c;
        ctx.beginPath(); ctx.arc(p.x, p.y, p.r, 0, 7); ctx.fill();
      }
      /* 粒子间连线：弱环境光 + 光标附近增强（与全站 TechNetBG 同逻辑） */
      for (let i = 0; i < pts.length; i++) {
        const p = pts[i];
        const dm = Math.hypot(p.x - mouse.x, p.y - mouse.y);
        for (let k = i + 1; k < pts.length; k++) {
          const q = pts[k];
          const d = Math.hypot(p.x - q.x, p.y - q.y);
          if (d < LINK) {
            const near = Math.hypot((p.x + q.x) / 2 - mouse.x, (p.y + q.y) / 2 - mouse.y);
            const boost = near < MLINK + LINK ? (1 - near / (MLINK + LINK)) * .50 : 0;
            const alpha = (1 - d / LINK) * (.12 + boost);
            if (alpha < 0.02) continue;
            ctx.globalAlpha = alpha;
            ctx.strokeStyle = p.c; ctx.lineWidth = 1.0 + boost * .45;
            ctx.beginPath(); ctx.moveTo(p.x, p.y); ctx.lineTo(q.x, q.y); ctx.stroke();
          }
        }
        /* 粒子 ↔ 光标连线（跟随光标的随机感） */
        if (dm < MLINK) {
          ctx.globalAlpha = (1 - dm / MLINK) * .55;
          ctx.strokeStyle = p.c; ctx.lineWidth = 1.15;
          ctx.beginPath(); ctx.moveTo(p.x, p.y); ctx.lineTo(mouse.x, mouse.y); ctx.stroke();
        }
      }
      ctx.globalAlpha = 1;
      raf = requestAnimationFrame(frame);
    }
    if (!matchMedia('(prefers-reduced-motion: reduce)').matches)
      raf = requestAnimationFrame(frame);

    return () => {
      cancelAnimationFrame(raf);
      mo.disconnect();
      window.removeEventListener('resize', onResize);
      hero.removeEventListener('pointermove', onMove);
      hero.removeEventListener('pointerleave', onLeave);
    };
  }, []);

  /* 拼图入场（IntersectionObserver 触发） */
  React.useEffect(() => {
    const j = jigRef.current;
    if (!j) return;
    const io = new IntersectionObserver((e) => {
      if (e[0].isIntersecting) { setTimeout(() => j.classList.add('is-on'), 350); io.disconnect(); }
    }, { threshold: .35 });
    io.observe(j);
    return () => io.disconnect();
  }, []);

  const clickSound = () => {
    try {
      const ctx = new (window.AudioContext || window.webkitAudioContext)();
      [0, .07].forEach((t, i) => {
        const o = ctx.createOscillator(), g = ctx.createGain();
        o.type = 'square'; o.frequency.value = i ? 2200 : 1600;
        g.gain.setValueAtTime(.12, ctx.currentTime + t);
        g.gain.exponentialRampToValueAtTime(.001, ctx.currentTime + t + .04);
        o.connect(g).connect(ctx.destination);
        o.start(ctx.currentTime + t); o.stop(ctx.currentTime + t + .05);
      });
    } catch (e) {}
  };

  const onHubClick = () => {
    const j = jigRef.current; if (!j) return;
    j.classList.remove('is-on'); void j.offsetWidth;
    setTimeout(() => j.classList.add('is-on'), 60);
    setTimeout(clickSound, 60 + 600);
  };

  return (
    <section className="ah-hero" ref={heroRef}>
      <div className="cyanblob" />
      <canvas id="stars" ref={starsRef} />
      <div className="grain" />

      <h1><em>咔嗒</em>一声<span style={{ display: 'inline-block', width: '0.5em' }} />连接全球</h1>
      <p className="lead">面向全球 AI社区，企业及开发者的交流平台。</p>
      <p className="claim">让真正有价值的思想，精准地发出属于它们的“咔嗒”声。</p>

      <div className="jig" ref={jigRef}>
        <a className="pc pc1" href="#community"><svg viewBox="0 0 380 260"><path d="M 28 0 H 350 V 40 A 20 20 0 0 1 350 80 V 130 A 20 20 0 0 0 350 170 V 230 H 260 A 20 20 0 0 1 220 230 H 130 A 20 20 0 0 0 90 230 H 0 V 28 Q 0 0 28 0 Z" /></svg>
          <span className="txt"><span className="ic">🎪</span><h3>社区活动</h3><p>线下聚会 · 技术分享 · Hackathon</p></span></a>
        <a className="pc pc2" href="#enterprise"><svg viewBox="0 0 380 260"><path d="M 30 0 H 352 Q 380 0 380 28 V 230 H 290 A 20 20 0 0 0 250 230 H 160 A 20 20 0 0 1 120 230 H 30 V 170 A 20 20 0 0 1 30 130 V 80 A 20 20 0 0 0 30 40 Z" /></svg>
          <span className="txt"><span className="ic">🏢</span><h3>企业活动</h3><p>招聘直连 · 商务合作对接</p></span></a>
        <a className="pc pc3" href="#demo"><svg viewBox="0 0 380 260"><path d="M 0 30 H 90 A 20 20 0 0 1 130 30 H 220 A 20 20 0 0 0 260 30 H 350 V 90 A 20 20 0 0 1 350 130 V 180 A 20 20 0 0 0 350 220 V 260 H 28 Q 0 260 0 232 Z" /></svg>
          <span className="txt"><span className="ic">🧪</span><h3>技术广场</h3><p>Demo 展示 · 开源项目</p></span></a>
        <a className="pc pc4" href="#post"><svg viewBox="0 0 380 260"><path d="M 30 30 H 120 A 20 20 0 0 0 160 30 H 250 A 20 20 0 0 1 290 30 H 380 V 232 Q 380 260 352 260 H 30 V 220 A 20 20 0 0 1 30 180 V 130 A 20 20 0 0 0 30 90 Z" /></svg>
          <span className="txt"><span className="ic">💬</span><h3>社区发帖</h3><p>讨论 · 问答 · 灵感碰撞</p></span></a>

        <i className="preglow" />
        <i className="suck-ring a" /><i className="suck-ring b" />
        <i className="suck-dot" style={{ '--dx': '130px', '--dy': '-80px' }} /><i className="suck-dot" style={{ '--dx': '-130px', '--dy': '-80px' }} />
        <i className="suck-dot" style={{ '--dx': '130px', '--dy': '80px' }} /><i className="suck-dot" style={{ '--dx': '-130px', '--dy': '80px' }} />
        <i className="suck-dot" style={{ '--dx': '0px', '--dy': '-120px' }} /><i className="suck-dot" style={{ '--dx': '0px', '--dy': '120px' }} />
        <i className="suck-dot" style={{ '--dx': '165px', '--dy': '0px' }} /><i className="suck-dot" style={{ '--dx': '-165px', '--dy': '0px' }} />
        <svg className="seams" viewBox="0 0 700 460" aria-hidden="true">
          <defs>
            <linearGradient id="kd-gh" x1="0" y1="0" x2="700" y2="0" gradientUnits="userSpaceOnUse">
              <stop offset="0" style={{ stopColor: 'var(--accent)' }} stopOpacity="0" />
              <stop offset=".15" style={{ stopColor: 'var(--accent)' }} stopOpacity="1" />
              <stop offset=".85" style={{ stopColor: 'var(--accent)' }} stopOpacity="1" />
              <stop offset="1" style={{ stopColor: 'var(--accent)' }} stopOpacity="0" />
            </linearGradient>
            <linearGradient id="kd-gv" x1="0" y1="0" x2="0" y2="460" gradientUnits="userSpaceOnUse">
              <stop offset="0" style={{ stopColor: 'var(--accent)' }} stopOpacity="0" />
              <stop offset=".15" style={{ stopColor: 'var(--accent)' }} stopOpacity="1" />
              <stop offset=".85" style={{ stopColor: 'var(--accent)' }} stopOpacity="1" />
              <stop offset="1" style={{ stopColor: 'var(--accent)' }} stopOpacity="0" />
            </linearGradient>
          </defs>
          <path className="sflash" stroke="url(#kd-gh)" d="M 8 230 H 90 A 20 20 0 0 1 130 230 H 220 A 20 20 0 0 0 260 230 H 440 A 20 20 0 0 0 480 230 H 570 A 20 20 0 0 1 610 230 H 692" />
          <path className="sflash" stroke="url(#kd-gv)" d="M 350 8 V 40 A 20 20 0 0 1 350 80 V 130 A 20 20 0 0 0 350 170 V 290 A 20 20 0 0 1 350 330 V 380 A 20 20 0 0 0 350 420 V 452" />
          <path className="slive" stroke="url(#kd-gh)" d="M 8 230 H 90 A 20 20 0 0 1 130 230 H 220 A 20 20 0 0 0 260 230 H 440 A 20 20 0 0 0 480 230 H 570 A 20 20 0 0 1 610 230 H 692" />
          <path className="slive" stroke="url(#kd-gv)" d="M 350 8 V 40 A 20 20 0 0 1 350 80 V 130 A 20 20 0 0 0 350 170 V 290 A 20 20 0 0 1 350 330 V 380 A 20 20 0 0 0 350 420 V 452" />
          <path className="sflow" pathLength="100" d="M 8 230 H 90 A 20 20 0 0 1 130 230 H 220 A 20 20 0 0 0 260 230 H 440 A 20 20 0 0 0 480 230 H 570 A 20 20 0 0 1 610 230 H 692" />
          <path className="sflow sflowb" pathLength="100" d="M 350 8 V 40 A 20 20 0 0 1 350 80 V 130 A 20 20 0 0 0 350 170 V 290 A 20 20 0 0 1 350 330 V 380 A 20 20 0 0 0 350 420 V 452" />
        </svg>
        <i className="crack" />
        <div className="hub" title="再咔嗒一下" onClick={onHubClick}>
          <div className="glow" /><div className="ring" /><div className="ring2" />
          <div className="hub-core"><b>咔嗒</b><span>KATA LAB</span></div>
        </div>
      </div>
    </section>
  );
}

function HomePage() {
  return (
    <div className="ah">
      {/* continuous atmosphere — unifies hero + below-fold */}
      <div className="ah-atmosphere" aria-hidden="true">
        <i className="ah-blob ah-blob-a" />
        <i className="ah-blob ah-blob-b" />
        <i className="ah-blob ah-blob-c" />
        <i className="ah-mesh" />
        <i className="ah-grain" />
      </div>

      {/* HERO · v16 星座连线 */}
      <HeroKata />

      {/* FEATURE ROWS */}
      {FEATURES.map((f, i) => (
        <section className={'ah-feature' + (i % 2 ? ' alt flip' : '')} key={f.key}>
          <div className="inner">
            <div className="copy">
              <Reveal>
                <p className="eyebrow2">{f.eyebrow}</p>
                <h2>{f.h}</h2>
                <p className="fsub">{f.sub}</p>
                <a className="link" href={f.href}>了解更多 <Chev /></a>
              </Reveal>
            </div>
            <Reveal className="shot" tag="div"><Preview which={f.key} /></Reveal>
          </div>
        </section>
      ))}

      {/* EVENTS STRIP */}
      <section className="ah-events">
        <div className="head">
          <h2>近期活动</h2>
          <a className="link" href="#community">查看全部 <Chev /></a>
        </div>
        <div className="ah-evgrid">
          {HOME_COMMUNITY_PICK.slice(0, 3).map(({ e, i }) => (
            <Reveal key={e.title} delay={i * 90}>
              <a className="ah-ev" href={'#event/c' + i}>
                <div className="top"><span className="date">{e.date}<span>{e.day}</span></span><span className="ahp-chip">{e.tag}</span></div>
                <h3>{e.title}</h3>
                <div className="org">{e.org} · {e.mode === '线上' ? '线上' : e.city}</div>
              </a>
            </Reveal>
          ))}
        </div>
      </section>

      {/* CLOSING CTA — open band, no boxed card */}
      <section className="ah-cta">
        <div className="ah-cta-inner">
          <p className="ah-cta-kicker">开始使用</p>
          <h2>把有价值的连接，从这里开始</h2>
          <p>浏览活动、体验作品、参与讨论。加入社区，即可在社区与产业之间自由切换。</p>
          <div className="btns">
            <a className="ah-btn ah-btn-primary" href="#auth">加入社区</a>
            <a className="ah-btn ah-btn-ghost" href="#demo">先逛技术广场</a>
          </div>
          <div className="ah-cta-meta">
            <span>社区活动</span>
            <i />
            <span>企业动态</span>
            <i />
            <span>技术作品</span>
            <i />
            <span>开放讨论</span>
          </div>
        </div>
      </section>
    </div>
  );
}

(window.__KATA_PAGES = window.__KATA_PAGES || {}).home = { Comp: HomePage, active: 'home' };
if (!window.__KATA_SPA) {
  ReactDOM.createRoot(document.getElementById('root')).render(
    <KataPage active="home"><HomePage /></KataPage>
  );
}
