// Components for Holistic Radar landing page
// Exports: Radar, Pyramid, Icon

const { useState, useEffect, useRef } = React;

// ============ RADAR ============
function Radar({ pings = true }) {
  const [angle, setAngle] = useState(0);
  const rafRef = useRef(null);

  useEffect(() => {
    if (!pings) return;
    let last = performance.now();
    const tick = (t) => {
      const dt = (t - last) / 1000;
      last = t;
      setAngle((a) => (a + dt * 60) % 360); // 60deg/s
      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, [pings]);

  // fixed blip positions (so they don't jump on re-render)
  const blips = [
    { r: 0.30, theta: 30,  label: "Vision" },
    { r: 0.50, theta: 90,  label: "Strategy" },
    { r: 0.62, theta: 160, label: "Brand" },
    { r: 0.42, theta: 215, label: "Systems" },
    { r: 0.68, theta: 285, label: "Sales" },
    { r: 0.25, theta: 335, label: "Self" },
  ];

  return (
    <div className="radar-wrap" aria-hidden="true">
      <svg viewBox="0 0 400 400" style={{ width: "100%", height: "100%", overflow: "visible" }}>
        <defs>
          <radialGradient id="radarBg" cx="50%" cy="50%" r="50%">
            <stop offset="0%" stopColor="oklch(0.28 0.04 75)" stopOpacity="0.4" />
            <stop offset="100%" stopColor="oklch(0.18 0.015 250)" stopOpacity="0" />
          </radialGradient>
          <linearGradient id="sweepGrad" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0%" stopColor="oklch(0.82 0.17 75)" stopOpacity="0" />
            <stop offset="100%" stopColor="oklch(0.82 0.17 75)" stopOpacity="0.55" />
          </linearGradient>
        </defs>

        {/* outer atmospheric glow */}
        <circle cx="200" cy="200" r="180" fill="url(#radarBg)" />

        {/* concentric rings */}
        {[60, 100, 140, 180].map((r, i) => (
          <circle
            key={i}
            cx="200" cy="200" r={r}
            fill="none"
            stroke="oklch(0.32 0.02 250)"
            strokeWidth="1"
            strokeDasharray={i === 3 ? "" : "2 4"}
          />
        ))}

        {/* crosshairs */}
        <line x1="20" y1="200" x2="380" y2="200" stroke="oklch(0.28 0.018 250)" strokeWidth="1" />
        <line x1="200" y1="20" x2="200" y2="380" stroke="oklch(0.28 0.018 250)" strokeWidth="1" />

        {/* tick marks */}
        {Array.from({ length: 24 }).map((_, i) => {
          const a = (i * 15) * Math.PI / 180;
          const x1 = 200 + Math.cos(a) * 178;
          const y1 = 200 + Math.sin(a) * 178;
          const x2 = 200 + Math.cos(a) * (i % 6 === 0 ? 168 : 174);
          const y2 = 200 + Math.sin(a) * (i % 6 === 0 ? 168 : 174);
          return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2} stroke="oklch(0.45 0.02 250)" strokeWidth="1" />;
        })}

        {/* sweep */}
        {pings && (
          <g style={{ transform: `rotate(${angle}deg)`, transformOrigin: "200px 200px" }}>
            <path
              d="M 200 200 L 380 200 A 180 180 0 0 0 305 50 Z"
              fill="url(#sweepGrad)"
              opacity="0.9"
            />
            <line x1="200" y1="200" x2="380" y2="200" stroke="oklch(0.82 0.17 75)" strokeWidth="1.5" />
          </g>
        )}

        {/* blips */}
        {blips.map((b, i) => {
          const a = b.theta * Math.PI / 180;
          const x = 200 + Math.cos(a) * b.r * 170;
          const y = 200 + Math.sin(a) * b.r * 170;
          // reveal pulse based on sweep angle proximity
          const sweepDelta = pings ? Math.abs(((angle - b.theta + 540) % 360) - 180) : 180;
          const recent = 180 - sweepDelta; // 0..180
          const pulse = Math.max(0, recent - 130) / 50; // last ~50deg of sweep
          return (
            <g key={i}>
              <circle cx={x} cy={y} r={3 + pulse * 8} fill="oklch(0.82 0.17 75)" opacity={0.15 + pulse * 0.4} />
              <circle cx={x} cy={y} r={2.5} fill="oklch(0.82 0.17 75)" />
              <text
                x={x + 10} y={y + 4}
                fill="oklch(0.82 0.17 75)"
                fontFamily="JetBrains Mono, monospace"
                fontSize="9"
                opacity={0.4 + pulse * 0.6}
                letterSpacing="0.5"
              >
                {b.label.toUpperCase()}
              </text>
            </g>
          );
        })}

        {/* center */}
        <circle cx="200" cy="200" r="4" fill="oklch(0.94 0.012 80)" />
        <circle cx="200" cy="200" r="10" fill="none" stroke="oklch(0.94 0.012 80)" strokeWidth="0.5" opacity="0.5" />

        {/* corner readouts */}
        <text x="20" y="20" fill="oklch(0.62 0.015 250)" fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="1">
          HR-360°
        </text>
        <text x="380" y="20" textAnchor="end" fill="oklch(0.62 0.015 250)" fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="1">
          SCAN ACTIVE
        </text>
        <text x="20" y="392" fill="oklch(0.62 0.015 250)" fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="1">
          6 SIGNALS
        </text>
        <text x="380" y="392" textAnchor="end" fill="oklch(0.62 0.015 250)" fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="1">
          v.04
        </text>
      </svg>
    </div>
  );
}

// ============ PYRAMID ============
function Pyramid({ tiers, activeIdx, onSelect }) {
  // tiers ordered top -> bottom
  const total = tiers.length;
  const baseWidth = 100; // %
  const topWidth = 28;

  return (
    <div style={{ position: "relative", padding: "24px 0" }}>
      <svg viewBox={`0 0 500 ${24 + total * 58 + 24}`} style={{ width: "100%", height: "auto", overflow: "visible" }}>
        <defs>
          <linearGradient id="pyGlow" x1="50%" y1="0%" x2="50%" y2="100%">
            <stop offset="0%" stopColor="oklch(0.82 0.17 75)" stopOpacity="0.3" />
            <stop offset="100%" stopColor="oklch(0.82 0.17 75)" stopOpacity="0" />
          </linearGradient>
        </defs>

        {tiers.map((tier, i) => {
          const isActive = i === activeIdx;
          // i=0 is top tier (smallest)
          const rowH = 58;
          const y = 24 + i * rowH;
          const t1 = i / total;
          const t2 = (i + 1) / total;
          const w1 = topWidth + (baseWidth - topWidth) * t1;
          const w2 = topWidth + (baseWidth - topWidth) * t2;
          const cx = 250;
          const x1L = cx - (w1 / 2) * 4.4;
          const x1R = cx + (w1 / 2) * 4.4;
          const x2L = cx - (w2 / 2) * 4.4;
          const x2R = cx + (w2 / 2) * 4.4;

          return (
            <g
              key={i}
              onClick={() => onSelect(i)}
              style={{ cursor: "pointer" }}
            >
              <polygon
                points={`${x1L},${y} ${x1R},${y} ${x2R},${y + rowH - 4} ${x2L},${y + rowH - 4}`}
                fill={isActive ? "oklch(0.82 0.17 75)" : "oklch(0.27 0.02 250)"}
                stroke={isActive ? "oklch(0.82 0.17 75)" : "oklch(0.42 0.02 250)"}
                strokeWidth="1"
                style={{ transition: "fill 0.25s, stroke 0.25s" }}
              />
              {/* tier number */}
              <text
                x={x2L - 18}
                y={y + rowH / 2}
                textAnchor="end"
                dominantBaseline="middle"
                fill={isActive ? "oklch(0.82 0.17 75)" : "oklch(0.62 0.015 250)"}
                fontFamily="JetBrains Mono, monospace"
                fontSize="11"
                letterSpacing="1"
                style={{ transition: "fill 0.25s" }}
              >
                T{total - i}
              </text>
              {/* tier label */}
              <text
                x={cx}
                y={y + rowH / 2}
                textAnchor="middle"
                dominantBaseline="middle"
                fill={isActive ? "oklch(0.18 0.015 250)" : "oklch(0.94 0.012 80)"}
                fontFamily="Instrument Serif, serif"
                fontSize={i === 0 ? "20" : "22"}
                style={{ transition: "fill 0.25s" }}
              >
                {tier.title}
              </text>
              {/* keyword on right */}
              <text
                x={x2R + 18}
                y={y + rowH / 2}
                dominantBaseline="middle"
                fill={isActive ? "oklch(0.82 0.17 75)" : "oklch(0.62 0.015 250)"}
                fontFamily="JetBrains Mono, monospace"
                fontSize="10"
                letterSpacing="1.5"
                style={{ transition: "fill 0.25s" }}
              >
                {tier.keyword.toUpperCase()}
              </text>
            </g>
          );
        })}
      </svg>
    </div>
  );
}

// ============ Icon ============
function Icon({ name, size = 22 }) {
  const props = {
    width: size, height: size, viewBox: "0 0 24 24",
    fill: "none", stroke: "currentColor", strokeWidth: "1.5",
    strokeLinecap: "round", strokeLinejoin: "round",
  };
  switch (name) {
    case "saas":
      return (<svg {...props}><rect x="3" y="4" width="18" height="14" rx="2"/><path d="M3 10h18"/><circle cx="6.5" cy="7" r="0.5" fill="currentColor"/><path d="M9 22h6"/><path d="M12 18v4"/></svg>);
    case "ecom":
      return (<svg {...props}><path d="M3 4h2l2.5 12h12L22 8H6"/><circle cx="9" cy="20" r="1.5"/><circle cx="18" cy="20" r="1.5"/></svg>);
    case "founder":
      return (<svg {...props}><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8"/></svg>);
    case "arrow":
      return (<svg {...props}><path d="M5 12h14M13 6l6 6-6 6"/></svg>);
    case "play":
      return (<svg {...props}><polygon points="6 4 20 12 6 20 6 4" fill="currentColor"/></svg>);
    default: return null;
  }
}

Object.assign(window, { Radar, Pyramid, Icon });
