// Shared low-level components for TagWave landing

const { useEffect, useRef, useState } = React;

function Reveal({ children, delay = 0, as: As = "div", className = "", style = {} }) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let done = false;
    const reveal = () => {
      if (done) return;
      done = true;
      setTimeout(() => setSeen(true), delay);
    };
    // Synchronously check if in view on mount (fallback if IO doesn't fire)
    const rect = el.getBoundingClientRect();
    const vh = window.innerHeight || document.documentElement.clientHeight;
    if (rect.top < vh * 0.95 && rect.bottom > 0) {
      reveal();
    }
    // Safety net: always reveal after 600ms regardless
    const failsafe = setTimeout(reveal, 600);
    let io;
    try {
      io = new IntersectionObserver((entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            reveal();
            io && io.unobserve(el);
          }
        });
      }, { threshold: 0.15 });
      io.observe(el);
    } catch (_) {}
    return () => { io && io.disconnect(); clearTimeout(failsafe); };
  }, [delay]);
  return (
    <As ref={ref} className={`reveal ${seen ? "in" : ""} ${className}`} style={style}>
      {children}
    </As>
  );
}

function Wave({ count = 32, height = 28, peakBias = 0.6 }) {
  const bars = Array.from({ length: count }).map((_, i) => {
    const t = i / count;
    // Two peaks, modulated
    const v = 0.35 + 0.65 * Math.abs(Math.sin(i * 0.42) * Math.cos(i * 0.18 + 1.1));
    const h = Math.max(3, v * height * (peakBias + 0.5));
    return <i key={i} style={{ height: `${h}px`, animationDelay: `${(i % 7) * 0.08}s` }} />;
  });
  return <span className="wave" style={{ height }}>{bars}</span>;
}

function MiniWave({ pattern }) {
  // deterministic pattern for table rows
  const bars = pattern.map((v, i) => (
    <i key={i} style={{ height: `${Math.max(2, v * 22)}px`, opacity: 0.4 + v * 0.6 }} />
  ));
  return <span className="wave-mini">{bars}</span>;
}

function Chip({ children, warn = false }) {
  return (
    <span className={`chip ${warn ? "chip-warn" : ""}`}>
      <span className="led"></span>
      {children}
    </span>
  );
}

function LogoMark({ size = 24 }) {
  // fill-rule evenodd creates a true transparent ring (donut) — no fill on the inner path
  return (
    <svg width={size} height={size} viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
      <path
        fillRule="evenodd"
        fill="#D4503A"
        d="M50 0 A50 50 0 0 1 100 50 A50 50 0 0 1 50 100 A50 50 0 0 1 0 50 A50 50 0 0 1 50 0 Z M50 22 A28 28 0 0 1 78 50 A28 28 0 0 1 50 78 A28 28 0 0 1 22 50 A28 28 0 0 1 50 22 Z"
      />
    </svg>
  );
}

function Logo() {
  return (
    <a className="logo" href="#top" style={{ display: "inline-flex", alignItems: "center", textDecoration: "none" }}>
      {/* Full logo: mark + wordmark */}
      <span className="logo-img-full">
        <LogoMark size={26} />
        <span style={{
          fontFamily: "'Geist', 'Helvetica Neue', Helvetica, sans-serif",
          fontWeight: 600,
          fontSize: 17,
          letterSpacing: "-0.02em",
          color: "var(--bone)",
          lineHeight: 1,
        }}>TagWave</span>
      </span>
      {/* Icon only — mobile */}
      <span className="logo-img-mark">
        <LogoMark size={34} />
      </span>
    </a>
  );
}

function CTAButton({ children, variant = "primary", as: As = "button", ...rest }) {
  const cls = variant === "primary" ? "btn btn-primary" : "btn btn-ghost";
  return (
    <As className={cls} {...rest}>
      <span className="dot"></span>
      {children}
    </As>
  );
}

// Floating UI card used around hero image
function FloatCard({ children, style, animClass = "" }) {
  return (
    <div className={`float-card glass ${animClass}`} style={style}>
      {children}
    </div>
  );
}

// Tiny key/value row used inside cards
function KV({ k, v, accent = false }) {
  return (
    <div style={{ display: "flex", justifyContent: "space-between", fontFamily: "'JetBrains Mono', monospace", fontSize: 11, padding: "4px 0", color: "var(--bone-dim)" }}>
      <span>{k}</span>
      <b style={{ color: accent ? "var(--accent-bright)" : "var(--bone)", fontWeight: 500 }}>{v}</b>
    </div>
  );
}

Object.assign(window, { Reveal, Wave, MiniWave, Chip, Logo, CTAButton, FloatCard, KV });
