"use client";

import { Environment, Line, PerspectiveCamera, Text } from "@react-three/drei";
import { Canvas, useFrame, useThree } from "@react-three/fiber";
import { Suspense, useEffect, useMemo, useRef, useState } from "react";
import type { Group, Mesh } from "three";

const farmerNodes = [
  [2.25, -0.34, -0.72],
  [2.72, -0.18, -0.12],
  [2.3, -0.08, 0.58],
  [1.86, -0.26, 0.08]
] as const;

function hasWebGL() {
  if (typeof window === "undefined") return false;
  try {
    const canvas = document.createElement("canvas");
    return Boolean(
      window.WebGLRenderingContext &&
        (canvas.getContext("webgl") || canvas.getContext("experimental-webgl"))
    );
  } catch {
    return false;
  }
}

function WorkflowNode({
  label,
  sublabel,
  position,
  color,
  size = 0.42
}: {
  label: string;
  sublabel: string;
  position: [number, number, number];
  color: string;
  size?: number;
}) {
  return (
    <group position={position}>
      <mesh castShadow>
        <cylinderGeometry args={[size, size * 0.86, 0.18, 48]} />
        <meshPhysicalMaterial
          color={color}
          roughness={0.2}
          metalness={0.16}
          transmission={0.18}
          thickness={0.7}
          clearcoat={0.8}
          clearcoatRoughness={0.18}
        />
      </mesh>
      <mesh position={[0, 0.14, 0]}>
        <sphereGeometry args={[size * 0.19, 24, 24]} />
        <meshStandardMaterial color="#f8fbff" emissive={color} emissiveIntensity={1.45} />
      </mesh>
      <Text
        position={[0, 0.39, 0]}
        rotation={[-0.95, 0, 0]}
        fontSize={0.13}
        color="#f7fbff"
        anchorX="center"
        anchorY="middle"
        maxWidth={1.6}
      >
        {label}
      </Text>
      <Text
        position={[0, 0.22, 0.28]}
        rotation={[-0.95, 0, 0]}
        fontSize={0.075}
        color="#c3d3d1"
        anchorX="center"
        anchorY="middle"
        maxWidth={1.45}
      >
        {sublabel}
      </Text>
    </group>
  );
}

function FlowPacket({
  delay,
  from,
  to,
  color
}: {
  delay: number;
  from: [number, number, number];
  to: [number, number, number];
  color: string;
}) {
  const packet = useRef<Mesh>(null);

  useFrame(({ clock }) => {
    if (!packet.current) return;
    const t = ((clock.getElapsedTime() + delay) % 3.8) / 3.8;
    const eased = t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
    packet.current.position.set(
      from[0] + (to[0] - from[0]) * eased,
      from[1] + (to[1] - from[1]) * eased + Math.sin(t * Math.PI) * 0.34,
      from[2] + (to[2] - from[2]) * eased
    );
    packet.current.scale.setScalar(0.78 + Math.sin(t * Math.PI) * 0.28);
  });

  return (
    <mesh ref={packet}>
      <sphereGeometry args={[0.055, 20, 20]} />
      <meshStandardMaterial color={color} emissive={color} emissiveIntensity={1.9} />
    </mesh>
  );
}

