/**
 * DC 入场特效 - 主模块
 * 粒子星场 → 充电桩卡牌依次飞入 → 动态文案 → 淡出进入监控页
 */

import { createStarfield } from './dc-intro-starfield.js';

// ===== 时间配置（秒） =====
const T_STARFIELD   = 0;
const T_CARD_START  = 1.2;   // 卡牌开始飞入
const T_CARD_STAGGER = 0.18; // 卡牌间隔
const T_CARD_FLIGHT = 1.0;   // 单张卡飞行耗时
const T_TEXT_SHOW   = 2.8;   // 文案淡入
const T_HOLD_END   = 4.5;   // 停留结束
const T_FADE_DONE  = 5.0;   // 淡出完成
const T_TIMEOUT    = 6.0;   // 强制超时

// ===== Three.js 引用 =====
let THREE = null;
let scene, camera, renderer, clock;
let starfield;
let cardMeshes = [];
let textEl = null;
let containerEl = null;
let animFrameId = null;

// ===== 状态 =====
let startTime = 0;
let resolvePlay = null;
let isPlaying = false;

/**
 * 播放入场特效
 * @param {Array<{name: string, power: string}>} freeDCList - 空闲 DC 充电桩列表
 * @returns {Promise<void>} 特效完成后 resolve
 */
export async function play(freeDCList) {
  if (!freeDCList || freeDCList.length === 0) return;

  // 懒加载 Three.js
  try {
    const mod = await import('../../assets/three.module.min.js');
    THREE = mod;
    window.THREE = THREE; // 供 starfield 模块使用
  } catch (e) {
    console.warn('[dc-intro] Three.js 加载失败，跳过特效', e);
    return;
  }

  // 检测 WebGL
  if (!checkWebGL()) {
    console.warn('[dc-intro] WebGL 不可用，跳过特效');
    return;
  }

  return new Promise((resolve) => {
    resolvePlay = resolve;
    isPlaying = true;

    try {
      setupContainer();
      initScene();
      createCards(freeDCList);
      createTextElement(freeDCList.length);
      startAnimation();
    } catch (e) {
      console.error('[dc-intro] 特效初始化失败', e);
      destroy();
      resolve();
    }

    // 强制超时保护
    setTimeout(() => {
      if (isPlaying) {
        console.warn('[dc-intro] 特效超时，强制结束');
        finish();
      }
    }, T_TIMEOUT * 1000);
  });
}

/**
 * 检测 WebGL 是否可用
 */
function checkWebGL() {
  try {
    const canvas = document.createElement('canvas');
    return !!(canvas.getContext('webgl2') || canvas.getContext('webgl'));
  } catch {
    return false;
  }
}

/**
 * 设置 DOM 容器
 */
function setupContainer() {
  containerEl = document.getElementById('dc-intro');
  if (!containerEl) {
    containerEl = document.createElement('div');
    containerEl.id = 'dc-intro';
    document.body.appendChild(containerEl);
  }
}

/**
 * 初始化 Three.js 场景
 */
function initScene() {
  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 200);
  camera.position.set(0, 0, 10);
  camera.lookAt(0, 0, 0);

  renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false, powerPreference: 'high-performance' });
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 限制像素比，高 DPI 屏幕降采样
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1.5));
  renderer.setClearColor(0x000000, 1);
  containerEl.appendChild(renderer.domElement);

  clock = new THREE.Clock();

  // 创建粒子星场
  starfield = createStarfield(scene);

  // 窗口自适应
  window.__dcIntroResize = () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  };
  window.addEventListener('resize', window.__dcIntroResize);
}

/**
 * 动态绘制卡牌纹理
 * @param {string} name - 充电桩编号
 * @param {string} power - 功率
 * @returns {THREE.CanvasTexture}
 */
