import {
  Environment,
  Float,
  MeshTransmissionMaterial,
} from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import { EffectComposer } from "@react-three/postprocessing";
import { Suspense, useEffect, useState } from "react";
import { DEFAULT_CONFIG, Fluid } from "../react-fluid-distortion";

function BackdropGeometry() {
  return (
    <>
      <ambientLight intensity={1.4} />
      <directionalLight color="#ddf6ff" intensity={3.2} position={[3, 4, 6]} />
      <directionalLight
        color="#6ebfff"
        intensity={1.5}
        position={[-6, -3, -2]}
      />
      <Environment preset="city" />

      <Float floatIntensity={1.1} rotationIntensity={0.9} speed={1.45}>
        <mesh position={[-4.6, 1.9, -4.2]} rotation={[0.95, 0.35, 0.55]}>
          <torusGeometry args={[1.12, 0.16, 48, 160]} />
          <MeshTransmissionMaterial
            anisotropy={0.4}
            chromaticAberration={0.09}
            distortion={0.2}
            roughness={0.03}
            thickness={1.3}
            transmission={1}
          />
        </mesh>
      </Float>

      <Float floatIntensity={1.2} rotationIntensity={1.1} speed={1.55}>
        <mesh position={[4.7, -1.7, -3.2]}>
          <torusKnotGeometry args={[1.05, 0.24, 240, 32]} />
          <MeshTransmissionMaterial
            anisotropy={0.42}
            chromaticAberration={0.1}
            distortion={0.18}
            roughness={0.03}
            thickness={1.25}
            transmission={1}
          />
        </mesh>
      </Float>

      <Float floatIntensity={1.25} rotationIntensity={1} speed={1.7}>
        <mesh position={[4.9, 2.3, -4.5]} rotation={[0.35, 0.6, 1.05]}>
          <dodecahedronGeometry args={[0.92, 0]} />
          <MeshTransmissionMaterial
            anisotropy={0.35}
            chromaticAberration={0.08}
            distortion={0.14}
            roughness={0.03}
            thickness={1.1}
            transmission={1}
          />
        </mesh>
      </Float>

      <Float floatIntensity={1} rotationIntensity={0.85} speed={1.25}>
        <mesh position={[-1.4, -2.3, -5.5]} rotation={[0.45, 0.75, 0.25]}>
          <octahedronGeometry args={[1.18, 0]} />
          <MeshTransmissionMaterial
            anisotropy={0.32}
            chromaticAberration={0.07}
            distortion={0.12}
            roughness={0.035}
            thickness={1.15}
            transmission={1}
          />
        </mesh>
      </Float>

      <Float floatIntensity={0.85} rotationIntensity={0.65} speed={1.1}>
        <mesh position={[0.4, 0.35, -6.1]}>
          <sphereGeometry args={[1.38, 64, 64]} />
          <MeshTransmissionMaterial
            anisotropy={0.28}
            chromaticAberration={0.06}
            distortion={0.08}
            roughness={0.02}
            thickness={1.4}
            transmission={1}
          />
        </mesh>
      </Float>
    </>
  );
}

type FluidBackdropProps = {
  subdued?: boolean;
};

function BackdropReadySignal({ onReady }: { onReady: () => void }) {
  useEffect(() => {
    let raf = window.requestAnimationFrame(() => {
      raf = window.requestAnimationFrame(() => {
        onReady();
      });
    });

    return () => {
      window.cancelAnimationFrame(raf);
    };
  }, [onReady]);

  return null;
}

export function FluidBackdrop({ subdued = false }: FluidBackdropProps) {
  const backgroundColor = subdued ? "#060912" : DEFAULT_CONFIG.backgroundColor;
  const [isReady, setIsReady] = useState(false);

  return (
    <div aria-hidden="true" className="fluid-backdrop">
      <div className={`fluid-backdrop__scene ${isReady ? "is-ready" : ""}`}>
        <Canvas
          camera={{ fov: 42, position: [0, 0, 8] }}
          dpr={[1, 2]}
          gl={{ antialias: false }}
        >
          <color attach="background" args={[backgroundColor]} />

          <Suspense fallback={null}>
            <BackdropReadySignal onReady={() => setIsReady(true)} />
            <BackdropGeometry />

            <EffectComposer multisampling={0}>
              <Fluid
                {...DEFAULT_CONFIG}
                backgroundColor={backgroundColor}
                distortion={subdued ? 0.32 : 0.46}
                fluidColor={subdued ? "#6fcff8" : "#96d8ff"}
                intensity={subdued ? 1.35 : 1.9}
                radius={0.24}
                rainbow={false}
              />
            </EffectComposer>
          </Suspense>
        </Canvas>
      </div>
      <div className={`fluid-backdrop__veil ${subdued ? "is-subdued" : ""}`} />
    </div>
  );
}
