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

// ===== Custom Cursor =====
function Cursor() {
  const [pos, setPos] = useState({ x: -100, y: -100 });
  const [hovering, setHovering] = useState(false);
  const ringRef = useRef(null);

  useEffect(() => {
    const move = (e) => setPos({ x: e.clientX, y: e.clientY });
    const over = (e) => {
      if (e.target.closest('a, button, [data-hover]')) setHovering(true);
      else setHovering(false);
    };
    window.addEventListener('mousemove', move);
    window.addEventListener('mouseover', over);
    return () => {
      window.removeEventListener('mousemove', move);
      window.removeEventListener('mouseover', over);
    };
  }, []);

  // smooth ring follow
  useEffect(() => {
    let raf;
    let rx = pos.x, ry = pos.y;
    const tick = () => {
      rx += (pos.x - rx) * 0.18;
      ry += (pos.y - ry) * 0.18;
      if (ringRef.current) {
        ringRef.current.style.transform = `translate(${rx}px, ${ry}px) translate(-50%, -50%)`;
      }
      raf = requestAnimationFrame(tick);
    };
    tick();
    return () => cancelAnimationFrame(raf);
  });

  const fmt = (n) => String(Math.round(n)).padStart(4, '0');

  return (
    <>
      <div className="cursor-dot" style={{ transform: `translate(${pos.x}px, ${pos.y}px) translate(-50%, -50%)` }} />
      <div ref={ringRef} className={`cursor-ring ${hovering ? 'is-hover' : ''}`} />
      <div className="cursor-coords" style={{ transform: `translate(${pos.x + 24}px, ${pos.y + 24}px)` }}>
        SCAN [{fmt(pos.x)},{fmt(pos.y)}] · {hovering ? 'LOCK' : 'IDLE'}
      </div>
    </>
  );
}

// ===== Logo Mark =====
function LogoMark() {
  return (
    <img src="assets/linkguard-logo.jpg" alt="LinkGuard" className="logo-img" />
  );
}

// ===== Nav =====
function Nav() {
  return (
    <nav className="nav">
      <div className="nav-logo">
        <LogoMark />
        <div className="name">LINK<b>GUARD</b> / 聯動守護</div>
      </div>
      <div className="nav-links">
        <a href="#mission" data-num="01">任務</a>
        <a href="#system" data-num="02">系統</a>
        <a href="#architecture" data-num="03">架構</a>
        <a href="#chain" data-num="04">傳輸鏈</a>
        <a href="#data" data-num="05">實證</a>
        <a href="#team" data-num="06">團隊</a>
      </div>
      <button className="nav-cta">
        部署中 <span style={{ color: '#e8401b' }}>●</span>
      </button>
    </nav>
  );
}

