/* global React, THREE */
const { useState: useStateH, useEffect: useEffectH, useRef: useRefH, useMemo: useMemoH } = React;

/* ============================================
   3D GLASS CUBE — Three.js (mobile-lite path + lazy mount)
   ============================================ */
function GlassCube() {
  const containerRef = useRefH(null);
  const [mounted, setMounted] = useStateH(false);

  // IntersectionObserver: only mount WebGL once container enters viewport
  useEffectH(() => {
    const el = containerRef.current;
    if (!el) return;
    if (typeof IntersectionObserver === 'undefined') { setMounted(true); return; }
    const io = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) { setMounted(true); io.disconnect(); }
    }, { rootMargin: '100px' });
    io.observe(el);
    return () => io.disconnect();
  }, []);

  useEffectH(() => {
    if (!mounted) return;
    if (!window.THREE || !containerRef.current) return;

    const isMobile = window.matchMedia('(max-width: 767px)').matches
      || window.matchMedia('(hover: none)').matches;
    const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

    const container = containerRef.current;
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);
    camera.position.set(0, 0, 6);

    const renderer = new THREE.WebGLRenderer({ antialias: !isMobile, alpha: true, powerPreference: isMobile ? 'low-power' : 'high-performance' });
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, isMobile ? 1.5 : 2));
    const setSize = () => {
      const w = container.clientWidth;
      const h = container.clientHeight;
      renderer.setSize(w, h, false);
      camera.aspect = w / h;
      camera.updateProjectionMatrix();
    };
    setSize();
    container.appendChild(renderer.domElement);
    renderer.domElement.style.width = '100%';
    renderer.domElement.style.height = '100%';

    // Lighting — cool studio. Mobile uses ambient + key only.
    const amb = new THREE.AmbientLight(0xa8c5e8, isMobile ? 0.55 : 0.4);
    scene.add(amb);
    const key = new THREE.DirectionalLight(0xc4dbf0, isMobile ? 1.4 : 1.2);
    key.position.set(5, 5, 5);
    scene.add(key);
    let rim, fill;
    if (!isMobile) {
      rim = new THREE.DirectionalLight(0x6b8ab5, 0.8);
      rim.position.set(-5, 3, -3);
      scene.add(rim);
      fill = new THREE.PointLight(0xa8c5e8, 1.5, 10);
      fill.position.set(-2, -2, 4);
      scene.add(fill);
    }

    // Procedural environment via cubeRenderTarget — desktop only
    let cubeRenderTarget;
    if (!isMobile) {
      cubeRenderTarget = new THREE.WebGLCubeRenderTarget(256);
      const envScene = new THREE.Scene();
      const skyGeo = new THREE.SphereGeometry(50, 32, 32);
      const skyMat = new THREE.ShaderMaterial({
        side: THREE.BackSide,
        uniforms: {
          topColor: { value: new THREE.Color(0x1a2030) },
          midColor: { value: new THREE.Color(0x0c1430) },
          botColor: { value: new THREE.Color(0x04060a) },
          accent: { value: new THREE.Color(0xa8c5e8) },
        },
        vertexShader: `varying vec3 vWorld; void main() { vWorld = normalize(position); gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); }`,
        fragmentShader: `
          uniform vec3 topColor, midColor, botColor, accent;
          varying vec3 vWorld;
          void main() {
            float h = vWorld.y * 0.5 + 0.5;
            vec3 c = mix(botColor, midColor, smoothstep(0.0, 0.6, h));
            c = mix(c, topColor, smoothstep(0.5, 1.0, h));
            float g = pow(max(0.0, dot(normalize(vWorld), normalize(vec3(0.5, 0.7, 0.4)))), 8.0);
            c += accent * g * 0.4;
            gl_FragColor = vec4(c, 1.0);
          }
        `,
      });
      envScene.add(new THREE.Mesh(skyGeo, skyMat));
      const cubeCam = new THREE.CubeCamera(0.1, 100, cubeRenderTarget);
      envScene.add(cubeCam);
      cubeCam.update(renderer, envScene);
      scene.environment = cubeRenderTarget.texture;
    }

    // Glass obelisk
    const geometry = new THREE.BoxGeometry(1.4, 2.6, 1.4, 1, 1, 1);
    const material = new THREE.MeshPhysicalMaterial({
      color: 0xeaf2fc,
      transmission: isMobile ? 0.85 : 1.0,
      thickness: 1.5,
      roughness: isMobile ? 0.15 : 0.08,
      metalness: 0.0,
      ior: 1.45,
      envMapIntensity: isMobile ? 0.8 : 1.4,
      clearcoat: 1.0,
      clearcoatRoughness: 0.05,
      attenuationColor: new THREE.Color(0xa8c5e8),
      attenuationDistance: 4.0,
      transparent: true,
    });
    const obelisk = new THREE.Mesh(geometry, material);
    scene.add(obelisk);

    // Inner core — lower poly on mobile
    const coreGeo = new THREE.IcosahedronGeometry(0.35, isMobile ? 0 : 1);
    const coreMat = new THREE.MeshBasicMaterial({
      color: 0xa8c5e8,
      transparent: true,
      opacity: 0.45,
    });
    const core = new THREE.Mesh(coreGeo, coreMat);
    scene.add(core);

    // Floating glass shard — desktop only
    let shardGeo, shard;
    if (!isMobile) {
      shardGeo = new THREE.OctahedronGeometry(0.28, 0);
      shard = new THREE.Mesh(shardGeo, material.clone());
      shard.position.set(1.4, 0.9, 0.4);
      scene.add(shard);
    }

    // Animate (skip animation under reduced motion — single render)
    let t = 0;
    let raf;
    const tick = () => {
      t += 0.005;
      obelisk.rotation.y += 0.003;
      obelisk.rotation.x = Math.sin(t * 0.4) * 0.05;
      obelisk.position.y = Math.sin(t * 0.6) * 0.08;
      core.rotation.x += 0.008;
      core.rotation.y -= 0.006;
      core.position.y = Math.sin(t * 0.6) * 0.08;
      if (shard) {
        shard.rotation.x += 0.006;
        shard.rotation.z += 0.004;
        shard.position.y = 0.9 + Math.sin(t * 0.8 + 1) * 0.12;
      }
      renderer.render(scene, camera);
      raf = requestAnimationFrame(tick);
    };
    if (reduceMotion) {
      renderer.render(scene, camera);
    } else {
      tick();
    }

    const onResize = () => setSize();
    window.addEventListener('resize', onResize);

    return () => {
      if (raf) cancelAnimationFrame(raf);
      window.removeEventListener('resize', onResize);
      renderer.dispose();
      geometry.dispose();
      material.dispose();
      coreGeo.dispose();
      coreMat.dispose();
      if (shardGeo) shardGeo.dispose();
      if (cubeRenderTarget) cubeRenderTarget.dispose();
      if (renderer.domElement.parentNode) renderer.domElement.parentNode.removeChild(renderer.domElement);
    };
  }, [mounted]);

  return (
    <div ref={containerRef} style={{
      position: 'absolute',
      inset: 0,
      pointerEvents: 'none',
    }}>
      {!mounted && (
        <div aria-hidden="true" style={{
          position: 'absolute',
          inset: 0,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}>
          <img
            src="assets/brand/codage-favicon.png"
            alt=""
            width="120"
            height="120"
            style={{
              width: 'clamp(80px, 14vw, 140px)',
              height: 'auto',
              opacity: 0.18,
              filter: 'drop-shadow(0 0 24px rgba(168,197,232,0.35))',
            }}
          />
        </div>
      )}
    </div>
  );
}

