import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';

// ============ 控制模块配置 ============
interface ControlOptions {
  scene: THREE.Scene;
  camera: THREE.Camera;
  renderer: THREE.WebGLRenderer;
}

interface ControlState {
  autoRotate: boolean;
  showHelp: boolean;
  showInfo: boolean;
}

const createControlModule = (opts: ControlOptions) => {
  const { scene, camera, renderer } = opts;

  // 轨道控制器
  const controls = new OrbitControls(camera as THREE.PerspectiveCamera, renderer.domElement);
  controls.enableDamping = true; // 启用阻尼效果
  controls.dampingFactor = 0.05;
  controls.rotateSpeed = 0.5;
  controls.zoomSpeed = 1.0;
  controls.panSpeed = 0.8;

  // 限制范围
  controls.minDistance = 5;
  controls.maxDistance = 30;
  controls.maxPolarAngle = Math.PI / 2 - 0.1; // 防止看到地面以下
  controls.minPolarAngle = Math.PI / 6;

  // 目标点
  controls.target.set(0, 2, 0);

  // 控制状态
  const state: ControlState = {
    autoRotate: false,
    showHelp: false,
    showInfo: false
  };

  // 键盘控制
  const handleKeyPress = (event: KeyboardEvent) => {
    switch (event.key.toLowerCase()) {
      case 'r':
        // 重置视角
        (camera as THREE.PerspectiveCamera).position.set(0, 8, 12);
        controls.target.set(0, 2, 0);
        break;
      case 'a':
        // 切换自动旋转
        state.autoRotate = !state.autoRotate;
        controls.autoRotate = state.autoRotate;
        console.log(`自动旋转: ${state.autoRotate ? '开启' : '关闭'}`);
        break;
      case 'h':
        // 切换帮助信息
        state.showHelp = !state.showHelp;
        break;
      case 'i':
        // 切换详细信息
        state.showInfo = !state.showInfo;
        break;
      case 'arrowup':
        // 向上平移视角
        controls.target.y += 0.5;
        break;
      case 'arrowdown':
        // 向下平移视角
        controls.target.y -= 0.5;
        break;
    }
  };

  window.addEventListener('keydown', handleKeyPress);

  // 创建帮助面板
  const createHelpPanel = () => {
    const panel = document.createElement('div');
    panel.id = 'help-panel';
    panel.style.cssText = `
      position: fixed;
      top: 20px;
      right: 20px;
      background: rgba(10, 10, 26, 0.9);
      border: 1px solid rgba(0, 255, 255, 0.3);
      border-radius: 10px;
      padding: 20px;
      color: #00ffff;
      font-family: 'Microsoft YaHei', sans-serif;
      font-size: 14px;
      z-index: 1000;
      box-shadow: 0 0 20px rgba(0, 255, 255, 0.2);
      display: none;
    `;

    panel.innerHTML = `
      <div style="margin-bottom: 15px; font-size: 16px; font-weight: bold; color: #ff00ff;">
        🎮 控制说明
      </div>
      <div style="line-height: 1.8;">
        <div>🖱️ <strong>鼠标左键</strong>: 旋转视角</div>
        <div>🖱️ <strong>鼠标右键</strong>: 平移视角</div>
        <div>🖱️ <strong>滚轮</strong>: 缩放</div>
        <div>⌨️ <strong>R键</strong>: 重置视角</div>
        <div>⌨️ <strong>A键</strong>: 自动旋转开关</div>
        <div>⌨️ <strong>H键</strong>: 显示/隐藏帮助</div>
        <div>⌨️ <strong>↑/↓</strong>: 上下移动视角</div>
        <div>🔗 <strong>右侧按钮</strong>: 显示/隐藏信息面板</div>
      </div>
    `;

    document.body.appendChild(panel);
    return panel;
  };

  const helpPanel = createHelpPanel();

  // 更新帮助面板显示
  const updateHelpPanel = () => {
    helpPanel.style.display = state.showHelp ? 'block' : 'none';
  };

  // 监听H键切换帮助面板
  const originalHandleKeyPress = handleKeyPress;
  window.removeEventListener('keydown', originalHandleKeyPress);
  window.addEventListener('keydown', handleKeyPress);

  // 创建信息面板
  const createInfoPanel = () => {
    const panel = document.createElement('div');
    panel.id = 'info-panel';
    panel.style.cssText = `
      position: fixed;
      bottom: 20px;
      left: 20px;
      background: rgba(10, 10, 26, 0.9);
      border: 1px solid rgba(255, 0, 255, 0.3);
      border-radius: 10px;
      padding: 15px;
      color: #ff00ff;
      font-family: 'Microsoft YaHei', sans-serif;
      font-size: 12px;
      z-index: 1000;
      box-shadow: 0 0 20px rgba(255, 0, 255, 0.2);
      display: none;
    `;

    const updateInfo = () => {
      const camPos = (camera as THREE.PerspectiveCamera).position;
      panel.innerHTML = `
        <div style="font-weight: bold; margin-bottom: 10px; color: #00ffff;">
          📊 相机信息
        </div>
        <div style="line-height: 1.6;">
          <div>位置 X: ${camPos.x.toFixed(2)}</div>
          <div>位置 Y: ${camPos.y.toFixed(2)}</div>
          <div>位置 Z: ${camPos.z.toFixed(2)}</div>
          <div>目标: (${controls.target.x.toFixed(2)}, ${controls.target.y.toFixed(2)}, ${controls.target.z.toFixed(2)})</div>
          <div>自动旋转: ${state.autoRotate ? '✅' : '❌'}</div>
        </div>
      `;
    };

    document.body.appendChild(panel);

    return { panel, updateInfo };
  };

  const { panel: infoPanel, updateInfo: updateInfoPanel } = createInfoPanel();

  // 返回控制接口
  return {
    controls,
    state,

    // 在动画循环中调用
    update: () => {
      controls.update();

      if (state.showInfo) {
        updateInfoPanel();
      }

      updateHelpPanel();
    },

    // 清理
    dispose: () => {
      window.removeEventListener('keydown', handleKeyPress);
      controls.dispose();
      helpPanel.remove();
      infoPanel.remove();
    }
  };
};
export const render = () => {
  // 场景设置
  const container = document.getElementById('container');
  if (!container) return;

  const scene = new THREE.Scene();
  scene.background = new THREE.Color(0x0a0a1a);
  scene.fog = new THREE.Fog(0x0a0a1a, 10, 50);

  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.set(0, 8, 12);
  camera.lookAt(0, 2, 0);

  const renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  container.innerHTML = '';
  container.appendChild(renderer.domElement);

  // 创建 CSS3D 渲染器（用于 HTML/CSS 元素）
  const cssRenderer = new CSS3DRenderer();
  cssRenderer.setSize(window.innerWidth, window.innerHeight);
  cssRenderer.domElement.style.position = 'absolute';
  cssRenderer.domElement.style.top = '0';
  cssRenderer.domElement.style.left = '0';
  cssRenderer.domElement.style.pointerEvents = 'none'; // 允许点击穿透到 WebGL
  container.appendChild(cssRenderer.domElement);

  // ============ 模块1：流光旋转地面 ============
  const groundGeometry = new THREE.PlaneGeometry(60, 60, 100, 100);

  // 创建流光效果的着色器材质
  const groundMaterial = new THREE.ShaderMaterial({
    uniforms: {
      time: { value: 0 },
      color1: { value: new THREE.Color(0x00ffff) },
      color2: { value: new THREE.Color(0xff00ff) },
      color3: { value: new THREE.Color(0x0066ff) }
    },
    vertexShader: `
      varying vec2 vUv;
      varying float vElevation;
      uniform float time;

      void main() {
        vUv = uv;

        vec3 pos = position;
        float elevation = sin(pos.x * 0.3 + time) * 0.3 +
                         sin(pos.y * 0.2 + time * 0.8) * 0.2 +
                         sin((pos.x + pos.y) * 0.1 + time * 1.2) * 0.15;
        vElevation = elevation;
        pos.z += elevation;

        gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
      }
    `,
    fragmentShader: `
      varying vec2 vUv;
      varying float vElevation;
      uniform float time;
      uniform vec3 color1;
      uniform vec3 color2;
      uniform vec3 color3;

      void main() {
        vec2 center = vec2(0.5, 0.5);
        float dist = distance(vUv, center);

        // 旋转流光效果
        float angle = atan(vUv.y - 0.5, vUv.x - 0.5);
        float rotatingAngle = angle + time * 0.5;

        // 多层流光
        float light1 = sin(rotatingAngle * 3.0 + dist * 20.0 - time * 2.0) * 0.5 + 0.5;
        float light2 = sin(rotatingAngle * 5.0 - dist * 15.0 + time * 1.5) * 0.5 + 0.5;
        float light3 = sin(dist * 30.0 - time * 3.0) * 0.5 + 0.5;

        // 流光线条
        float lines = smoothstep(0.4, 0.6, light1) * smoothstep(0.6, 0.4, light1);
        lines += smoothstep(0.45, 0.55, light2) * smoothstep(0.55, 0.45, light2) * 0.5;

        // 距离衰减
        float fade = 1.0 - smoothstep(0.0, 0.5, dist);

        // 颜色混合
        vec3 color = mix(color1, color2, light3);
        color = mix(color, color3, light2 * 0.5);

        // 添加发光
        float glow = lines * 2.0 * fade;
        color += glow * color1;

        // 基础网格
        float gridX = step(0.98, fract(vUv.x * 40.0));
        float gridY = step(0.98, fract(vUv.y * 40.0));
        float grid = max(gridX, gridY) * 0.1 * fade;

        color += grid * vec3(0.2, 0.4, 0.6);

        // 边缘渐隐
        float edgeFade = smoothstep(0.5, 0.3, dist);

        gl_FragColor = vec4(color * edgeFade, edgeFade * 0.9);
      }
    `,
    transparent: true,
    side: THREE.DoubleSide
  });

  const ground = new THREE.Mesh(groundGeometry, groundMaterial);
  ground.rotation.x = -Math.PI / 2;
  ground.receiveShadow = true;
  scene.add(ground);

  // ============ 添加信息面板模块（使用 CSS3DObject，居中显示）============
  const createIframePanel3D = (camera: THREE.PerspectiveCamera, controls: OrbitControls) => {
    // ============ 相机移动配置 ============
    // 可调整的目标相机位置参数
    const cameraTargetConfig = {
      position: {
        x: 0,      // 相机目标位置 X
        y: 3.5,    // 相机目标位置 Y（与面板中心对齐）
        z: 8       // 相机目标位置 Z（距离面板的距离，可调整）
      },
      target: {
        x: 0,      // 控制器目标点 X（面板中心）
        y: 3.5,    // 控制器目标点 Y（面板中心高度）
        z: 0       // 控制器目标点 Z（面板中心）
      },
      duration: 1500  // 动画持续时间（毫秒），可调整
    };

    // 平滑移动相机到目标位置的函数
    const moveCameraToPanel = () => {
      const startPosition = {
        x: camera.position.x,
        y: camera.position.y,
        z: camera.position.z
      };
      const startTarget = {
        x: controls.target.x,
        y: controls.target.y,
        z: controls.target.z
      };

      const startTime = Date.now();

      const animateCamera = () => {
        const elapsed = Date.now() - startTime;
        const progress = Math.min(elapsed / cameraTargetConfig.duration, 1);

        // 使用缓动函数（easeInOutCubic）
        const easeProgress = progress < 0.5
          ? 4 * progress * progress * progress
          : 1 - Math.pow(-2 * progress + 2, 3) / 2;

        // 插值更新相机位置
        camera.position.x = startPosition.x + (cameraTargetConfig.position.x - startPosition.x) * easeProgress;
        camera.position.y = startPosition.y + (cameraTargetConfig.position.y - startPosition.y) * easeProgress;
        camera.position.z = startPosition.z + (cameraTargetConfig.position.z - startPosition.z) * easeProgress;

        // 插值更新控制器目标点
        controls.target.x = startTarget.x + (cameraTargetConfig.target.x - startTarget.x) * easeProgress;
        controls.target.y = startTarget.y + (cameraTargetConfig.target.y - startTarget.y) * easeProgress;
        controls.target.z = startTarget.z + (cameraTargetConfig.target.z - startTarget.z) * easeProgress;

        controls.update();

        if (progress < 1) {
          requestAnimationFrame(animateCamera);
        }
      };

      animateCamera();
    };

    // 创建 HTML 元素
    const div = document.createElement('div');
    div.style.cssText = `
      width: 1400px;
      height: 700px;
      background: rgba(10, 10, 26, 0.95);
      border: 2px solid rgba(0, 255, 255, 0.5);
      border-radius: 15px;
      box-shadow: 0 0 30px rgba(0, 255, 255, 0.3), inset 0 0 20px rgba(0, 255, 255, 0.1);
      overflow: hidden;
    `;

    // 创建标题栏
    const header = document.createElement('div');
    header.style.cssText = `
      background: linear-gradient(90deg, rgba(0, 255, 255, 0.2), rgba(255, 0, 255, 0.2));
      padding: 12px 15px;
      border-bottom: 1px solid rgba(0, 255, 255, 0.3);
      display: flex;
      justify-content: space-between;
      align-items: center;
    `;

    const title = document.createElement('div');
    title.textContent = '我的信息面板';
    title.style.cssText = `
      color: #00ffff;
      font-family: 'Microsoft YaHei', sans-serif;
      font-size: 16px;
      font-weight: bold;
      text-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
      cursor: pointer;
      user-select: none;
      transition: all 0.3s;
    `;

    // 鼠标悬停效果
    title.onmouseover = () => {
      title.style.color = '#ff00ff';
      title.style.textShadow = '0 0 15px rgba(255, 0, 255, 0.8)';
    };
    title.onmouseout = () => {
      title.style.color = '#00ffff';
      title.style.textShadow = '0 0 10px rgba(0, 255, 255, 0.5)';
    };

    // 点击标题时移动相机到面板前方
    title.onclick = () => {
      moveCameraToPanel();
    };

    const closeButton = document.createElement('button');
    closeButton.textContent = '✕';
    closeButton.style.cssText = `
      background: rgba(255, 0, 100, 0.3);
      border: 1px solid rgba(255, 0, 100, 0.5);
      color: #fff;
      width: 28px;
      height: 28px;
      border-radius: 5px;
      cursor: pointer;
      font-size: 16px;
      transition: all 0.2s;
    `;
    closeButton.onmouseover = () => {
      closeButton.style.background = 'rgba(255, 0, 100, 0.6)';
    };
    closeButton.onmouseout = () => {
      closeButton.style.background = 'rgba(255, 0, 100, 0.3)';
    };
    closeButton.onclick = () => {
      // 隐藏面板
      css3dObject.visible = false;
    };

    header.appendChild(title);
    header.appendChild(closeButton);

    // 创建 iframe 容器
    const iframeContainer = document.createElement('div');
    iframeContainer.style.cssText = `
      width: 100%;
      height: calc(100% - 50px);
      position: relative;
      background: rgba(0, 0, 0, 0.3);
    `;

    // 创建 iframe
    const iframe = document.createElement('iframe');
    iframe.src = '/info/';
    iframe.style.cssText = `
      width: 100%;
      height: 100%;
      border: none;
      background: transparent;
    `;

    iframeContainer.appendChild(iframe);

    // 添加发光装饰角
    const corners = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];
    corners.forEach(corner => {
      const cornerEl = document.createElement('div');
      cornerEl.style.cssText = `
        position: absolute;
        width: 20px;
        height: 20px;
        border: 2px solid #00ffff;
        ${corner.includes('top') ? 'top: -2px;' : 'bottom: -2px;'}
        ${corner.includes('left') ? 'left: -2px;' : 'right: -2px;'}
        ${corner.includes('top') ? corner.includes('left') ? 'border-right: none;' : 'border-left: none;' : corner.includes('left') ? 'border-right: none;' : 'border-left: none;'}
        ${corner.includes('top') ? corner.includes('left') ? 'border-bottom: none;' : 'border-bottom: none;' : corner.includes('left') ? 'border-top: none;' : 'border-top: none;'}
        box-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
      `;
      div.appendChild(cornerEl);
    });

    div.appendChild(header);
    div.appendChild(iframeContainer);

    // 创建 CSS3DObject
    const css3dObject = new CSS3DObject(div);
    css3dObject.position.set(0, 3.5, 0); // 居中显示
    css3dObject.rotation.y = 0; // 面向正前方
    css3dObject.scale.set(0.01, 0.01, 0.01); // 缩放以适应场景

    scene.add(css3dObject);

    // 添加打开按钮（固定在屏幕上）
    const openButton = document.createElement('button');
    openButton.id = 'open-iframe-btn';
    openButton.textContent = '🔗 打开信息面板';
    openButton.style.cssText = `
      position: fixed;
      top: 50%;
      right: 20px;
      transform: translateY(-50%);
      background: linear-gradient(135deg, rgba(0, 255, 255, 0.2), rgba(255, 0, 255, 0.2));
      border: 2px solid rgba(0, 255, 255, 0.5);
      color: #00ffff;
      padding: 12px 24px;
      border-radius: 25px;
      cursor: pointer;
      font-family: 'Microsoft YaHei', sans-serif;
      font-size: 14px;
      font-weight: bold;
      text-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
      box-shadow: 0 0 20px rgba(0, 255, 255, 0.3);
      transition: all 0.3s;
      z-index: 50;
      pointer-events: auto;
    `;
    openButton.onmouseover = () => {
      openButton.style.background = 'linear-gradient(135deg, rgba(0, 255, 255, 0.4), rgba(255, 0, 255, 0.4))';
      openButton.style.transform = 'translateY(-50%) scale(1.05)';
    };
    openButton.onmouseout = () => {
      openButton.style.background = 'linear-gradient(135deg, rgba(0, 255, 255, 0.2), rgba(255, 0, 255, 0.2))';
      openButton.style.transform = 'translateY(-50%) scale(1)';
    };
    openButton.onclick = () => {
      css3dObject.visible = !css3dObject.visible;
    };

    document.body.appendChild(openButton);

    return {
      css3dObject,
      openButton,
      dispose: () => {
        scene.remove(css3dObject);
        openButton.remove();
      }
    };
  };

  // ============ 控制模块初始化 ============
  const controlModule = createControlModule({
    scene,
    camera,
    renderer
  });

  // 创建信息面板（传入 camera 和 controls）
  const iframePanel3D = createIframePanel3D(camera, controlModule.controls);

  // ============ 灯光系统 ============
  const ambientLight = new THREE.AmbientLight(0x222244, 0.5);
  scene.add(ambientLight);

  // 主光源
  const mainLight = new THREE.PointLight(0x00ffff, 2, 50);
  mainLight.position.set(5, 10, 5);
  mainLight.castShadow = true;
  scene.add(mainLight);

  // 辅助光源
  const auxLight = new THREE.PointLight(0xff00ff, 1.5, 50);
  auxLight.position.set(-5, 8, -5);
  scene.add(auxLight);

  // 聚光灯照亮广告牌
  const spotLight = new THREE.SpotLight(0xffffff, 3);
  spotLight.position.set(0, 15, 0);
  spotLight.angle = Math.PI / 6;
  spotLight.penumbra = 0.5;
  spotLight.castShadow = true;
  scene.add(spotLight);

  // ============ 粒子系统 ============
  const particleCount = 500;
  const particleGeometry = new THREE.BufferGeometry();
  const positions = new Float32Array(particleCount * 3);
  const colors = new Float32Array(particleCount * 3);

  for (let i = 0; i < particleCount; i++) {
    positions[i * 3] = (Math.random() - 0.5) * 50;
    positions[i * 3 + 1] = Math.random() * 10;
    positions[i * 3 + 2] = (Math.random() - 0.5) * 50;

    const color = new THREE.Color();
    color.setHSL(Math.random() * 0.2 + 0.5, 1, 0.5);
    colors[i * 3] = color.r;
    colors[i * 3 + 1] = color.g;
    colors[i * 3 + 2] = color.b;
  }

  particleGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
  particleGeometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));

  const particleMaterial = new THREE.PointsMaterial({
    size: 0.1,
    vertexColors: true,
    transparent: true,
    opacity: 0.8,
    blending: THREE.AdditiveBlending
  });

  const particles = new THREE.Points(particleGeometry, particleMaterial);
  scene.add(particles);

  // ============ 动画循环 ============
  let time = 0;

  const animate = () => {
    requestAnimationFrame(animate);
    time += 0.016;

    // 更新地面着色器时间
    groundMaterial.uniforms.time.value = time;

    // 粒子动画
    const particlePositions = particleGeometry.attributes.position.array as Float32Array;
    for (let i = 0; i < particleCount; i++) {
      particlePositions[i * 3 + 1] += 0.02;
      if (particlePositions[i * 3 + 1] > 10) {
        particlePositions[i * 3 + 1] = 0;
      }
    }
    particleGeometry.attributes.position.needsUpdate = true;

    // 灯光旋转
    mainLight.position.x = Math.sin(time * 0.5) * 8;
    mainLight.position.z = Math.cos(time * 0.5) * 8;

    auxLight.position.x = Math.sin(time * 0.3 + Math.PI) * 8;
    auxLight.position.z = Math.cos(time * 0.3 + Math.PI) * 8;

    // 更新控制模块
    controlModule.update();

    // 渲染 WebGL 和 CSS3D
    renderer.render(scene, camera);
    cssRenderer.render(scene, camera);
  };

  animate();

  // ============ 窗口自适应 ============
  const handleResize = () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
    cssRenderer.setSize(window.innerWidth, window.innerHeight);
  };

  window.addEventListener('resize', handleResize);

  // 返回清理函数
  return () => {
    window.removeEventListener('resize', handleResize);
    controlModule.dispose();
    iframePanel3D.dispose();
    renderer.dispose();
    groundMaterial.dispose();
    particleMaterial.dispose();
  };
};