// ============================================================
// Control AI — Kinetic Observatory
// Shared primitives & section components
// ============================================================

const { useState, useEffect, useRef, useMemo } = React;

// ---- Three.js 3D Earth -------------------------------------------
function ThreeGlobe({ cameraZ = 5.0 }) {
  const mountRef = useRef(null);
  const cameraRef = useRef(null);
  useEffect(() => {
    const mount = mountRef.current;
    if (!mount || !window.THREE) return;
    const THREE = window.THREE;

    const w = mount.clientWidth;
    const h = mount.clientHeight;

    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(35, w / h, 0.1, 100);
    camera.position.set(0, 0, cameraZ);
    cameraRef.current = camera;

    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    renderer.setSize(w, h);
    renderer.setClearColor(0x000000, 0);
    mount.appendChild(renderer.domElement);

    const loader = new THREE.TextureLoader();
    loader.setCrossOrigin("anonymous");

    // NASA Blue Marble textures via jsdelivr from three.js examples repo (stable CDN)
    const BASE = "https://cdn.jsdelivr.net/gh/mrdoob/three.js@r160/examples/textures/planets/";
    const earthTex = loader.load(BASE + "earth_atmos_2048.jpg");
    const specTex = loader.load(BASE + "earth_specular_2048.jpg");
    const normTex = loader.load(BASE + "earth_normal_2048.jpg");
    const cloudTex = loader.load(BASE + "earth_clouds_1024.png");
    earthTex.colorSpace = THREE.SRGBColorSpace;

    // Earth
    const earthGeo = new THREE.SphereGeometry(1, 96, 96);
    const earthMat = new THREE.MeshPhongMaterial({
      map: earthTex,
      specularMap: specTex,
      normalMap: normTex,
      normalScale: new THREE.Vector2(0.85, 0.85),
      specular: new THREE.Color(0x335577),
      shininess: 18,
    });
    const earth = new THREE.Mesh(earthGeo, earthMat);
    earth.rotation.z = 0.41; // axial tilt
    scene.add(earth);

    // Cloud layer
    const cloudsGeo = new THREE.SphereGeometry(1.012, 64, 64);
    const cloudsMat = new THREE.MeshPhongMaterial({
      map: cloudTex,
      transparent: true,
      opacity: 0.55,
      depthWrite: false,
    });
    const clouds = new THREE.Mesh(cloudsGeo, cloudsMat);
    clouds.rotation.z = 0.41;
    scene.add(clouds);

    // Atmosphere glow (back-facing shader shell) — subtle, warm-neutral tint to sit with amber brand
    const atmoMat = new THREE.ShaderMaterial({
      vertexShader: `
        varying vec3 vNormal;
        void main() {
          vNormal = normalize(normalMatrix * normal);
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }`,
      fragmentShader: `
        varying vec3 vNormal;
        void main() {
          float intensity = pow(0.52 - dot(vNormal, vec3(0.0, 0.0, 1.0)), 3.0);
          gl_FragColor = vec4(0.55, 0.72, 0.95, 1.0) * intensity * 0.55;
        }`,
      blending: THREE.AdditiveBlending,
      side: THREE.BackSide,
      transparent: true,
    });
    const atmo = new THREE.Mesh(new THREE.SphereGeometry(1.06, 64, 64), atmoMat);
    scene.add(atmo);

    // Lighting — warm sun from upper-left (to echo hero's tungsten accent)
    const sun = new THREE.DirectionalLight(0xfff1d8, 2.6);
    sun.position.set(-3, 1.2, 2.5);
    scene.add(sun);
    const ambient = new THREE.AmbientLight(0x223344, 0.35);
    scene.add(ambient);
    const rim = new THREE.DirectionalLight(0x4488cc, 0.35);
    rim.position.set(2, -1, -2);
    scene.add(rim);

    let raf;
    const start = performance.now();
    const animate = () => {
      const t = (performance.now() - start) / 1000;
      earth.rotation.y = t * 0.06;
      clouds.rotation.y = t * 0.075;
      renderer.render(scene, camera);
      raf = requestAnimationFrame(animate);
    };
    animate();

    const onResize = () => {
      const nw = mount.clientWidth, nh = mount.clientHeight;
      camera.aspect = nw / nh; camera.updateProjectionMatrix();
      renderer.setSize(nw, nh);
    };
    const ro = new ResizeObserver(onResize);
    ro.observe(mount);

    return () => {
      cancelAnimationFrame(raf);
      ro.disconnect();
      renderer.dispose();
      earthGeo.dispose(); earthMat.dispose();
      cloudsGeo.dispose(); cloudsMat.dispose();
      atmoMat.dispose();
      if (renderer.domElement.parentNode) renderer.domElement.parentNode.removeChild(renderer.domElement);
    };
  }, []);

  // React to cameraZ prop changes (driven by scroll)
  useEffect(() => {
    if (cameraRef.current) {
      cameraRef.current.position.z = cameraZ;
    }
  }, [cameraZ]);

  return <div ref={mountRef} className="absolute inset-0" style={{ pointerEvents: "none" }} />;
}

