"use client";

import React, { useMemo, useRef } from "react";
import { useFrame } from "@react-three/fiber";
import * as THREE from "three";
import { COLORS } from "./constants";
import { seeded, smoothstep } from "./math";

type Props = {
  progress: React.RefObject<number>;
  reduced?: boolean;
};

const CORE_Y = 3.4;

type CalcBeamProps = {
  offset: THREE.Vector3;
  index: number;
  progress: React.RefObject<number>;
  color: string;
};

function CalculationBeam({ offset, index, progress, color }: CalcBeamProps) {
  const lineRef = useRef<THREE.LineSegments>(null);
  const lineMatRef = useRef<THREE.LineBasicMaterial>(null);
  const packetRefs = useRef<(THREE.Mesh | null)[]>([]);

  const packetCount = 3;
  const offsets = useMemo(() => Array.from({ length: packetCount }, (_, k) => k / packetCount), []);

  useFrame((state) => {
    const p = progress.current ?? 0;
    const t = state.clock.elapsedTime;

    // Beams are active during AI Scan and Route Generation phases (progress 0.22 -> 0.76)
    const activeFactor = smoothstep(0.20, 0.40, p) * (1 - smoothstep(0.72, 0.85, p));
    const isVisible = activeFactor > 0.01;

    if (lineRef.current) lineRef.current.visible = isVisible;
    if (lineMatRef.current && isVisible) {
      lineMatRef.current.opacity = activeFactor * (0.15 + Math.sin(t * 12 + index) * 0.08);
    }

    packetRefs.current.forEach((mesh, k) => {
      if (!mesh) return;
      mesh.visible = isVisible;
      if (!isVisible) return;

      const speed = 0.8 + seeded(index * 5 + k) * 0.4;
      const u = (offsets[k] + t * (speed / 3)) % 1;

      // Linearly interpolate from center [0,0,0] to hub offset
      mesh.position.copy(offset).multiplyScalar(u);

      const mat = mesh.material as THREE.MeshBasicMaterial;
      mat.opacity = activeFactor * Math.sin(u * Math.PI) * 0.8;

      const s = 0.04 + Math.sin(t * 8 + k) * 0.015;
      mesh.scale.setScalar(s / 0.06);
    });
  });

  // Pre-generated geometry for the static connecting line
  const lineGeo = useMemo(() => {
    const geo = new THREE.BufferGeometry();
    const pts = new Float32Array([0, 0, 0, offset.x, offset.y, offset.z]);
    geo.setAttribute("position", new THREE.BufferAttribute(pts, 3));
    return geo;
  }, [offset]);

  return (
    <group>
      {/* Connector line segment */}
      <lineSegments ref={lineRef} geometry={lineGeo}>
        <lineBasicMaterial
          ref={lineMatRef}
          color={color}
          transparent
          opacity={0}
          depthWrite={false}
          blending={THREE.AdditiveBlending}
        />
      </lineSegments>

      {/* Streams of flowing energy data packets */}
      {Array.from({ length: packetCount }).map((_, k) => (
        <mesh
          key={k}
          ref={(el) => {
            packetRefs.current[k] = el;
          }}
          visible={false}
        >
          <sphereGeometry args={[0.06, 8, 8]} />
          <meshBasicMaterial
            color={color}
            transparent
            opacity={0}
            depthWrite={false}
            blending={THREE.AdditiveBlending}
          />
        </mesh>
      ))}
    </group>
  );
}

const CalculationBeamMemo = React.memo(CalculationBeam);

/**
 * The Doormile AI core: a clean floating holographic orb with energy rings,
 * a particle shell and neural links. It powers up during the AI-scan phase,
 * fires an expanding radar scan, then a route-optimization burst.
 */
function AICore({ progress }: Props) {
  const root = useRef<THREE.Group>(null);

  const hubOffsets = useMemo(() => {
    return Array.from({ length: 5 }, (_, c) => {
      const baseAngle = (c / 5) * Math.PI * 2 + 0.3;
      const radius = 7 + seeded(c * 7 + 1) * 3;
      const cx = Math.cos(baseAngle) * radius;
      const cz = Math.sin(baseAngle) * radius;
      return new THREE.Vector3(cx, 0.1 - CORE_Y, cz);
    });
  }, []);

  useFrame((state) => {
    const t = state.clock.elapsedTime;

    if (root.current) {
      root.current.position.y = CORE_Y + Math.sin(t * 0.8) * 0.12;
    }
  });

  return (
    <group ref={root} position={[0, CORE_Y, 0]}>
      {/* Sleek, subtle dispatch beacon directly above warehouse tower */}
      <mesh>
        <sphereGeometry args={[0.06, 12, 12]} />
        <meshBasicMaterial color={COLORS.green} blending={THREE.AdditiveBlending} />
      </mesh>

      {/* Route Calculation/Analysis Beams */}
      {hubOffsets.map((offset, i) => (
        <CalculationBeamMemo
          key={`calc-beam-${i}`}
          offset={offset}
          index={i}
          progress={progress}
          color={i % 2 === 0 ? COLORS.cyan : COLORS.green}
        />
      ))}
    </group>
  );
}

export default React.memo(AICore);
