"use client";

import { useEffect, useRef } from "react";

type Tr = (zh: string, en: string) => string;

export function LiveStudioScene3D({ tr }: { tr: Tr }) {
  const mountRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const el = mountRef.current;
    if (!el) return;

    let disposed = false;
    let animationId = 0;
    let teardown: (() => void) | undefined;

    void import("three").then((THREE) => {
      if (disposed || !mountRef.current) return;

      const mount = mountRef.current;
      const width = Math.max(mount.clientWidth, 280);
      const height = Math.max(mount.clientHeight, 200);

      const scene = new THREE.Scene();

      const camera = new THREE.PerspectiveCamera(48, width / height, 0.1, 80);
      camera.position.set(0, 1.1, 7.2);

      const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
      renderer.setPixelRatio(Math.min(typeof window !== "undefined" ? window.devicePixelRatio : 1, 2));
      renderer.setSize(width, height);
      renderer.setClearColor(0x000000, 0);
      mount.appendChild(renderer.domElement);

      const hemi = new THREE.HemisphereLight(0xffc4ec, 0x4466ff, 0.85);
      scene.add(hemi);
      const dir = new THREE.DirectionalLight(0xffffff, 0.9);
      dir.position.set(4, 8, 6);
      scene.add(dir);
      const back = new THREE.PointLight(0x7cf5ff, 0.6, 20);
      back.position.set(-3, 2, -2);
      scene.add(back);

      const group = new THREE.Group();

      const studio = new THREE.Mesh(
        new THREE.BoxGeometry(3.2, 0.35, 2.2),
        new THREE.MeshStandardMaterial({
          color: 0x2a2540,
          metalness: 0.15,
          roughness: 0.55,
        }),
      );
      studio.position.y = -0.85;
      group.add(studio);

      const ring = new THREE.Mesh(
        new THREE.TorusGeometry(0.72, 0.09, 12, 48),
        new THREE.MeshStandardMaterial({
          color: 0xff3355,
          emissive: 0x440011,
          metalness: 0.35,
          roughness: 0.25,
        }),
      );
      ring.rotation.x = Math.PI / 2;
      ring.position.set(-0.85, 0.15, 0.2);
      group.add(ring);

      const play = new THREE.Mesh(
        new THREE.ConeGeometry(0.35, 0.5, 3),
        new THREE.MeshStandardMaterial({
          color: 0xffffff,
          emissive: 0x222222,
          metalness: 0.2,
          roughness: 0.3,
        }),
      );
      play.rotation.z = -Math.PI / 2;
      play.rotation.y = Math.PI;
      play.position.set(-0.55, 0.18, 0.2);
      group.add(play);

      const tk = new THREE.Mesh(
        new THREE.CylinderGeometry(0.22, 0.28, 0.95, 20),
        new THREE.MeshStandardMaterial({
          color: 0x25f4ee,
          emissive: 0x053038,
          metalness: 0.25,
          roughness: 0.35,
        }),
      );
      tk.position.set(1.05, 0.35, -0.15);
      tk.rotation.z = 0.12;
      group.add(tk);

      const tkCap = new THREE.Mesh(
        new THREE.SphereGeometry(0.26, 16, 16),
        new THREE.MeshStandardMaterial({
          color: 0xfe2c55,
          emissive: 0x220510,
          metalness: 0.2,
          roughness: 0.4,
        }),
      );
      tkCap.position.set(1.05, 0.92, -0.15);
      group.add(tkCap);

      const starGeo = new THREE.BufferGeometry();
      const starCount = 120;
      const positions = new Float32Array(starCount * 3);
      for (let i = 0; i < starCount; i++) {
        positions[i * 3] = (Math.random() - 0.5) * 14;
        positions[i * 3 + 1] = (Math.random() - 0.3) * 8;
        positions[i * 3 + 2] = (Math.random() - 0.5) * 8 - 2;
      }
      starGeo.setAttribute("position", new THREE.BufferAttribute(positions, 3));
      const stars = new THREE.Points(
        starGeo,
        new THREE.PointsMaterial({ color: 0xffffff, size: 0.06, transparent: true, opacity: 0.7 }),
      );
      scene.add(stars);

      scene.add(group);

      const t0 = performance.now();
      const tick = () => {
        if (disposed) return;
        animationId = requestAnimationFrame(tick);
        const t = (performance.now() - t0) / 1000;
        group.rotation.y = Math.sin(t * 0.35) * 0.25 + t * 0.12;
        group.position.y = Math.sin(t * 0.9) * 0.06;
        ring.rotation.z = t * 0.4;
        stars.rotation.y = t * 0.02;
        renderer.render(scene, camera);
      };
      tick();

      const ro = new ResizeObserver(() => {
        if (!mountRef.current || disposed) return;
        const w = Math.max(mountRef.current.clientWidth, 280);
        const h = Math.max(mountRef.current.clientHeight, 200);
        camera.aspect = w / h;
        camera.updateProjectionMatrix();
        renderer.setSize(w, h);
      });
      ro.observe(mount);

      teardown = () => {
        cancelAnimationFrame(animationId);
        ro.disconnect();
        renderer.dispose();
        starGeo.dispose();
        if (renderer.domElement.parentNode === mount) {
          mount.removeChild(renderer.domElement);
        }
      };
    });

    return () => {
      disposed = true;
      cancelAnimationFrame(animationId);
      teardown?.();
    };
  }, []);

  return (
    <div className="flex h-full min-h-[14rem] flex-col">
      <p className="mb-2 px-1 text-[10px] font-medium uppercase tracking-wider text-fuchsia-200/80">
        {tr("直播工作室 · 3D", "Live studio · 3D")}
      </p>
      <div ref={mountRef} className="relative min-h-[12rem] flex-1 overflow-hidden rounded-xl bg-gradient-to-b from-fuchsia-950/40 to-cyan-950/20 ring-1 ring-white/10" />
    </div>
  );
}