function drawCardTexture(name, power) {
  const w = 256, h = 360;
  const canvas = document.createElement('canvas');
  canvas.width = w;
  canvas.height = h;
  const ctx = canvas.getContext('2d');

  // 背景渐变 — 深金黑底
  const bgGrad = ctx.createLinearGradient(0, 0, w, h);
  bgGrad.addColorStop(0, '#1a1408');
  bgGrad.addColorStop(1, '#0f0a04');
  roundRect(ctx, 0, 0, w, h, 16);
  ctx.fillStyle = bgGrad;
  ctx.fill();

  // 金色边框
  ctx.strokeStyle = '#f59e0b';
  ctx.lineWidth = 3;
  roundRect(ctx, 4, 4, w - 8, h - 8, 14);
  ctx.stroke();

  // 光晕效果（顶部金色）
  const glowGrad = ctx.createRadialGradient(w / 2, h * 0.25, 10, w / 2, h * 0.25, 100);
  glowGrad.addColorStop(0, 'rgba(251, 191, 36, 0.15)');
  glowGrad.addColorStop(1, 'rgba(251, 191, 36, 0)');
  ctx.fillStyle = glowGrad;
  ctx.fillRect(0, 0, w, h);

  // ⚡ 图标 — 金色
  ctx.font = 'bold 56px sans-serif';
  ctx.textAlign = 'center';
  ctx.fillStyle = '#fbbf24';
  ctx.shadowColor = 'rgba(251, 191, 36, 0.5)';
  ctx.shadowBlur = 20;
  ctx.fillText('⚡', w / 2, h * 0.28);
  ctx.shadowBlur = 0;

  // 充电桩编号
  ctx.font = 'bold 32px sans-serif';
  ctx.fillStyle = '#e2e8f0';
  ctx.fillText(name, w / 2, h * 0.48);

  // 状态标签
  ctx.font = 'bold 22px sans-serif';
  ctx.fillStyle = '#fbbf24';
  ctx.fillText('空闲', w / 2, h * 0.58);

  // 分割线
  ctx.strokeStyle = 'rgba(245, 158, 11, 0.3)';
  ctx.lineWidth = 1;
  ctx.beginPath();
  ctx.moveTo(w * 0.2, h * 0.65);
  ctx.lineTo(w * 0.8, h * 0.65);
  ctx.stroke();

  // 功率
  ctx.font = '18px sans-serif';
  ctx.fillStyle = '#94a3b8';
  ctx.fillText(`${power}kW 直流快充`, w / 2, h * 0.74);

  const texture = new THREE.CanvasTexture(canvas);
  texture.needsUpdate = true;
  return texture;
}

/**
 * Canvas 圆角矩形辅助
 */
function roundRect(ctx, x, y, w, h, r) {
  ctx.beginPath();
  ctx.moveTo(x + r, y);
  ctx.lineTo(x + w - r, y);
  ctx.quadraticCurveTo(x + w, y, x + w, y + r);
  ctx.lineTo(x + w, y + h - r);
  ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
  ctx.lineTo(x + r, y + h);
  ctx.quadraticCurveTo(x, y + h, x, y + h - r);
  ctx.lineTo(x, y + r);
  ctx.quadraticCurveTo(x, y, x + r, y);
  ctx.closePath();
}

/**
 * 创建充电桩卡牌
 * @param {Array<{name: string, power: string}>} freeDCList
 */
function createCards(freeDCList) {
  cardMeshes = [];
  const count = freeDCList.length;

  freeDCList.forEach((pile, index) => {
    const texture = drawCardTexture(pile.name, pile.power);
    const aspect = 256 / 360;
    const cardHeight = 4.5;
    const cardWidth = cardHeight * aspect;

    const geometry = new THREE.PlaneGeometry(cardWidth, cardHeight);
    const material = new THREE.MeshBasicMaterial({
      map: texture,
      transparent: true,
      opacity: 0,
      side: THREE.DoubleSide,
    });

    const mesh = new THREE.Mesh(geometry, material);

    // ---- 炫酷入场：随机散布起点 ----
    const angle = (index / count) * Math.PI * 2 + (Math.random() - 0.5) * 0.8;
    const radius = 25 + Math.random() * 20;
    const startX = Math.cos(angle) * radius * 0.5;
    const startY = (Math.random() - 0.5) * 18;           // 上下散布
    const startZ = -45 - Math.random() * 25;              // 远处散布

    mesh.position.set(startX, startY, startZ);

    // 初始大幅旋转（1-3 圈）
    const startRotY = (Math.random() - 0.5) * Math.PI * 4;
    const startRotX = (Math.random() - 0.5) * Math.PI * 1.5;
    mesh.rotation.set(startRotX, startRotY, 0);

    // 初始缩放
    const startScale = 0.15 + Math.random() * 0.3;
    mesh.scale.set(startScale, startScale, startScale);

    // 目标位置
    const targetX = (index - (count - 1) / 2) * 0.5;
    const targetY = 0.3;
    const targetZ = -index * 0.3;
    const targetRotY = (index - (count - 1) / 2) * 0.12;

    // 飞行弧顶（Bezier 控制点）
    const arcPeakY = 4 + Math.random() * 3;
    const arcSide = (Math.random() - 0.5) * 4;

    mesh.userData = {
      startX, startY, startZ,
      startRotY, startRotX,
      startScale,
      arcPeakY, arcSide,
      targetX, targetY, targetZ,
      targetRotY,
      delay: T_CARD_START + index * T_CARD_STAGGER,
      landed: false,
    };

    scene.add(mesh);
    cardMeshes.push(mesh);
  });
}

/**
 * 创建文案 DOM 元素
 * @param {number} count - 空闲桩数量
 */
function createTextElement(count) {
  textEl = document.createElement('div');
  textEl.className = 'dc-intro-text';
  textEl.textContent = `捡到宝了！有 ${count} 个快充空闲`;
  containerEl.appendChild(textEl);
}

/**
 * easeOutBack 弹性缓动（轻微 overshoot）
 */
function easeOutBack(t) {
  const c1 = 1.70158;
  const c3 = c1 + 1;
  return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
}