/* ============================================
   STREAMING TERMINAL
   ============================================ */
function StreamingTerminal() {
  const lines = useMemoH(() => ([
    { type: 'cmd', text: '> Process application AZ-44729', delay: 0 },
    { type: 'blank' },
    { type: 'progress', label: 'Reading passport.pdf', endText: '100%', duration: 1400 },
    { type: 'check', label: 'Liveness check', value: 'verified' },
    { type: 'check', label: 'Sanctions screen', value: 'OFAC, EU, local — clean' },
    { type: 'check', label: 'Income validation', value: '3-month average confirmed' },
    { type: 'value', label: 'Risk score', value: '0.12 (low)' },
    { type: 'blank' },
    { type: 'arrow', text: '→ Recommendation: fast-track approve' },
    { type: 'arrow', text: '→ Time elapsed: 47s' },
    { type: 'arrow', text: '→ Confidence: 94%' },
  ]), []);

  const [step, setStep] = useState(0);
  const [progress, setProgress] = useStateH(0);
  const [typed, setTyped] = useStateH('');
  const [faded, setFaded] = useStateH(false);
  const cycleRef = useRefH(0);

  useEffectH(() => {
    let timers = [];
    let mounted = true;

    const runCycle = async () => {
      while (mounted) {
        setFaded(false);
        setStep(0);
        setTyped('');
        setProgress(0);

        // Type first command char-by-char
        const cmd = lines[0].text;
        for (let i = 0; i <= cmd.length; i++) {
          if (!mounted) return;
          setTyped(cmd.slice(0, i));
          await new Promise(r => { const t = setTimeout(r, 18); timers.push(t); });
        }
        await new Promise(r => { const t = setTimeout(r, 300); timers.push(t); });

        // Walk subsequent lines
        for (let i = 1; i < lines.length; i++) {
          if (!mounted) return;
          setStep(i);
          const ln = lines[i];
          if (ln.type === 'progress') {
            const dur = ln.duration || 1200;
            const startTs = performance.now();
            await new Promise(resolve => {
              const tick = () => {
                if (!mounted) return resolve();
                const p = Math.min(1, (performance.now() - startTs) / dur);
                setProgress(p);
                if (p < 1) requestAnimationFrame(tick);
                else resolve();
              };
              tick();
            });
            await new Promise(r => { const t = setTimeout(r, 250); timers.push(t); });
          } else if (ln.type === 'blank') {
            await new Promise(r => { const t = setTimeout(r, 120); timers.push(t); });
          } else {
            await new Promise(r => { const t = setTimeout(r, 320); timers.push(t); });
          }
        }

        setStep(lines.length);
        await new Promise(r => { const t = setTimeout(r, 4000); timers.push(t); });
        setFaded(true);
        await new Promise(r => { const t = setTimeout(r, 1200); timers.push(t); });
        cycleRef.current++;
      }
    };
    runCycle();

    return () => {
      mounted = false;
      timers.forEach(clearTimeout);
    };
  }, [lines]);

  const renderLine = (ln, i) => {
    if (i > step && i !== 0) return null;
    if (ln.type === 'cmd') {
      return (
        <div key={i} style={{ color: 'var(--accent-ice-bright)', fontWeight: 500 }}>
          {i === 0 ? typed : ln.text}
          {i === 0 && typed.length < ln.text.length && <span className="term-caret">▍</span>}
        </div>
      );
    }
    if (ln.type === 'blank') return <div key={i} style={{ height: 8 }} />;
    if (ln.type === 'progress') {
      const isCurrent = step === i;
      const p = isCurrent ? progress : (i < step ? 1 : 0);
      const bars = 20;
      const filled = Math.round(p * bars);
      const bar = '█'.repeat(filled) + '░'.repeat(bars - filled);
      return (
        <div key={i} style={{ display: 'grid', gridTemplateColumns: '1fr auto auto', gap: 16, color: 'var(--text-secondary)' }}>
          <span style={{ paddingLeft: 12 }}>{ln.label}</span>
          <span style={{ color: 'var(--accent-ice)' }}>{bar}</span>
          <span style={{ color: 'var(--text-secondary)', minWidth: 38, textAlign: 'right' }}>{Math.round(p * 100)}%</span>
        </div>
      );
    }
    if (ln.type === 'check') {
      return (
        <div key={i} className="term-check-row" style={{ display: 'grid', gridTemplateColumns: '1fr auto', gap: 16, color: 'var(--text-secondary)' }}>
          <span style={{ paddingLeft: 12 }}>{ln.label}</span>
          <span style={{ color: 'var(--accent-ice-bright)' }}>
            <span className="term-check">✓</span> {ln.value}
          </span>
        </div>
      );
    }
    if (ln.type === 'value') {
      return (
        <div key={i} style={{ display: 'grid', gridTemplateColumns: '1fr auto', gap: 16, color: 'var(--text-secondary)' }}>
          <span style={{ paddingLeft: 12 }}>{ln.label}</span>
          <span style={{ color: 'var(--accent-ice-bright)' }}>{ln.value}</span>
        </div>
      );
    }
    if (ln.type === 'arrow') {
      return <div key={i} style={{ color: 'var(--text-primary)', paddingLeft: 12 }}>{ln.text}</div>;
    }
    return null;
  };

  return (
    <div className="glass glass-strong hero-terminal" style={{
      width: '100%',
      maxWidth: 540,
      height: 'clamp(320px, 70vw, 400px)',
      borderRadius: 18,
      padding: 0,
      overflow: 'hidden',
      transform: 'translateY(-8px)',
      position: 'relative',
    }}>
      {/* caustic sweep */}
      <div style={{
        position: 'absolute',
        inset: -50,
        background: 'radial-gradient(circle at 30% 20%, rgba(168, 197, 232, 0.18), transparent 50%), radial-gradient(circle at 80% 90%, rgba(196, 219, 240, 0.14), transparent 50%)',
        animation: 'causticDrift 12s ease-in-out infinite',
        pointerEvents: 'none',
      }} />
      {/* header */}
      <div style={{
        display: 'flex',
        alignItems: 'center',
        gap: 12,
        padding: '14px 18px',
        borderBottom: '1px solid var(--border-glass)',
        position: 'relative',
        zIndex: 1,
      }}>
        <div style={{ display: 'flex', gap: 6 }}>
          <span style={{ width: 10, height: 10, borderRadius: '50%', background: 'rgba(255,255,255,0.18)' }} />
          <span style={{ width: 10, height: 10, borderRadius: '50%', background: 'rgba(255,255,255,0.18)' }} />
          <span style={{ width: 10, height: 10, borderRadius: '50%', background: 'rgba(255,255,255,0.18)' }} />
        </div>
        <span style={{ flex: 1, fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text-tertiary)' }}>
          müştəri.agent · <span style={{ color: 'var(--accent-ice)' }}>running</span> · v2.4
        </span>
        <span className="status-dot" />
      </div>

      {/* body */}
      <div style={{
        padding: '22px 22px 18px',
        fontFamily: 'var(--font-mono)',
        fontSize: 12.5,
        lineHeight: 1.85,
        color: 'var(--text-primary)',
        opacity: faded ? 0.3 : 1,
        transition: 'opacity 800ms ease',
        position: 'relative',
        zIndex: 1,
      }}>
        {lines.map(renderLine)}
      </div>
    </div>
  );
}

/* ============================================
   HERO
   ============================================ */
function Hero() {
  return (
    <section className="hero-section" style={{
      position: 'relative',
      paddingTop: 'clamp(140px, 22vh, 200px)',
      paddingBottom: 'clamp(80px, 14vh, 140px)',
      minHeight: '100vh',
      display: 'flex',
      alignItems: 'center',
    }}>
      <div className="container" style={{ width: '100%' }}>
        <div style={{
          display: 'grid',
          gridTemplateColumns: '1.05fr 1fr',
          gap: 60,
          alignItems: 'center',
        }} className="hero-grid">

          {/* LEFT */}
          <div className="reveal-stagger in">
            <div className="eyebrow" style={{ marginBottom: 28 }}>
              CODAGE — APPLIED AI LAB · BAKU / PARIS
            </div>
            <h1 className="serif hero-h1" style={{
              fontSize: 'clamp(48px, 7.5vw, 104px)',
              lineHeight: 1.02,
              letterSpacing: '-0.025em',
              marginBottom: 32,
              paddingBottom: '0.12em',
              color: 'var(--text-primary)',
            }}>
              We build AI agents that{' '}
              <em className="hero-em-glow" style={{
                fontStyle: 'italic',
                color: 'var(--accent-ice)',
              }}>actually ship</em>.
            </h1>
            <p style={{
              fontSize: 18,
              lineHeight: 1.55,
              color: 'var(--text-secondary)',
              maxWidth: 480,
              marginBottom: 40,
            }}>
              Specialists in Natural Language Processing, Computer Vision, and 3D visualization — engineered for the languages, regulations, and realities of the Caspian region and beyond.
            </p>
            <div className="hero-cta-row" style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
              <a href="#agents" className="btn btn-primary">
                Explore our agents
                <svg className="arrow-icon" width="14" height="14" viewBox="0 0 14 14" fill="none">
                  <path d="M2 7h10m0 0L7 2m5 5L7 12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
                </svg>
              </a>
              <a href="https://calendar.app.google/an2mX8SWcKPFcvNK6" target="_blank" rel="noopener noreferrer" className="btn btn-secondary">
                Book a 30-minute AI Workflow Audit
              </a>
            </div>
          </div>

          {/* RIGHT */}
          <div style={{ position: 'relative', minHeight: 480 }}>
            <GlassCube />
            <div style={{
              position: 'relative',
              zIndex: 2,
              display: 'flex',
              justifyContent: 'flex-end',
            }}>
              <StreamingTerminal />
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Hero, GlassCube, StreamingTerminal });
