import * as THREE from 'three';

/**
 * Create a 3D scene inspired by payment QR code illustration
 * Features: Large phone/tablet with QR code, person figure, floating coins, and security shield
 */
export function initHeroScene() {
  const container = document.getElementById('hero-3d-container');
  if (!container) return;

  // Scene setup
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(
    50,
    container.clientWidth / container.clientHeight,
    0.1,
    1000
  );
  camera.position.set(0, 0, 10);

  const renderer = new THREE.WebGLRenderer({
    alpha: true,
    antialias: true
  });
  renderer.setSize(container.clientWidth, container.clientHeight);
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  container.appendChild(renderer.domElement);

  // Lighting
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
  scene.add(ambientLight);

  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
  directionalLight.position.set(5, 5, 5);
  scene.add(directionalLight);

  const pointLight = new THREE.PointLight(0xFF7A59, 1, 100);
  pointLight.position.set(-5, 5, 5);
  scene.add(pointLight);

  // Create QR Code Cube (centerpiece)
  const qrCodeTexture = createQRCodeTexture();
  const qrCubeGeometry = new THREE.BoxGeometry(2, 2, 2);
  const qrCubeMaterial = new THREE.MeshStandardMaterial({
    map: qrCodeTexture,
    metalness: 0.3,
    roughness: 0.4,
  });
  const qrCube = new THREE.Mesh(qrCubeGeometry, qrCubeMaterial);
  qrCube.position.set(0, 0, 0);
  scene.add(qrCube);

  // Create Euro coins
  const coins = [];
  const coinGeometry = new THREE.CylinderGeometry(0.3, 0.3, 0.1, 32);
  const coinMaterial = new THREE.MeshStandardMaterial({
    color: 0xFFD700,
    metalness: 0.8,
    roughness: 0.2,
  });

  for (let i = 0; i < 6; i++) {
    const coin = new THREE.Mesh(coinGeometry, coinMaterial);
    const angle = (i / 6) * Math.PI * 2;
    const radius = 3;
    coin.position.set(
      Math.cos(angle) * radius,
      Math.sin(angle * 2) * 1.5,
      Math.sin(angle) * radius
    );
    coin.rotation.x = Math.PI / 2;
    coins.push({ mesh: coin, angle, radius, offset: i });
    scene.add(coin);
  }

  // Create shopping cart icon (simplified)
  const cartGroup = new THREE.Group();

  // Cart body
  const cartBodyGeometry = new THREE.BoxGeometry(0.8, 0.6, 0.6);
  const cartMaterial = new THREE.MeshStandardMaterial({
    color: 0x2563EB,
    metalness: 0.5,
    roughness: 0.3,
  });
  const cartBody = new THREE.Mesh(cartBodyGeometry, cartMaterial);
  cartGroup.add(cartBody);

  // Cart wheels
  const wheelGeometry = new THREE.CylinderGeometry(0.1, 0.1, 0.05, 16);
  const wheelMaterial = new THREE.MeshStandardMaterial({ color: 0x1E293B });

  const wheel1 = new THREE.Mesh(wheelGeometry, wheelMaterial);
  wheel1.position.set(-0.2, -0.4, 0.3);
  wheel1.rotation.z = Math.PI / 2;
  cartGroup.add(wheel1);

  const wheel2 = new THREE.Mesh(wheelGeometry, wheelMaterial);
  wheel2.position.set(0.2, -0.4, 0.3);
  wheel2.rotation.z = Math.PI / 2;
  cartGroup.add(wheel2);

  cartGroup.position.set(-3, -2, 2);
  cartGroup.scale.set(1.5, 1.5, 1.5);
  scene.add(cartGroup);

  // Create smartphone (payment device)
  const phoneGroup = new THREE.Group();

  const phoneBodyGeometry = new THREE.BoxGeometry(0.6, 1, 0.1);
  const phoneMaterial = new THREE.MeshStandardMaterial({
    color: 0x1E293B,
    metalness: 0.6,
    roughness: 0.2,
  });
  const phoneBody = new THREE.Mesh(phoneBodyGeometry, phoneMaterial);
  phoneGroup.add(phoneBody);

  // Phone screen
  const screenGeometry = new THREE.BoxGeometry(0.54, 0.9, 0.05);
  const screenMaterial = new THREE.MeshStandardMaterial({
    color: 0x4A90E2,
    emissive: 0x2563EB,
    emissiveIntensity: 0.3,
  });
  const screen = new THREE.Mesh(screenGeometry, screenMaterial);
  screen.position.z = 0.06;
  phoneGroup.add(screen);

  phoneGroup.position.set(3, -1.5, 1);
  phoneGroup.rotation.y = -0.3;
  phoneGroup.scale.set(1.5, 1.5, 1.5);
  scene.add(phoneGroup);

  // Create bank icon
  const bankGroup = new THREE.Group();

  const bankBodyGeometry = new THREE.BoxGeometry(1.2, 0.8, 0.6);
  const bankMaterial = new THREE.MeshStandardMaterial({
    color: 0xFF7A59,
    metalness: 0.3,
    roughness: 0.5,
  });
  const bankBody = new THREE.Mesh(bankBodyGeometry, bankMaterial);
  bankGroup.add(bankBody);

  // Bank roof
  const roofGeometry = new THREE.ConeGeometry(0.9, 0.4, 4);
  const roofMaterial = new THREE.MeshStandardMaterial({
    color: 0xE85A3D,
  });
  const roof = new THREE.Mesh(roofGeometry, roofMaterial);
  roof.position.y = 0.6;
  roof.rotation.y = Math.PI / 4;
  bankGroup.add(roof);

  bankGroup.position.set(2.5, 2, -1);
  bankGroup.scale.set(0.8, 0.8, 0.8);
  scene.add(bankGroup);

  // Particle system for data flow
  const particlesGeometry = new THREE.BufferGeometry();
  const particlesCount = 50;
  const positions = new Float32Array(particlesCount * 3);

  for (let i = 0; i < particlesCount * 3; i++) {
    positions[i] = (Math.random() - 0.5) * 10;
  }

  particlesGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
  const particlesMaterial = new THREE.PointsMaterial({
    color: 0xFF7A59,
    size: 0.05,
    transparent: true,
    opacity: 0.6,
  });
  const particles = new THREE.Points(particlesGeometry, particlesMaterial);
  scene.add(particles);

  // Animation
  let time = 0;
  function animate() {
    requestAnimationFrame(animate);
    time += 0.01;

    // Rotate QR cube
    qrCube.rotation.y += 0.005;
    qrCube.rotation.x = Math.sin(time) * 0.1;
    qrCube.position.y = Math.sin(time * 1.5) * 0.2;

    // Animate coins in orbit
    coins.forEach((coinData, index) => {
      const { mesh, angle, radius, offset } = coinData;
      const newAngle = angle + time * 0.5;
      mesh.position.x = Math.cos(newAngle) * radius;
      mesh.position.z = Math.sin(newAngle) * radius;
      mesh.position.y = Math.sin(time * 2 + offset) * 1.5;
      mesh.rotation.y += 0.02;
    });

    // Animate cart (bobbing)
    cartGroup.position.y = -2 + Math.sin(time * 2) * 0.1;
    cartGroup.rotation.y = Math.sin(time * 0.5) * 0.1;

    // Animate phone
    phoneGroup.position.y = -1.5 + Math.sin(time * 1.5 + 1) * 0.15;
    phoneGroup.rotation.z = Math.sin(time * 0.8) * 0.05;

    // Animate bank
    bankGroup.position.y = 2 + Math.sin(time * 1.2 + 2) * 0.1;

    // Animate particles
    particles.rotation.y += 0.001;
    const positions = particles.geometry.attributes.position.array;
    for (let i = 0; i < positions.length; i += 3) {
      positions[i + 1] += Math.sin(time + i) * 0.002;
    }
    particles.geometry.attributes.position.needsUpdate = true;

    renderer.render(scene, camera);
  }

  animate();

  // Handle resize
  function onWindowResize() {
    if (!container) return;
    camera.aspect = container.clientWidth / container.clientHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(container.clientWidth, container.clientHeight);
  }

  window.addEventListener('resize', onWindowResize);

  // Cleanup function
  return () => {
    window.removeEventListener('resize', onWindowResize);
    renderer.dispose();
    container.removeChild(renderer.domElement);
  };
}

/**
 * Create a procedural QR code texture
 */
function createQRCodeTexture() {
  const canvas = document.createElement('canvas');
  canvas.width = 512;
  canvas.height = 512;
  const ctx = canvas.getContext('2d');

  // White background
  ctx.fillStyle = '#FFFFFF';
  ctx.fillRect(0, 0, 512, 512);

  // Draw QR code pattern
  ctx.fillStyle = '#000000';
  const moduleSize = 32;
  const modules = 16;

  // QR code pattern (simplified)
  const pattern = [
    [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1],
    [1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1],
    [1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1],
    [1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1],
    [1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
    [1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
    [0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
    [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
    [1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1],
    [1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0],
    [1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1],
    [1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0],
    [1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1],
    [1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0],
    [1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1],
  ];

  const offset = (512 - (pattern.length * moduleSize)) / 2;

  pattern.forEach((row, i) => {
    row.forEach((cell, j) => {
      if (cell === 1) {
        ctx.fillRect(
          offset + j * moduleSize,
          offset + i * moduleSize,
          moduleSize,
          moduleSize
        );
      }
    });
  });

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