/**
 * easeInOutCubic — 用于旋转减速
 */
function easeInOutCubic(t) {
  return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
}

/**
 * Quadratic bezier 插值
 */
function bezier2(p0, p1, p2, t) {
  const mt = 1 - t;
  return mt * mt * p0 + 2 * mt * t * p1 + t * t * p2;
}

/**
 * 启动动画循环
 */
function startAnimation() {
  startTime = performance.now() / 1000;
  animate();
}

/**
 * 动画主循环
 */
function animate() {
  if (!isPlaying) return;

  animFrameId = requestAnimationFrame(animate);

  const now = performance.now() / 1000;
  const elapsed = now - startTime;
  const delta = clock.getDelta();

  // Phase 4: 粒子减速
  if (elapsed >= T_TEXT_SHOW && starfield) {
    starfield.slowDown();
  }

  // 更新粒子
  if (starfield) {
    starfield.update(delta);
  }

  // Phase 2: 卡牌炫酷飞入
  cardMeshes.forEach((mesh) => {
    const d = mesh.userData;
    const cardElapsed = elapsed - d.delay;

    if (cardElapsed < 0) return;

    const fp = Math.min(1, cardElapsed / T_CARD_FLIGHT);
    const flightEase = easeOutBack(fp);

    // 位置：Bezier 弧线飞行
    const arcCtrlX = (d.startX + d.targetX) / 2 + d.arcSide;
    const arcCtrlY = d.arcPeakY;
    const arcCtrlZ = (d.startZ + d.targetZ) / 2 + 8;

    mesh.position.x = bezier2(d.startX, arcCtrlX, d.targetX, flightEase);
    mesh.position.y = bezier2(d.startY, arcCtrlY, d.targetY, flightEase);
    mesh.position.z = bezier2(d.startZ, arcCtrlZ, d.targetZ, flightEase);

    // 旋转：从大幅旋转降速到目标
    const rotEase = easeInOutCubic(fp);
    mesh.rotation.y = d.startRotY + (d.targetRotY - d.startRotY) * rotEase;
    mesh.rotation.x = d.startRotX * (1 - rotEase);

    // 缩放：弹性由小变大
    const scale = d.startScale + (1.0 - d.startScale) * flightEase;
    mesh.scale.setScalar(scale);

    // 透明度
    mesh.material.opacity = Math.min(1, cardElapsed * 6);

    // 落地瞬间光亮脉冲
    if (fp >= 1 && !d.landed) {
      d.landed = true;
      mesh.position.set(d.targetX, d.targetY, d.targetZ);
      mesh.rotation.set(0, d.targetRotY, 0);
      mesh.scale.setScalar(1);

      // 落地脉冲缩放
      const landPulse = () => {
        const gsapInstance = globalThis.gsap;
        if (!isPlaying || !gsapInstance) return;
        gsapInstance.to(mesh.scale, {
          x: 1.08, y: 1.08, z: 1.08,
          duration: 0.15,
          ease: 'power2.out',
          onComplete: () => {
            gsapInstance.to(mesh.scale, {
              x: 1, y: 1, z: 1,
              duration: 0.4,
              ease: 'elastic.out(1, 0.4)',
            });
          },
        });
      };
      // 队列到下一帧执行（保证 set 先落地）
      requestAnimationFrame(landPulse);
    }
  });

  // Phase 3: 文案淡入
  if (elapsed >= T_TEXT_SHOW && textEl) {
    textEl.classList.add('show');
  }

  // Phase 5: 淡出
  if (elapsed >= T_HOLD_END) {
    containerEl.classList.add('fade-out');
  }

  if (elapsed >= T_FADE_DONE) {
    finish();
    return;
  }

  renderer.render(scene, camera);
}

/**
 * 特效完成，清理资源
 */
function finish() {
  isPlaying = false;
  if (animFrameId) {
    cancelAnimationFrame(animFrameId);
    animFrameId = null;
  }
  destroy();
  if (resolvePlay) {
    resolvePlay();
    resolvePlay = null;
  }
}

/**
 * 销毁 Three.js 资源
 */
function destroy() {
  // 移除 resize 监听
  if (window.__dcIntroResize) {
    window.removeEventListener('resize', window.__dcIntroResize);
    window.__dcIntroResize = null;
  }

  // 移除容器
  if (containerEl && containerEl.parentNode) {
    containerEl.parentNode.removeChild(containerEl);
  }
  containerEl = null;

  // 销毁 Three.js 资源
  if (renderer) {
    renderer.dispose();
    renderer = null;
  }

  if (scene) {
    scene.traverse((obj) => {
      if (obj.geometry) obj.geometry.dispose();
      if (obj.material) {
        if (Array.isArray(obj.material)) {
          obj.material.forEach(m => m.dispose());
        } else {
          obj.material.dispose();
        }
      }
    });
    scene = null;
  }

  camera = null;
  clock = null;
  starfield = null;
  cardMeshes = [];
  textEl = null;
  THREE = null;
}