// ===== Radar SVG =====
function HeroRadar() {
  const [angle, setAngle] = useState(0);
  useEffect(() => {
    let raf;
    let t = 0;
    const tick = () => {
      t += 0.6;
      setAngle(t);
      raf = requestAnimationFrame(tick);
    };
    tick();
    return () => cancelAnimationFrame(raf);
  }, []);

  const targets = [
    { r: 90, a: 30, hr: 78 },
    { r: 140, a: 200, hr: 92 },
    { r: 175, a: 290, hr: 0 },
  ];

  return (
    <svg viewBox="-220 -220 440 440" className="hero-radar">
      <defs>
        <radialGradient id="rad-glow" cx="0" cy="0" r="220" gradientUnits="userSpaceOnUse">
          <stop offset="0" stopColor="#1d6fe0" stopOpacity="0.10" />
          <stop offset="0.6" stopColor="#1d6fe0" stopOpacity="0.03" />
          <stop offset="1" stopColor="#1d6fe0" stopOpacity="0" />
        </radialGradient>
        <linearGradient id="sweep" x1="0" y1="0" x2="200" y2="0" gradientUnits="userSpaceOnUse">
          <stop offset="0" stopColor="#1d6fe0" stopOpacity="0" />
          <stop offset="1" stopColor="#1d6fe0" stopOpacity="0.45" />
        </linearGradient>
      </defs>

      <circle r="200" fill="url(#rad-glow)" />
      {[40, 80, 120, 160, 200].map((r, i) => (
        <circle key={r} r={r} fill="none" stroke="#1d6fe0" strokeOpacity={0.22 - i * 0.025} strokeWidth="0.5" />
      ))}
      {/* crosshairs */}
      <line x1="-200" y1="0" x2="200" y2="0" stroke="#1d6fe0" strokeOpacity="0.18" strokeWidth="0.5" strokeDasharray="2 4" />
      <line x1="0" y1="-200" x2="0" y2="200" stroke="#1d6fe0" strokeOpacity="0.18" strokeWidth="0.5" strokeDasharray="2 4" />

      {/* sweep */}
      <g transform={`rotate(${angle})`}>
        <path d={`M 0 0 L 200 0 A 200 200 0 0 0 ${200 * Math.cos(-Math.PI / 4)} ${200 * Math.sin(-Math.PI / 4)} Z`} fill="url(#sweep)" opacity="0.6" />
        <line x1="0" y1="0" x2="200" y2="0" stroke="#1d6fe0" strokeWidth="1" opacity="0.85" />
      </g>

      {/* targets */}
      {targets.map((t, i) => {
        const x = t.r * Math.cos(t.a * Math.PI / 180);
        const y = t.r * Math.sin(t.a * Math.PI / 180);
        const isAlert = t.hr === 0;
        return (
          <g key={i} transform={`translate(${x},${y})`}>
            <circle r="14" fill="none" stroke={isAlert ? "#e8401b" : "#1d6fe0"} strokeWidth="0.8" opacity="0.55">
              <animate attributeName="r" from="6" to="20" dur="2s" repeatCount="indefinite" />
              <animate attributeName="opacity" from="0.7" to="0" dur="2s" repeatCount="indefinite" />
            </circle>
            <circle r="3" fill={isAlert ? "#e8401b" : "#1d6fe0"} />
            <text x="10" y="-6" fill={isAlert ? "#e8401b" : "#1d6fe0"} fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="0.1em">
              {isAlert ? 'SOS' : `${t.hr}BPM`}
            </text>
          </g>
        );
      })}

      {/* center */}
      <circle r="3" fill="#1d6fe0" />
      <text y="220" textAnchor="middle" fill="#7c8699" fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="0.18em">
        CMD CENTER · 25.0330°N 121.5654°E
      </text>
    </svg>
  );
}

// ===== Reveal hook =====
function useReveal() {
  useEffect(() => {
    // If user prefers reduced motion, just reveal everything immediately.
    const prm = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (prm) {
      const reveal = () => {
        document.querySelectorAll('.reveal:not(.in), .reveal-stagger:not(.in)').forEach((el) => el.classList.add('in'));
      };
      reveal();
      const mo = new MutationObserver(reveal);
      mo.observe(document.body, { childList: true, subtree: true });
      return () => mo.disconnect();
    }

    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add('in');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.1 });

    const observeAll = () => {
      document.querySelectorAll('.reveal:not(.in), .reveal-stagger:not(.in)').forEach((el) => io.observe(el));
    };

    observeAll();

    // Watch for newly mounted nodes (e.g. accordion children, lazy sections)
    const mo = new MutationObserver(() => observeAll());
    mo.observe(document.body, { childList: true, subtree: true });

    // safety fallback: if anything visible is still hidden after 2s, force-reveal
    const t = setTimeout(() => {
      document.querySelectorAll('.reveal:not(.in), .reveal-stagger:not(.in)').forEach((el) => {
        const r = el.getBoundingClientRect();
        if (r.top < window.innerHeight * 1.2) el.classList.add('in');
      });
      observeAll();
    }, 1500);

    return () => { io.disconnect(); mo.disconnect(); clearTimeout(t); };
  }, []);
}

