/* global React */
const { useEffect, useRef, useState } = React;

// Brand mark — abstract pulse heart with N glyph (original mark, distinct from any uploaded reference)
function BrandMark({ size = 38 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 64 64" fill="none">
      <defs>
        <linearGradient id="bm-g" x1="0" x2="1" y1="0" y2="1">
          <stop offset="0" stopColor="#5be7ff" />
          <stop offset=".6" stopColor="#9a6bff" />
          <stop offset="1" stopColor="#ff5cd2" />
        </linearGradient>
      </defs>
      <path d="M32 56 C12 42 8 30 14 22 C18 16 26 16 32 24 C38 16 46 16 50 22 C56 30 52 42 32 56Z"
            stroke="url(#bm-g)" strokeWidth="2" fill="none" />
      <path d="M16 34 L24 34 L28 26 L34 42 L38 32 L48 32"
            stroke="url(#bm-g)" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" fill="none" />
    </svg>
  );
}

function Particles({ count = 12 }) {
  const canvasRef = React.useRef(null);
  React.useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let dpr = Math.min(window.devicePixelRatio || 1, 2);
    let w = 0, h = 0;
    const resize = () => {
      w = canvas.clientWidth;
      h = canvas.clientHeight;
      canvas.width = Math.floor(w * dpr);
      canvas.height = Math.floor(h * dpr);
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    };
    resize();
    window.addEventListener('resize', resize);

    // Hero scene palette — cyan + violet glow, with a faint pink accent.
    const colors = [
      { r: 91, g: 231, b: 255 },   // neon cyan (matches hero)
      { r: 154, g: 107, b: 255 },  // neon violet (matches hero)
      { r: 200, g: 170, b: 255 },  // pale violet highlight
    ];

    // Spawn with vertical positions evenly distributed top-to-bottom so
    // no part of the screen is ever empty — produces a continuous stream.
    const parts = Array.from({ length: count }, (_, i) => {
      const c = colors[i % colors.length];
      return {
        x: Math.random() * (w || window.innerWidth),
        y: ((i + Math.random()) / count) * (h || window.innerHeight),
        r: 0.7 + Math.random() * 1.4,
        // slow, drifting speed
        vy: 10 + Math.random() * 16,
        // gentle horizontal sway
        sway: 0.4 + Math.random() * 1.0,
        swayPhase: Math.random() * Math.PI * 2,
        swayFreq: 0.15 + Math.random() * 0.3,
        baseAlpha: 0.55 + Math.random() * 0.35,
        col: c,
        // fade-in distance from spawn point so a respawn isn't a hard pop
        spawnY: 0,
      };
    });

    let last = performance.now();
    let raf = 0;
    const tick = (now) => {
      const dt = Math.min((now - last) / 1000, 0.05);
      last = now;
      ctx.clearRect(0, 0, w, h);
      for (const p of parts) {
        // move
        p.y -= p.vy * dt;
        const sx = p.x + Math.sin(now / 1000 * p.swayFreq + p.swayPhase) * p.sway;
        // wrap when fully off-screen at top — respawn at bottom
        if (p.y < -8) {
          p.y = h + 8;
          p.x = Math.random() * w;
          p.r = 0.7 + Math.random() * 1.4;
          p.vy = 10 + Math.random() * 16;
          p.baseAlpha = 0.55 + Math.random() * 0.35;
        }
        const edgeFade = 100;
        let alpha = p.baseAlpha;
        if (p.y > h - edgeFade) alpha *= (h - p.y) / edgeFade;
        if (p.y < edgeFade) alpha *= p.y / edgeFade;
        if (alpha < 0) alpha = 0;
        const { r: cr, g: cg, b: cb } = p.col;
        // soft glow halo
        const halo = p.r * 7;
        const grd = ctx.createRadialGradient(sx, p.y, 0, sx, p.y, halo);
        grd.addColorStop(0, `rgba(${cr}, ${cg}, ${cb}, ${alpha * 0.85})`);
        grd.addColorStop(0.45, `rgba(${cr}, ${cg}, ${cb}, ${alpha * 0.22})`);
        grd.addColorStop(1, `rgba(${cr}, ${cg}, ${cb}, 0)`);
        ctx.fillStyle = grd;
        ctx.beginPath();
        ctx.arc(sx, p.y, halo, 0, Math.PI * 2);
        ctx.fill();
        // bright core dot
        ctx.fillStyle = `rgba(${cr}, ${cg}, ${cb}, ${alpha})`;
        ctx.beginPath();
        ctx.arc(sx, p.y, p.r, 0, Math.PI * 2);
        ctx.fill();
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('resize', resize);
    };
  }, [count]);

  return <canvas ref={canvasRef} className="hero-particles" aria-hidden="true" />;
}