function FinancingWorkflow() {
  const group = useRef<Group>(null);
  const sweep = useRef<Mesh>(null);

  useFrame(({ clock, pointer }) => {
    const t = clock.getElapsedTime();
    if (group.current) {
      group.current.rotation.x = -0.62 + pointer.y * 0.035;
      group.current.rotation.z = -0.1 + pointer.x * 0.04;
      group.current.position.y = Math.sin(t * 0.5) * 0.035;
    }
    if (sweep.current) {
      sweep.current.position.x = ((t * 0.7) % 5.2) - 2.6;
      sweep.current.scale.y = 1 + Math.sin(t * 3) * 0.08;
    }
  });

  const fieldStrips = useMemo(
    () =>
      Array.from({ length: 9 }, (_, index) => ({
        x: 1.55 + index * 0.18,
        z: -0.7 + index * 0.17,
        h: 0.03 + (index % 3) * 0.01
      })),
    []
  );

  return (
    <group ref={group} position={[0.1, -0.46, 0]}>
      <mesh position={[0, -0.08, 0]} receiveShadow>
        <boxGeometry args={[5.9, 0.08, 2.45]} />
        <meshPhysicalMaterial
          color="#dfeee8"
          roughness={0.28}
          metalness={0.03}
          transmission={0.16}
          thickness={0.9}
          transparent
          opacity={0.42}
        />
      </mesh>

      {fieldStrips.map((strip, index) => (
        <mesh key={strip.x} position={[strip.x, 0, strip.z]} castShadow>
          <boxGeometry args={[0.11, strip.h, 1.15]} />
          <meshStandardMaterial
            color={index % 2 === 0 ? "#41a846" : "#138f43"}
            roughness={0.72}
            metalness={0.04}
          />
        </mesh>
      ))}

      <mesh ref={sweep} position={[-2.6, 0.08, 0]} rotation={[0, 0, 0]}>
        <boxGeometry args={[0.035, 0.016, 2.55]} />
        <meshStandardMaterial
          color="#34a5ff"
          emissive="#34a5ff"
          emissiveIntensity={1.5}
          transparent
          opacity={0.5}
        />
      </mesh>

      <WorkflowNode
        label="BANKS"
        sublabel="credit pools"
        position={[-2.25, 0.04, -0.12]}
        color="#1677d2"
        size={0.36}
      />
      <WorkflowNode
        label="AGNET"
        sublabel="eligibility + SLA routing"
        position={[0, 0.18, 0]}
        color="#11a34a"
        size={0.54}
      />
      <WorkflowNode
        label="FARMERS"
        sublabel="approved finance"
        position={[2.2, 0.05, -0.06]}
        color="#40b64c"
        size={0.36}
      />

      {[
        [
          [-2.25, 0.16, -0.12],
          [0, 0.28, 0]
        ],
        [
          [0, 0.28, 0],
          [2.2, 0.16, -0.06]
        ]
      ].map(([from, to], index) => (
        <Line
          key={`capital-route-${index}`}
          points={[from, to] as [number, number, number][]}
          color={index === 0 ? "#38a0ff" : "#58c45a"}
          lineWidth={1.4}
          transparent
          opacity={0.9}
        />
      ))}

      <FlowPacket delay={0} from={[-2.25, 0.22, -0.12]} to={[0, 0.34, 0]} color="#35a7ff" />
      <FlowPacket delay={1.2} from={[-2.25, 0.22, -0.12]} to={[0, 0.34, 0]} color="#35a7ff" />
      <FlowPacket delay={1.8} from={[0, 0.34, 0]} to={[2.2, 0.22, -0.06]} color="#73d263" />
      <FlowPacket delay={3.0} from={[0, 0.34, 0]} to={[2.2, 0.22, -0.06]} color="#73d263" />

      {farmerNodes.map((node, index) => (
        <mesh key={`${node[0]}-${node[2]}`} position={node}>
          <cylinderGeometry args={[0.045, 0.06, 0.08, 20]} />
          <meshStandardMaterial
            color={index === 1 ? "#1768c4" : "#48af45"}
            emissive={index === 1 ? "#0a4d91" : "#1b6428"}
            emissiveIntensity={0.6}
          />
        </mesh>
      ))}
    </group>
  );
}

function CameraRig() {
  const { camera } = useThree();

  useFrame(({ pointer }) => {
    camera.position.x = pointer.x * 0.14;
    camera.position.y = 2.62 + pointer.y * 0.06;
    camera.lookAt(0.05, -0.12, 0);
  });

  return null;
}

function SceneFallback() {
  return (
    <div className="scene-fallback" aria-label="Bank to AGNET to farmer financing workflow preview">
      <span />
      <span />
      <span />
      <span />
    </div>
  );
}

function SceneLoader() {
  return <div className="scene-loader">Routing finance</div>;
}

export default function AgriNetworkScene() {
  const [supported, setSupported] = useState(false);
  const [ready, setReady] = useState(false);

  useEffect(() => {
    setSupported(hasWebGL());
    setReady(true);
  }, []);

  if (!ready) return <SceneLoader />;
  if (!supported) return <SceneFallback />;

  return (
    <Canvas
      dpr={[1, 1.6]}
      shadows
      gl={{ antialias: true, alpha: true, powerPreference: "high-performance" }}
      className="hero-canvas"
    >
      <Suspense fallback={null}>
        <PerspectiveCamera makeDefault position={[0, 2.75, 5.15]} fov={39} />
        <CameraRig />
        <ambientLight intensity={2.15} />
        <directionalLight position={[3, 5, 4]} intensity={2.35} castShadow />
        <pointLight position={[-2.2, 1.4, 2.2]} color="#1d8dff" intensity={1.1} />
        <pointLight position={[2.1, 1.2, 1.8]} color="#54c95c" intensity={1.2} />
        <FinancingWorkflow />
        <Environment preset="city" />
      </Suspense>
    </Canvas>
  );
}