// ---- Small utilities ---------------------------------------------

function useTicker(intervalMs = 1000) {
  const [tick, setTick] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setTick((t) => t + 1), intervalMs);
    return () => clearInterval(id);
  }, [intervalMs]);
  return tick;
}

function useInView(ref, opts = { threshold: 0.15 }) {
  const [inView, setInView] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const obs = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) setInView(true);
    }, opts);
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, []);
  return inView;
}

function pad(n, w = 2) {
  return String(n).padStart(w, "0");
}

function formatClock(d = new Date()) {
  return `${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())} UTC`;
}

// ---- Crosshair corner frame --------------------------------------

function CornerFrame({ children, className = "", size = 10, color = "primary/40" }) {
  return (
    <div className={`relative ${className}`}>
      <div className={`absolute top-0 left-0 border-t border-l border-${color}`} style={{ width: size, height: size }} />
      <div className={`absolute top-0 right-0 border-t border-r border-${color}`} style={{ width: size, height: size }} />
      <div className={`absolute bottom-0 left-0 border-b border-l border-${color}`} style={{ width: size, height: size }} />
      <div className={`absolute bottom-0 right-0 border-b border-r border-${color}`} style={{ width: size, height: size }} />
      {children}
    </div>
  );
}

// ---- Telemetry label ---------------------------------------------

function TeleLabel({ children, className = "" }) {
  return (
    <span className={`font-label text-[10px] tracking-[0.2em] uppercase text-outline ${className}`}>
      {children}
    </span>
  );
}

function SectionTag({ num, children }) {
  return (
    <div className="inline-flex items-center gap-3 mb-8">
      <span className="font-label text-[10px] tracking-[0.3em] text-primary">{num}</span>
      <span className="h-px w-8 bg-outline-variant/40" />
      <span className="font-label text-[10px] tracking-[0.3em] text-on-surface-variant uppercase">{children}</span>
    </div>
  );
}

// ---- Status dot --------------------------------------------------

function StatusDot({ state = "nominal", pulse = true }) {
  const color =
    state === "nominal" ? "bg-secondary" :
    state === "warning" ? "bg-primary" :
    state === "info" ? "bg-tertiary" :
    state === "idle" ? "bg-outline" :
    "bg-error";
  return (
    <span className="relative inline-flex items-center justify-center" style={{ width: 8, height: 8 }}>
      <span className={`absolute inset-0 ${color} ${pulse ? "animate-ping opacity-40" : ""}`} style={{ borderRadius: 9999 }} />
      <span className={`relative ${color}`} style={{ width: 6, height: 6, borderRadius: 9999 }} />
    </span>
  );
}

// ---- Coordinate grid background ----------------------------------

function GridBackdrop({ className = "", opacity = 0.05 }) {
  return (
    <svg className={`absolute inset-0 w-full h-full pointer-events-none ${className}`} aria-hidden>
      <defs>
        <pattern id="grid-50" width="50" height="50" patternUnits="userSpaceOnUse">
          <path d="M 50 0 L 0 0 0 50" fill="none" stroke="currentColor" strokeWidth="0.5" opacity={opacity} />
        </pattern>
      </defs>
      <rect width="100%" height="100%" fill="url(#grid-50)" />
    </svg>
  );
}

// ============================================================
// NAV
// ============================================================