function Hero({ onSignIn, user }) {
  const bgRef = useRef(null);
  const [time, setTime] = useState(() => new Date());

  useEffect(() => {
    const id = setInterval(() => setTime(new Date()), 1000);
    return () => clearInterval(id);
  }, []);

  // Parallax + scroll zoom
  useEffect(() => {
    const onScroll = () => {
      if (!bgRef.current) return;
      const y = window.scrollY;
      const scale = 1 + Math.min(y / 2000, 0.18);
      const ty = y * 0.35;
      bgRef.current.style.transform = `translate3d(0, ${ty}px, 0) scale(${scale})`;
    };
    const onMove = (e) => {
      if (!bgRef.current) return;
      const w = window.innerWidth, h = window.innerHeight;
      const px = (e.clientX / w - 0.5) * 12;
      const py = (e.clientY / h - 0.5) * 8;
      bgRef.current.style.setProperty('--mx', `${px}px`);
      bgRef.current.style.setProperty('--my', `${py}px`);
      bgRef.current.style.backgroundPosition = `calc(50% + ${-px}px) calc(60% + ${-py}px)`;
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('mousemove', onMove);
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('mousemove', onMove);
    };
  }, []);

  const pad = (n) => String(n).padStart(2, '0');
  const localTime = `${pad(time.getHours())}:${pad(time.getMinutes())}:${pad(time.getSeconds())}`;
  const localDate = `${time.getFullYear()}-${pad(time.getMonth()+1)}-${pad(time.getDate())}`;
  let tzAbbr = 'LOCAL';
  try {
    const parts = new Intl.DateTimeFormat(undefined, { timeZoneName: 'short' }).formatToParts(time);
    const tz = parts.find(p => p.type === 'timeZoneName');
    if (tz && tz.value) tzAbbr = tz.value.toUpperCase();
  } catch (e) {}

  return (
    <section className="hero" data-screen-label="01 Hero">
      <div className="hero-bg-wrap">
        <div className="hero-bg-blur" />
        <div className="hero-bg" ref={bgRef} />
        <div className="hero-grid" />
      </div>
      <Particles />
      <div className="hero-hud"><i className="corner bl"/><i className="corner br"/></div>

      <div className="hero-meta-tr">
        {tzAbbr} {localTime}<br />
        <span>SIGNAL · LOCKED</span>
      </div>
      <div className="hero-meta-bl">
        v1.0.0 · STABLE<br />
        <span>ALL ITEMS RESOLVED</span>
      </div>
      <div className="hero-meta-br">
        LAST SYNC<br />
        <span>{localDate}</span>
      </div>

      <div className="hero-eyebrow hero-eyebrow-top">JOVANA MEDICAL · ARCHIVE</div>

      <div className="hero-content">
        <h1 className="hero-title">
          國考<em>全方位</em>攻克
        </h1>
        <p className="hero-sub">
          國考逐題詳解、命中重新註解、
          科別主題索引、計時模擬、錯題回返、文獻每日攝取。<br />
          一座為國考夜行者打造的全息檔案室。
        </p>
        <div className="hero-ctas">
          {user ? (
            <a className="btn btn-primary" href="/dashboard.html">
              <span>Open Dashboard</span>
              <span className="arrow" aria-hidden>→</span>
            </a>
          ) : (
            <button className="btn btn-primary" onClick={onSignIn}>
              <span>Enter the Archive</span>
              <span className="arrow" aria-hidden>→</span>
            </button>
          )}
          <a className="btn btn-ghost" href="#features">
            <span>System Tour</span>
            <span className="arrow" aria-hidden>↓</span>
          </a>
        </div>
      </div>

      <div className="scroll-cue">
        <span>SCROLL</span>
        <span className="line" />
      </div>
    </section>
  );
}

window.Hero = Hero;
window.BrandMark = BrandMark;