// ===== Hero =====
function Hero({ showRadar = true }) {
  const [time, setTime] = useState(new Date());
  useEffect(() => {
    const t = setInterval(() => setTime(new Date()), 1000);
    return () => clearInterval(t);
  }, []);
  const pad = (n) => String(n).padStart(2, '0');
  const ts = `${time.getUTCFullYear()}.${pad(time.getUTCMonth()+1)}.${pad(time.getUTCDate())} · ${pad(time.getUTCHours())}:${pad(time.getUTCMinutes())}:${pad(time.getUTCSeconds())} UTC`;

  return (
    <header className="hero" id="top">
      {showRadar && <HeroRadar />}
      <div className="container">
        <div className="hero-grid">
          <div className="hero-tag-row">
            <span>[ 00 ] / 系統總覽</span>
            <span>{ts}</span>
            <span>狀態 · <span style={{ color: '#4ddca8' }}>● 連線中</span></span>
          </div>

          <h1 className="display hero-title">
            <span className="line"><span>穿透廢墟的</span></span>
            <span className="line"><span>生命連結</span></span>
            <span className="line"><span className="en">LinkGuard-E · Signal beyond the rubble.</span></span>
          </h1>

          <p className="hero-sub">
            LinkGuard-E 為基於 Sub-GHz LoRa 異質網路與超寬頻定位之廢墟穿透搜救通訊系統 ——
            整合 433 MHz ISM CSS 擴頻、UWB PDOA 公分級定位與 BLE 5.0 穿戴式生理感測，
            在地震倒塌建築形成的法拉第籠下，建立穩定的雙向資料鏈路。
            <span style={{ color: '#1d6fe0' }}>讓黃金 72 小時不再失聯。</span>
          </p>

          <div className="hero-awards">
            <div className="hero-award">
              <span className="hero-award-badge">🏆</span>
              <span>中華民國中小學科學展覽會　分區科展　特優</span>
            </div>
            <div className="hero-award">
              <span className="hero-award-badge">🏅</span>
              <span>第 22 屆全國電子設計創意競賽　高中職組　智慧物聯網類　SI10 佳作</span>
            </div>
            <div className="hero-award">
              <span className="hero-award-badge">🎖️</span>
              <span>中學生小論文競賽　甲等</span>
            </div>
          </div>

          <div className="hero-meta">
            <div className="hero-meta-cell">
              <div className="v">15<span className="unit">m</span></div>
              <div className="k">廢墟穿透深度</div>
            </div>
            <div className="hero-meta-cell">
              <div className="v">900<span className="unit">m</span></div>
              <div className="k">場域距離 / 433MHz</div>
            </div>
            <div className="hero-meta-cell">
              <div className="v">96.5<span className="unit">%</span></div>
              <div className="k">封包到達率</div>
            </div>
            <div className="hero-meta-cell">
              <div className="v">235<span className="unit">hr</span></div>
              <div className="k">續航時數</div>
            </div>
          </div>
        </div>
      </div>
    </header>
  );
}

// ===== About / Mission =====
function About() {
  return (
    <section id="mission">
      <div className="container">
        <div className="section-head">
          <div className="meta">
            <span className="label">[ 01 ]</span>
            <span className="label">/ 任務</span>
          </div>
          <h2 className="h2 reveal">
            建築倒塌瞬間，<br />
            通訊先於建築物先一步崩塌。
          </h2>
        </div>

        <div className="about-grid">
          <div className="about-narrative reveal">
            <p>
              台灣位於板塊交界，地震頻仍。從 <span className="key">集集</span> 到 <span className="key">維冠大樓</span>，
              真正奪走生命的不是搖晃本身，而是建築倒塌後形成的封閉空間與斷絕的通訊。
            </p>
            <p>
              現代 RC 建築倒塌後，密集的鋼筋網格形成 <span className="signal">法拉第籠</span> ——
              4G、5G、Wi-Fi 等高頻訊號在進入廢墟的瞬間遭受極大衰減，
              受困者瞬間淪為數位孤島。
            </p>
            <p>
              LinkGuard 從物理層出發，採用 433MHz ISM 頻段的長波長繞射優勢，
              結合 LoRa 擴頻調變的低訊噪比解調能力，重新建立廢墟內外的生命線。
            </p>
          </div>

          <aside className="about-stats reveal">
            <div className="about-stat">
              <div className="num">72<span style={{fontSize:'18px',color:'var(--fg-2)'}}>h</span></div>
              <div className="lbl">災後黃金搜救時間 ——<br />存活率每小時呈指數下降</div>
            </div>
            <div className="about-stat">
              <div className="num">22<span style={{fontSize:'18px',color:'var(--fg-2)'}}>dB</span></div>
              <div className="lbl">每穿透一層 RC 樓板的訊號衰減<br /><span className="mono" style={{color:'var(--fg-3)'}}>樓板衰減係數 · 433MHz</span></div>
            </div>
            <div className="about-stat">
              <div className="num">{'<'}50<span style={{fontSize:'18px',color:'var(--fg-2)'}}>m</span></div>
              <div className="lbl">傳統 2.4GHz 在廢墟中的有效距離 ——<br />本系統的十八分之一</div>
            </div>
            <div className="about-stat">
              <div className="num">3.6<span style={{fontSize:'18px',color:'var(--fg-2)'}}>km</span></div>
              <div className="lbl">15 cm 含水混凝土等效空氣距離 ——<br />解釋了為何受困者求救無門</div>
            </div>
          </aside>
        </div>
      </div>
    </section>
  );
}

window.LGCore = { Cursor, Nav, Hero, About, useReveal, LogoMark };