function TopNav() {
  const [time, setTime] = useState(formatClock());
  useEffect(() => {
    const id = setInterval(() => setTime(formatClock()), 1000);
    return () => clearInterval(id);
  }, []);
  return (
    <nav className="fixed top-0 w-full z-50 bg-surface/85 backdrop-blur-xl border-b border-outline-variant/10">
      <div className="flex justify-between items-center w-full px-4 md:px-8 py-3 md:py-4 max-w-screen-2xl mx-auto gap-4">
        <div className="flex items-center gap-6 min-w-0">
          <a href="#" className="flex items-center" aria-label="Control Labs">
            <img
              src="assets/Contorl_Labs_Logo.png"
              alt="Control Labs"
              className="h-10 md:h-12 w-auto object-contain"
              style={{ mixBlendMode: "lighten" }}
            />
          </a>
          <span className="hidden lg:inline font-label text-[9px] tracking-[0.3em] text-outline uppercase">{time}</span>
        </div>
        <div className="hidden md:flex gap-8 items-center">
          {["Platform", "AI Org", "Integrations", "Security", "Pricing"].map((x) => (
            <a key={x} className="text-on-surface-variant hover:text-primary transition-colors font-label uppercase text-[10px] tracking-widest" href="#">{x}</a>
          ))}
        </div>
        <div className="flex items-center gap-3 shrink-0">
          <button className="hidden lg:block text-on-surface-variant hover:text-primary font-label text-[10px] tracking-widest uppercase transition-colors">Sign in</button>
          <button className="bg-primary text-on-primary px-3 sm:px-5 py-2 sm:py-2.5 font-label text-[10px] font-bold tracking-widest uppercase hover:bg-primary-container transition-all active:scale-[0.98] whitespace-nowrap">
            <span className="hidden sm:inline">Request access</span>
            <span className="sm:hidden">Access</span>
          </button>
        </div>
      </div>
    </nav>
  );
}

function ThemeToggle() {
  const [dark, setDark] = React.useState(() => {
    try { return document.documentElement.classList.contains("dark"); } catch { return true; }
  });

  const toggle = () => {
    const next = !dark;
    setDark(next);
    document.documentElement.classList.toggle("dark", next);
    try { localStorage.setItem("control-theme", next ? "dark" : "light"); } catch {}
  };

  React.useEffect(() => {
    try {
      const saved = localStorage.getItem("control-theme");
      if (saved === "light") {
        document.documentElement.classList.remove("dark");
        setDark(false);
      }
    } catch {}
  }, []);

  return (
    <button
      onClick={toggle}
      className="relative w-14 h-7 border border-outline-variant/30 bg-surface-container hover:border-primary/40 transition-colors group"
      title={dark ? "Switch to light" : "Switch to dark"}
      aria-label="Toggle theme"
    >
      <span
        className="absolute top-[2px] w-[22px] h-[22px] bg-primary flex items-center justify-center transition-all duration-300"
        style={{ left: dark ? "2px" : "calc(100% - 24px)" }}
      >
        <span className="material-symbols-outlined text-on-primary" style={{ fontSize: 14 }}>
          {dark ? "dark_mode" : "light_mode"}
        </span>
      </span>
      <span className="sr-only">Toggle theme</span>
    </button>
  );
}

// ============================================================
// HERO
// ============================================================

