import {
  createSignal,
  onMount,
  onCleanup,
  Show, createEffect,
} from "solid-js";
import * as THREE from "three";
import { STLLoader } from "three/examples/jsm/loaders/STLLoader.js";

export interface TokenViewerProps {
  stlUrl: string | null;
}

export default function MdTokenViewer(props: TokenViewerProps) { 

  const [viewerRef, setViewerRef] = createSignal<HTMLDivElement | null>(null);
  const [isLoaded, setIsLoaded] = createSignal(false);
  const [error, setError] = createSignal<string | null>(null);

  let scene: THREE.Scene | null = null;
  let camera: THREE.PerspectiveCamera | null = null;
  let renderer: THREE.WebGLRenderer | null = null;
  let mesh: THREE.Mesh | null = null;
  let animationId: number | null = null;
  let isDragging = false;
  let previousMousePosition = { x: 0, y: 0 };

  // 加载 STL 用于预览
  const loadSTL = async (url: string) => {
    const viewerEl = viewerRef();
    if (!viewerEl) return;

    // 清理旧的场景
    if (mesh) {
      scene?.remove(mesh);
      mesh.geometry.dispose();
      (mesh.material as THREE.Material).dispose();
      mesh = null;
    }

    try {
      const response = await fetch(url);
      const stlText = await response.text();

      // 解析 STL
      const loader = new STLLoader();
      const geometry = loader.parse(stlText);

      // 计算边界并居中
      geometry.center();

      // 创建材质
      const material = new THREE.MeshStandardMaterial({
        color: 0x808080,
        metalness: 0.3,
        roughness: 0.7,
        side: THREE.DoubleSide,
      });

      mesh = new THREE.Mesh(geometry, material);
      mesh.rotateX(Math.PI);
      scene?.add(mesh);

      // 调整相机
      if (camera && scene) {
        const box = new THREE.Box3().setFromObject(mesh);
        const size = box.getSize(new THREE.Vector3());
        const maxDim = Math.max(size.x, size.y, size.z);

        camera.position.set(maxDim * 2, maxDim * 2, maxDim * 2);
        camera.lookAt(0, 0, 0);
      }

      setIsLoaded(true);
    } catch (e) {
      console.error("加载 STL 预览失败:", e);
      setError(e instanceof Error ? e.message : "加载 STL 失败");
    }
  };

  // 初始化 Three.js 场景
  onMount(() => {
    const viewerEl = viewerRef();
    console.log("Viewer element:", viewerEl);
    if (!viewerEl) return;

    // 创建场景
    scene = new THREE.Scene();
    scene.background = new THREE.Color(0xf3f4f6);

    // 创建相机
    camera = new THREE.PerspectiveCamera(
      45,
      viewerEl.clientWidth / viewerEl.clientHeight,
      0.1,
      1000
    );
    camera.position.set(100, 100, 100);

    // 创建渲染器
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(viewerEl.clientWidth, viewerEl.clientHeight);
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.shadowMap.enabled = true;

    viewerEl.appendChild(renderer.domElement);

    // 添加灯光
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
    scene.add(ambientLight);

    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
    directionalLight.position.set(50, 100, 50);
    directionalLight.castShadow = true;
    scene.add(directionalLight);

    // 添加坐标轴辅助
    const axesHelper = new THREE.AxesHelper(10);
    scene.add(axesHelper);

    // 鼠标控制
    const handleMouseDown = (e: MouseEvent) => {
      isDragging = true;
      previousMousePosition = { x: e.clientX, y: e.clientY };
    };

    const handleMouseMove = (e: MouseEvent) => {
      if (!isDragging || !mesh) return;

      const deltaX = e.clientX - previousMousePosition.x;
      const deltaY = e.clientY - previousMousePosition.y;

      mesh.rotation.y += deltaX * 0.01;
      mesh.rotation.x += deltaY * 0.01;

      previousMousePosition = { x: e.clientX, y: e.clientY };
    };

    const handleMouseUp = () => {
      isDragging = false;
    };

    const handleWheel = (e: WheelEvent) => {
      if (!camera) return;

      const zoomSpeed = 0.5;
      camera.position.multiplyScalar(e.deltaY > 0 ? 1 + zoomSpeed : 1 - zoomSpeed);
    };

    viewerEl.addEventListener("mousedown", handleMouseDown);
    document.addEventListener("mousemove", handleMouseMove);
    document.addEventListener("mouseup", handleMouseUp);
    viewerEl.addEventListener("wheel", handleWheel);

    // 动画循环
    const animate = () => {
      if (scene && camera && renderer && mesh) {
        if (!isDragging) {
          mesh.rotation.y += 0.005; // 自动旋转
        }
        renderer.render(scene, camera);
      }
      animationId = requestAnimationFrame(animate);
    };
    animate();

    // 清理函数
    onCleanup(() => {
      if (animationId) cancelAnimationFrame(animationId);
      viewerEl.removeEventListener("mousedown", handleMouseDown);
      document.removeEventListener("mousemove", handleMouseMove);
      document.removeEventListener("mouseup", handleMouseUp);
      viewerEl.removeEventListener("wheel", handleWheel);

      if (renderer) {
        renderer.dispose();
        viewerEl.removeChild(renderer.domElement);
      }
      if (scene) scene.clear();
    });
  });
  
  createEffect(() => {
    if (props.stlUrl) {
      loadSTL(props.stlUrl);
    }
  });

  return (
    <div
      ref={setViewerRef}
      class="relative border rounded-lg overflow-hidden bg-gray-50 aspect-square"
      style={{ "min-height": "200px" }}
    >
      <div class="absolute top-2 left-2 z-10 bg-black/50 text-white text-xs px-2 py-1 rounded">
        拖动旋转 | 滚动缩放
      </div>
      <Show when={error()}>
        <div class="absolute inset-0 flex items-center justify-center bg-black/50 text-white">
          ⚠️ {error()}
        </div>
      </Show>
      <Show when={!isLoaded() && !error()}>
        <div class="absolute inset-0 flex items-center justify-center text-gray-500">
          <div class="animate-spin inline-block w-6 h-6 border-2 border-current border-t-transparent rounded-full mr-2" />
          加载模型中...
        </div>
      </Show>
    </div>
  );
}
