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.8);
  scene.add(ambientLight);

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

  const orangeLight = new THREE.PointLight(0xFF7A59, 0.8, 100);
  orangeLight.position.set(-3, 2, 3);
  scene.add(orangeLight);

  // Create large tablet/phone device (centerpiece)
  const deviceGroup = new THREE.Group();

  // Device frame
  const frameGeometry = new THREE.BoxGeometry(3.5, 4.5, 0.15);
  const frameMaterial = new THREE.MeshStandardMaterial({
    color: 0x4a5568,
    metalness: 0.7,
    roughness: 0.3,
  });
  const frame = new THREE.Mesh(frameGeometry, frameMaterial);
  deviceGroup.add(frame);

  // Device screen (white background)
  const screenGeometry = new THREE.BoxGeometry(3.3, 4.3, 0.1);
  const screenMaterial = new THREE.MeshStandardMaterial({
    color: 0xf8fafc,
    metalness: 0.1,
    roughness: 0.2,
  });
  const screen = new THREE.Mesh(screenGeometry, screenMaterial);
  screen.position.z = 0.08;
  deviceGroup.add(screen);

  // QR Code on screen
  const qrCodeTexture = createQRCodeTexture();
  const qrGeometry = new THREE.PlaneGeometry(2, 2);
  const qrMaterial = new THREE.MeshStandardMaterial({
    map: qrCodeTexture,
    transparent: false,
  });
  const qrCode = new THREE.Mesh(qrGeometry, qrMaterial);
  qrCode.position.set(0, 0.3, 0.16);
  deviceGroup.add(qrCode);

  // Orange frame around QR code
  const qrFrameShape = new THREE.Shape();
  qrFrameShape.moveTo(-1.1, -1.1);
  qrFrameShape.lineTo(1.1, -1.1);
  qrFrameShape.lineTo(1.1, 1.1);
  qrFrameShape.lineTo(-1.1, 1.1);
  qrFrameShape.lineTo(-1.1, -1.1);

  const qrFrameHole = new THREE.Path();
  qrFrameHole.moveTo(-1, -1);
  qrFrameHole.lineTo(1, -1);
  qrFrameHole.lineTo(1, 1);
  qrFrameHole.lineTo(-1, 1);
  qrFrameHole.lineTo(-1, -1);
  qrFrameShape.holes.push(qrFrameHole);

  const qrFrameGeometry = new THREE.ShapeGeometry(qrFrameShape);
  const qrFrameMaterial = new THREE.MeshStandardMaterial({
    color: 0xFF7A59,
    side: THREE.DoubleSide,
  });
  const qrFrame = new THREE.Mesh(qrFrameGeometry, qrFrameMaterial);
  qrFrame.position.set(0, 0.3, 0.17);
  deviceGroup.add(qrFrame);

  // Price text "$200"
  const priceGeometry = new THREE.PlaneGeometry(1.5, 0.5);
  const priceTexture = createTextTexture('$200', '#64748b', 72);
  const priceMaterial = new THREE.MeshBasicMaterial({
    map: priceTexture,
    transparent: true,
  });
  const priceText = new THREE.Mesh(priceGeometry, priceMaterial);
  priceText.position.set(0, -1.5, 0.16);
  deviceGroup.add(priceText);

  deviceGroup.position.set(0.5, 0, 0);
  deviceGroup.rotation.y = -0.1;
  scene.add(deviceGroup);

  // Create security shield
  const shieldGroup = new THREE.Group();

  const shieldShape = new THREE.Shape();
  shieldShape.moveTo(0, 0.8);
  shieldShape.lineTo(0.6, 0.6);
  shieldShape.lineTo(0.6, -0.3);
  shieldShape.quadraticCurveTo(0.6, -0.8, 0, -1);
  shieldShape.quadraticCurveTo(-0.6, -0.8, -0.6, -0.3);
  shieldShape.lineTo(-0.6, 0.6);
  shieldShape.lineTo(0, 0.8);

  const shieldExtrudeSettings = {
    depth: 0.15,
    bevelEnabled: true,
    bevelThickness: 0.02,
    bevelSize: 0.02,
    bevelSegments: 3,
  };

  const shieldGeometry = new THREE.ExtrudeGeometry(shieldShape, shieldExtrudeSettings);
  const shieldMaterial = new THREE.MeshStandardMaterial({
    color: 0xFF7A59,
    metalness: 0.3,
    roughness: 0.4,
  });
  const shield = new THREE.Mesh(shieldGeometry, shieldMaterial);
  shieldGroup.add(shield);

  // Checkmark on shield
  const checkShape = new THREE.Shape();
  checkShape.moveTo(-0.2, 0);
  checkShape.lineTo(-0.05, -0.2);
  checkShape.lineTo(0.3, 0.3);
  checkShape.lineTo(0.25, 0.35);
  checkShape.lineTo(-0.05, -0.1);
  checkShape.lineTo(-0.25, 0.05);
  checkShape.lineTo(-0.2, 0);

  const checkGeometry = new THREE.ShapeGeometry(checkShape);
  const checkMaterial = new THREE.MeshStandardMaterial({
    color: 0xffffff,
  });
  const check = new THREE.Mesh(checkGeometry, checkMaterial);
  check.position.z = 0.16;
  shieldGroup.add(check);

  shieldGroup.position.set(1.8, 2, 0.5);
  shieldGroup.scale.set(1.2, 1.2, 1.2);
  scene.add(shieldGroup);

  // Create floating coins
  const coins = [];
  const coinGeometry = new THREE.CylinderGeometry(0.35, 0.35, 0.12, 32);
  const coinMaterial = new THREE.MeshStandardMaterial({
    color: 0xFF7A59,
    metalness: 0.8,
    roughness: 0.2,
  });

  // Large coin with dollar sign
  const largeCoin = new THREE.Mesh(coinGeometry, coinMaterial);
  largeCoin.position.set(2.8, -1.5, 1);
  largeCoin.rotation.x = Math.PI / 2;
  largeCoin.scale.set(1.3, 1.3, 1.3);
  scene.add(largeCoin);

  // Dollar sign on coin
  const dollarTexture = createTextTexture('$', '#ffffff', 64);
  const dollarGeometry = new THREE.CircleGeometry(0.4, 32);
  const dollarMaterial = new THREE.MeshBasicMaterial({
    map: dollarTexture,
    transparent: true,
  });
  const dollarSign = new THREE.Mesh(dollarGeometry, dollarMaterial);
  dollarSign.position.set(2.8, -1.5, 1.17);
  scene.add(dollarSign);

  // Smaller floating coins
  const coinPositions = [
    { x: 2.2, y: 0.5, z: 1.5, scale: 0.7 },
    { x: 3.2, y: -0.8, z: 1.3, scale: 0.6 },
    { x: 2.5, y: 1.8, z: 1.2, scale: 0.5 },
  ];

  coinPositions.forEach((pos, index) => {
    const coin = new THREE.Mesh(coinGeometry, coinMaterial);
    coin.position.set(pos.x, pos.y, pos.z);
    coin.rotation.x = Math.PI / 2;
    coin.scale.set(pos.scale, pos.scale, pos.scale);
    coins.push({ mesh: coin, offset: index, baseY: pos.y });
    scene.add(coin);
  });

  // Create simplified person figure (left side)
  const personGroup = new THREE.Group();

  // Head
  const headGeometry = new THREE.SphereGeometry(0.3, 32, 32);
  const skinMaterial = new THREE.MeshStandardMaterial({
    color: 0xffdbac,
    roughness: 0.6,
  });
  const head = new THREE.Mesh(headGeometry, skinMaterial);
  head.position.y = 1.5;
  personGroup.add(head);

  // Body (torso)
  const bodyGeometry = new THREE.CylinderGeometry(0.35, 0.4, 1.2, 8);
  const jacketMaterial = new THREE.MeshStandardMaterial({
    color: 0xFF7A59,
    roughness: 0.5,
  });
  const body = new THREE.Mesh(bodyGeometry, jacketMaterial);
  body.position.y = 0.5;
  personGroup.add(body);

  // Arm holding phone
  const armGeometry = new THREE.CylinderGeometry(0.08, 0.1, 0.8, 8);
  const arm = new THREE.Mesh(armGeometry, jacketMaterial);
  arm.position.set(0.3, 0.8, 0.2);
  arm.rotation.z = -0.5;
  personGroup.add(arm);

  // Small phone in hand
  const handPhoneGeometry = new THREE.BoxGeometry(0.15, 0.25, 0.05);
  const handPhoneMaterial = new THREE.MeshStandardMaterial({
    color: 0x1e293b,
    metalness: 0.6,
  });
  const handPhone = new THREE.Mesh(handPhoneGeometry, handPhoneMaterial);
  handPhone.position.set(0.6, 1, 0.3);
  handPhone.rotation.z = -0.3;
  personGroup.add(handPhone);

  // Legs
  const legGeometry = new THREE.CylinderGeometry(0.12, 0.1, 1, 8);
  const pantsMaterial = new THREE.MeshStandardMaterial({
    color: 0x1e3a5f,
    roughness: 0.6,
  });
  const leftLeg = new THREE.Mesh(legGeometry, pantsMaterial);
  leftLeg.position.set(-0.15, -0.6, 0);
  personGroup.add(leftLeg);

  const rightLeg = new THREE.Mesh(legGeometry, pantsMaterial);
  rightLeg.position.set(0.15, -0.6, 0);
  personGroup.add(rightLeg);

  personGroup.position.set(-3, -1.5, 1);
  personGroup.scale.set(1.2, 1.2, 1.2);
  scene.add(personGroup);

  // Floating circles (decorative)
  const circles = [];
  const circleGeometry = new THREE.SphereGeometry(0.15, 16, 16);
  const circleMaterial = new THREE.MeshStandardMaterial({
    color: 0x94a3b8,
    transparent: true,
    opacity: 0.4,
  });

  const circlePositions = [
    { x: -2.5, y: 2.5, z: -1 },
    { x: -3.5, y: 1, z: 0.5 },
    { x: 3, y: 2.8, z: -0.5 },
    { x: -1, y: 3, z: -1 },
    { x: 3.5, y: 1.5, z: 0 },
  ];

  circlePositions.forEach((pos, index) => {
    const circle = new THREE.Mesh(circleGeometry, circleMaterial);
    circle.position.set(pos.x, pos.y, pos.z);
    const scale = 0.5 + Math.random() * 0.8;
    circle.scale.set(scale, scale, scale);
    circles.push({ mesh: circle, offset: index, baseY: pos.y });
    scene.add(circle);
  });

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

    // Gentle rotation of device
    deviceGroup.rotation.y = -0.1 + Math.sin(time * 0.5) * 0.05;
    deviceGroup.position.y = Math.sin(time * 0.8) * 0.1;

    // Shield bobbing
    shieldGroup.position.y = 2 + Math.sin(time * 1.2) * 0.1;
    shieldGroup.rotation.z = Math.sin(time * 0.6) * 0.05;

    // Large coin rotation
    largeCoin.rotation.y = time * 0.5;
    largeCoin.position.y = -1.5 + Math.sin(time * 1.5) * 0.1;

    // Small coins floating
    coins.forEach((coinData) => {
      const { mesh, offset, baseY } = coinData;
      mesh.position.y = baseY + Math.sin(time * 1.3 + offset) * 0.15;
      mesh.rotation.y = time * 0.8 + offset;
    });

    // Person slight movement
    personGroup.rotation.y = Math.sin(time * 0.4) * 0.03;
    personGroup.position.y = -1.5 + Math.sin(time * 1.1) * 0.05;

    // Circles floating
    circles.forEach((circleData) => {
      const { mesh, offset, baseY } = circleData;
      mesh.position.y = baseY + Math.sin(time * 0.9 + offset * 2) * 0.2;
      mesh.material.opacity = 0.3 + Math.sin(time + offset) * 0.1;
    });

    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 = '#4a5568';
  const moduleSize = 27;

  // QR code pattern (simplified but realistic)
  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;
}

/**
 * Create a text texture for labels
 */
function createTextTexture(text, color, fontSize) {
  const canvas = document.createElement('canvas');
  canvas.width = 512;
  canvas.height = 256;
  const ctx = canvas.getContext('2d');

  // Clear background
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // Draw text
  ctx.fillStyle = color;
  ctx.font = `bold ${fontSize}px Arial, sans-serif`;
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillText(text, canvas.width / 2, canvas.height / 2);

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