function Hero() {
  const tick = useTicker(1000);
  const agents = 12 + (tick % 3);
  const tasks = 847 + tick * 2;
  const scrollY = useScrollY();
  // Camera pulls in from 4.2 (planet clearly visible with edge) to 2.5 (close-up) as user scrolls
  const cameraZ = 4.2 - Math.min(scrollY * 0.003, 1.7);
  const vignetteFade = Math.min(scrollY / 800, 1);

  return (
    <section className="hero-viewport relative min-h-[100vh] flex items-center justify-center overflow-hidden">
      {/* Hyper-realistic ROTATING Earth globe */}
      <div className="absolute inset-0 z-0 flex items-center justify-center">
        {/* Starfield behind */}
        <div className="absolute inset-0 bg-surface">
          <div className="absolute inset-0 opacity-70">
            {Array.from({ length: 80 }).map((_, i) => {
              const x = (i * 37) % 100;
              const y = (i * 53) % 100;
              const size = (i % 3) + 1;
              return (
                <span key={i} className="absolute bg-white" style={{
                  left: `${x}%`, top: `${y}%`, width: size, height: size,
                  opacity: 0.25 + (i % 5) * 0.12,
                  animation: `twinkle ${3 + (i % 5)}s ease-in-out ${i * 0.17}s infinite`,
                }} />
              );
            })}
          </div>
        </div>

        {/* Globe — fills the hero viewport; zoom driven by three.js camera, not CSS scale */}
        <div className="absolute inset-0">
          <ThreeGlobe cameraZ={cameraZ} />
        </div>

        {/* Layered atmosphere + vignette on top */}
        <div className="absolute inset-0 bg-gradient-to-b from-surface/30 via-transparent to-surface/80 pointer-events-none" />
        <div className="absolute inset-0 mix-blend-overlay pointer-events-none" style={{ background: "radial-gradient(ellipse at 50% 90%, rgba(255,200,128,0.12), transparent 60%)" }} />

        {/* Orbiting satellite ring */}
        <div className="absolute inset-0 pointer-events-none" style={{ animation: "slowspin 60s linear infinite" }}>
          <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[120vmax] h-[120vmax] border border-primary/10" style={{ borderRadius: "50%" }}>
            <span className="absolute top-0 left-1/2 -translate-x-1/2 -translate-y-1/2 w-2 h-2 bg-primary shadow-[0_0_12px_#ffc880]" />
          </div>
        </div>
      </div>

      {/* Crosshair corners of the viewport */}
      <div className="absolute top-32 left-8 w-4 h-4 border-t border-l border-primary/40 z-10" />
      <div className="absolute top-32 right-8 w-4 h-4 border-t border-r border-primary/40 z-10" />
      <div className="absolute bottom-8 left-8 w-4 h-4 border-b border-l border-primary/40 z-10" />
      <div className="absolute bottom-8 right-8 w-4 h-4 border-b border-r border-primary/40 z-10" />

      {/* Corner telemetry readouts */}
      <div className="absolute top-32 left-16 z-10 font-label text-[9px] tracking-[0.3em] text-outline/80 uppercase space-y-1 hidden md:block">
        <div><span className="text-primary">◉</span> ORBITAL · LEO</div>
        <div>ALT 427 KM · V 7.66 KM/S</div>
        <div>INC 51.64°</div>
      </div>
      <div className="absolute top-32 right-16 z-10 font-label text-[9px] tracking-[0.3em] text-outline/80 uppercase space-y-1 text-right hidden md:block">
        <div>STATION · CONTROL</div>
        <div>OPS · <span className="text-secondary">NOMINAL</span></div>
        <div>LINK · <span className="text-secondary">LOCKED</span></div>
      </div>

      {/* Centered content */}
      <div className="relative z-20 max-w-4xl text-center px-4 sm:px-8 pt-20" style={{ opacity: Math.max(0, 1 - scrollY / 700), transform: `translate3d(0, ${scrollY * -0.1}px, 0)` }}>
        <div className="inline-flex items-center gap-3 px-4 py-1.5 bg-surface-container-lowest/70 backdrop-blur-sm border border-outline-variant/30 mb-8 md:mb-10 hero-entrance" style={{ animationDelay: "0.1s" }}>
          <StatusDot state="nominal" />
          <span className="font-label text-[9px] sm:text-[10px] tracking-[0.3em] text-on-surface-variant uppercase">Mission Control for AI workforces</span>
        </div>

        <h1 className="font-headline text-4xl sm:text-5xl md:text-7xl lg:text-[104px] font-bold tracking-[-0.04em] text-on-background mb-8 md:mb-10 leading-[0.95] md:leading-[0.9] drop-shadow-2xl hero-entrance" style={{ animationDelay: "0.3s" }}>
          Your team runs on <span className="text-primary italic">Control.</span>
        </h1>

        <p className="font-body text-on-surface/90 text-base sm:text-lg md:text-xl max-w-2xl mx-auto mb-10 md:mb-12 leading-relaxed hero-entrance" style={{ animationDelay: "0.6s" }}>
          Built for founders and operators drowning in tools. Control <span className="text-on-background font-medium">consolidates every signal</span> across your stack — and gives every person a <span className="text-on-background font-medium">Chief of Staff</span> to run missions on their behalf.
        </p>

        <div className="flex flex-col sm:flex-row gap-3 justify-center hero-entrance" style={{ animationDelay: "0.85s" }}>
          <button className="bg-primary text-on-primary px-6 sm:px-10 py-4 sm:py-5 font-label text-[11px] font-bold tracking-[0.25em] uppercase hover:bg-primary-container transition-all inline-flex items-center justify-center gap-3 group relative overflow-hidden">
            <span className="relative z-10">Request early access</span>
            <span className="material-symbols-outlined text-base group-hover:translate-x-0.5 transition-transform relative z-10">arrow_forward</span>
            <span className="absolute inset-0 -translate-x-full group-hover:translate-x-0 bg-primary-container transition-transform duration-500" />
          </button>
          <button className="bg-surface-container-lowest/60 backdrop-blur-sm border border-outline-variant/40 text-on-surface px-6 sm:px-10 py-4 sm:py-5 font-label text-[11px] font-bold tracking-[0.25em] uppercase hover:bg-surface-container transition-colors">
            Book a demo
          </button>
        </div>
      </div>
    </section>
  );
}

