import { useFrame } from "@react-three/fiber";
import { useLayoutEffect, useMemo, useRef } from "react";
import * as THREE from "three";
import type { HealerVisualProfile } from "../game/healerVisuals";

function RelicMaterial({ color }: { color: string }) {
  return (
    <meshStandardMaterial
      color={color}
      emissive={color}
      emissiveIntensity={0.45}
      metalness={0.35}
      roughness={0.42}
    />
  );
}

function DawnNimbus({ accentColor, secondaryColor }: { accentColor: string; secondaryColor: string }) {
  const rays = useRef<THREE.InstancedMesh>(null);
  const transform = useMemo(() => new THREE.Object3D(), []);

  useLayoutEffect(() => {
    if (!rays.current) return;
    for (let index = 0; index < 8; index += 1) {
      const angle = index * Math.PI / 4;
      transform.position.set(Math.sin(angle) * 0.54, Math.cos(angle) * 0.54, 0);
      transform.rotation.set(0, 0, -angle);
      transform.updateMatrix();
      rays.current.setMatrixAt(index, transform.matrix);
    }
    rays.current.instanceMatrix.needsUpdate = true;
  }, [transform]);

  return (
    <group position={[0, 0.68, -0.04]}>
      <instancedMesh ref={rays} args={[undefined, undefined, 8]}>
        <boxGeometry args={[0.045, 0.16, 0.035]} />
        <RelicMaterial color={accentColor} />
      </instancedMesh>
      <mesh>
        <torusGeometry args={[0.42, 0.04, 6, 20]} />
        <RelicMaterial color={accentColor} />
      </mesh>
      <mesh position={[0, 0.08, 0.015]} rotation={[0, 0, Math.PI / 4]}>
        <octahedronGeometry args={[0.1, 0]} />
        <RelicMaterial color={secondaryColor} />
      </mesh>
    </group>
  );
}

export function HealerClassAccessory({ profile }: { profile: HealerVisualProfile }) {
  const animated = useRef<THREE.Group>(null);

  useFrame((_, delta) => {
    if (!animated.current || profile.accessory !== "clockwork-rings") return;
    animated.current.rotation.z += delta * 0.42;
    animated.current.rotation.y -= delta * 0.18;
  });

  if (profile.accessory === "sun-halo") {
    return <DawnNimbus accentColor={profile.accentColor} secondaryColor={profile.secondaryColor} />;
  }

  if (profile.accessory === "grove-antlers") {
    return (
      <group position={[0, 0.34, 0]}>
        <mesh position={[-0.2, 0.18, 0]} rotation={[0, 0, -0.36]}>
          <coneGeometry args={[0.055, 0.5, 5]} />
          <RelicMaterial color={profile.secondaryColor} />
        </mesh>
        <mesh position={[0.2, 0.18, 0]} rotation={[0, 0, 0.36]}>
          <coneGeometry args={[0.055, 0.5, 5]} />
          <RelicMaterial color={profile.secondaryColor} />
        </mesh>
        <mesh position={[-0.31, 0.28, 0]} rotation={[0, 0, -0.62]}>
          <tetrahedronGeometry args={[0.1, 0]} />
          <RelicMaterial color={profile.accentColor} />
        </mesh>
        <mesh position={[0.31, 0.28, 0]} rotation={[0, 0, 0.62]}>
          <tetrahedronGeometry args={[0.1, 0]} />
          <RelicMaterial color={profile.accentColor} />
        </mesh>
      </group>
    );
  }

  if (profile.accessory === "storm-totem") {
    return (
      <group position={[0, 0.78, 0]}>
        <mesh>
          <cylinderGeometry args={[0.09, 0.12, 0.42, 6]} />
          <RelicMaterial color={profile.secondaryColor} />
        </mesh>
        <mesh position={[-0.22, 0.1, 0]}>
          <octahedronGeometry args={[0.11, 0]} />
          <RelicMaterial color={profile.accentColor} />
        </mesh>
        <mesh position={[0.22, -0.08, 0]} scale={0.75}>
          <octahedronGeometry args={[0.11, 0]} />
          <RelicMaterial color={profile.accentColor} />
        </mesh>
      </group>
    );
  }

  if (profile.accessory === "sun-crest") {
    return (
      <group position={[0, 0.68, 0]}>
        <mesh>
          <torusGeometry args={[0.46, 0.055, 6, 14]} />
          <RelicMaterial color={profile.accentColor} />
        </mesh>
        <mesh rotation={[0, 0, Math.PI / 4]}>
          <octahedronGeometry args={[0.23, 0]} />
          <RelicMaterial color={profile.secondaryColor} />
        </mesh>
      </group>
    );
  }

  return (
    <group ref={animated} position={[0, 0.68, 0]}>
      <mesh>
        <torusGeometry args={[0.46, 0.04, 6, 18]} />
        <RelicMaterial color={profile.accentColor} />
      </mesh>
      <mesh rotation={[Math.PI / 3, 0, 0]}>
        <torusGeometry args={[0.25, 0.035, 6, 14]} />
        <RelicMaterial color={profile.secondaryColor} />
      </mesh>
      <mesh rotation={[0, 0, Math.PI / 4]}>
        <octahedronGeometry args={[0.11, 0]} />
        <RelicMaterial color={profile.accentColor} />
      </mesh>
    </group>
  );
}