function HeroConsole() {
  const tick = useTicker(1400);
  const rows = [
    { t: "exec.cos", msg: "Deployed research sub-agent for Q2 competitor scan.", s: "nominal" },
    { t: "eng.cos", msg: "PR #842 reviewed · 3 comments · awaiting merge.", s: "info" },
    { t: "sales.cos", msg: "Drafted 4 follow-ups from Zoom call (12:04 UTC).", s: "nominal" },
    { t: "ops.cos", msg: "Jira epic CTRL-114 split into 7 subtasks.", s: "nominal" },
    { t: "recruit.cos", msg: "Parsed 23 résumés · shortlist ready.", s: "info" },
    { t: "finance.cos", msg: "3 invoices awaiting your approval.", s: "warning" },
  ];
  const visible = rows.slice(0, 4 + (tick % 3));

  return (
    <CornerFrame className="bg-surface-container-lowest p-6 relative" size={12} color="primary/30">
      <div className="flex items-center justify-between mb-5">
        <div className="flex items-center gap-2">
          <StatusDot state="nominal" />
          <span className="font-label text-[10px] tracking-[0.25em] text-on-surface-variant uppercase">Live · Control Room</span>
        </div>
        <span className="font-label text-[10px] text-outline">CTRL-EXEC-01</span>
      </div>

      <div className="space-y-0.5 font-label text-[11px] mb-5">
        {visible.map((r, i) => (
          <div key={i} className="grid grid-cols-[auto_1fr_auto] gap-3 items-center py-2 border-b border-outline-variant/10 last:border-0">
            <StatusDot state={r.s} pulse={false} />
            <span className="text-on-surface-variant"><span className="text-primary">{r.t}</span> — {r.msg}</span>
            <span className="text-outline text-[9px]">T-0{i + 1}:4{i}</span>
          </div>
        ))}
      </div>

      {/* mini sparkline */}
      <div className="pt-5 border-t border-outline-variant/10">
        <div className="flex justify-between mb-3">
          <TeleLabel>Throughput · 24h</TeleLabel>
          <span className="font-label text-[10px] text-secondary">+38%</span>
        </div>
        <svg viewBox="0 0 300 60" className="w-full h-14">
          <path d="M0,40 L30,35 L60,38 L90,28 L120,32 L150,22 L180,26 L210,15 L240,18 L270,10 L300,14" stroke="#ffc880" strokeWidth="1.5" fill="none" />
          <path d="M0,40 L30,35 L60,38 L90,28 L120,32 L150,22 L180,26 L210,15 L240,18 L270,10 L300,14 L300,60 L0,60 Z" fill="#ffc880" opacity="0.08" />
          {[0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300].map((x, i) => (
            <line key={i} x1={x} y1="0" x2={x} y2="60" stroke="#9f8e7a" strokeOpacity="0.08" />
          ))}
        </svg>
      </div>
    </CornerFrame>
  );
}

// ============================================================
// Social proof / logo strip
// ============================================================

function LogoStrip() {
  const integrations = [
    { id: "slack", name: "Slack" },
    { id: "mail", name: "Gmail" },
    { id: "jira", name: "Jira" },
    { id: "notion", name: "Notion" },
    { id: "linear", name: "Linear" },
    { id: "github", name: "GitHub" },
    { id: "zoom", name: "Zoom" },
    { id: "hubspot", name: "HubSpot" },
    { id: "drive", name: "Drive" },
    { id: "granola", name: "Granola" },
    { id: "cal", name: "Calendar" },
    { id: "loom", name: "Loom" },
  ];
  // Duplicate the list so the translateX(-50%) loop is seamless.
  const loop = [...integrations, ...integrations];

  return (
    <section className="border-y border-outline-variant/10 py-8 bg-surface-container-lowest/50 overflow-hidden">
      <div className="max-w-screen-2xl mx-auto px-8 mb-6">
        <TeleLabel>◉ Connects to the tools your team already runs on</TeleLabel>
      </div>
      <div
        className="relative w-full overflow-hidden"
        style={{
          maskImage: "linear-gradient(to right, transparent, black 6%, black 94%, transparent)",
          WebkitMaskImage: "linear-gradient(to right, transparent, black 6%, black 94%, transparent)",
        }}
      >
        <div className="flex items-center gap-x-12 whitespace-nowrap animate-marquee" style={{ animationDuration: "48s", width: "max-content" }}>
          {loop.map((i, idx) => (
            <div key={idx} className="flex items-center gap-3 shrink-0 opacity-70">
              <span className="w-6 h-6 flex items-center justify-center">
                <SourceGlyph kind={i.id} />
              </span>
              <span className="font-headline text-sm font-semibold tracking-tight text-on-surface-variant">{i.name}</span>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

Object.assign(window, {
  useTicker, useInView, CornerFrame, TeleLabel, SectionTag, StatusDot, GridBackdrop,
  TopNav, Hero, LogoStrip, formatClock, pad, ThemeToggle,
});
