import React, { useRef, useMemo, useEffect, useState, useCallback } from 'react';
import { Canvas, useFrame, useLoader, useThree } from '@react-three/fiber';
import { OrbitControls, Grid, Text, Line } from '@react-three/drei';
import * as THREE from 'three';
import { useTurtleStore } from '../store/turtleStore';

// World interaction modes
const INTERACTION_MODE = {
  LOOK: 'look',    // Default orbit camera
  MOVE: 'move',    // Click block to send turtle there
  BUILD: 'build',  // Click face to place block preview
  SELECT: 'select' // Click-drag area selection
};

// Texture mapping for Minecraft blocks
const TEXTURE_MAP = {
  // Basic blocks
  'minecraft:stone': 'stone',
  'minecraft:cobblestone': 'cobblestone',
  'minecraft:dirt': 'dirt',
  'minecraft:grass_block': 'grass_block_side',
  'minecraft:sand': 'sand',
  'minecraft:red_sand': 'red_sand',
  'minecraft:gravel': 'gravel',
  'minecraft:bedrock': 'bedrock',
  'minecraft:oak_log': 'oak_log',
  'minecraft:oak_planks': 'oak_planks',
  'minecraft:glass': 'glass',
  
  // Logs
  'minecraft:spruce_log': 'spruce_log',
  'minecraft:birch_log': 'birch_log',
  'minecraft:jungle_log': 'jungle_log',
  'minecraft:acacia_log': 'acacia_log',
  'minecraft:dark_oak_log': 'dark_oak_log',
  'minecraft:mangrove_log': 'mangrove_log',
  'minecraft:cherry_log': 'cherry_log',
  
  // Planks
  'minecraft:spruce_planks': 'spruce_planks',
  'minecraft:birch_planks': 'birch_planks',
  'minecraft:jungle_planks': 'jungle_planks',
  'minecraft:acacia_planks': 'acacia_planks',
  'minecraft:dark_oak_planks': 'dark_oak_planks',
  
  // Stone variants
  'minecraft:granite': 'granite',
  'minecraft:polished_granite': 'polished_granite',
  'minecraft:diorite': 'diorite',
  'minecraft:polished_diorite': 'polished_diorite',
  'minecraft:andesite': 'andesite',
  'minecraft:polished_andesite': 'polished_andesite',
  'minecraft:deepslate': 'deepslate',
  'minecraft:cobbled_deepslate': 'cobbled_deepslate',
  'minecraft:tuff': 'tuff',
  'minecraft:calcite': 'calcite',
  'minecraft:dripstone_block': 'dripstone_block',
  'minecraft:smooth_stone': 'smooth_stone',
  'minecraft:sandstone': 'sandstone',
  'minecraft:red_sandstone': 'red_sandstone',
  
  // Ores (overworld)
  'minecraft:coal_ore': 'coal_ore',
  'minecraft:iron_ore': 'iron_ore',
  'minecraft:gold_ore': 'gold_ore',
  'minecraft:diamond_ore': 'diamond_ore',
  'minecraft:emerald_ore': 'emerald_ore',
  'minecraft:redstone_ore': 'redstone_ore',
  'minecraft:lapis_ore': 'lapis_ore',
  'minecraft:copper_ore': 'copper_ore',
  
  // Deepslate ores
  'minecraft:deepslate_coal_ore': 'deepslate_coal_ore',
  'minecraft:deepslate_iron_ore': 'deepslate_iron_ore',
  'minecraft:deepslate_gold_ore': 'deepslate_gold_ore',
  'minecraft:deepslate_diamond_ore': 'deepslate_diamond_ore',
  'minecraft:deepslate_emerald_ore': 'deepslate_emerald_ore',
  'minecraft:deepslate_redstone_ore': 'deepslate_redstone_ore',
  'minecraft:deepslate_lapis_ore': 'deepslate_lapis_ore',
  'minecraft:deepslate_copper_ore': 'deepslate_copper_ore',
  
  // Nether ores
  'minecraft:nether_gold_ore': 'nether_gold_ore',
  'minecraft:nether_quartz_ore': 'nether_quartz_ore',
  'minecraft:ancient_debris': 'ancient_debris_side',
  
  // Special blocks
  'minecraft:obsidian': 'obsidian',
  'minecraft:crying_obsidian': 'crying_obsidian',
  'minecraft:netherrack': 'netherrack',
  'minecraft:soul_sand': 'soul_sand',
  'minecraft:soul_soil': 'soul_soil',
  'minecraft:glowstone': 'glowstone',
  'minecraft:end_stone': 'end_stone',
  'minecraft:water': 'water_still',
  'minecraft:lava': 'lava_still',
  'minecraft:magma_block': 'magma',
  'minecraft:amethyst_block': 'amethyst_block',
  'minecraft:budding_amethyst': 'budding_amethyst',
  'minecraft:moss_block': 'moss_block',
  'minecraft:clay': 'clay',
  'minecraft:terracotta': 'terracotta',
  'minecraft:packed_ice': 'packed_ice',
  'minecraft:blue_ice': 'blue_ice',
  'minecraft:ice': 'ice',
  'minecraft:snow_block': 'snow',
  'minecraft:mycelium': 'mycelium_side',
  'minecraft:podzol': 'podzol_side',
  
  // Building blocks
  'minecraft:bricks': 'bricks',
  'minecraft:stone_bricks': 'stone_bricks',
  'minecraft:cracked_stone_bricks': 'cracked_stone_bricks',
  'minecraft:mossy_cobblestone': 'mossy_cobblestone',
  'minecraft:mossy_stone_bricks': 'mossy_stone_bricks',
  'minecraft:prismarine': 'prismarine',
  'minecraft:dark_prismarine': 'dark_prismarine',
  'minecraft:purpur_block': 'purpur_block',
  'minecraft:nether_bricks': 'nether_bricks',
  'minecraft:red_nether_bricks': 'red_nether_bricks',
  'minecraft:quartz_block': 'quartz_block_side',
  'minecraft:basalt': 'basalt_side',
  'minecraft:polished_basalt': 'polished_basalt_side',
  'minecraft:blackstone': 'blackstone',
  'minecraft:polished_blackstone': 'polished_blackstone',
  'minecraft:gilded_blackstone': 'gilded_blackstone',
  
  // Functional blocks
  'minecraft:crafting_table': 'crafting_table_front',
  'minecraft:furnace': 'furnace_front',
  'minecraft:chest': 'barrel_side',
  'minecraft:barrel': 'barrel_side',
  'minecraft:bookshelf': 'bookshelf',
  'minecraft:tnt': 'tnt_side',
  'minecraft:spawner': 'spawner',
};

// Blocks with different top/side/bottom textures
const MULTI_FACE_BLOCKS = {
  'minecraft:grass_block': { top: 'grass_block_top', side: 'grass_block_side', bottom: 'dirt' },
  'minecraft:mycelium': { top: 'mycelium_top', side: 'mycelium_side', bottom: 'dirt' },
  'minecraft:podzol': { top: 'podzol_top', side: 'podzol_side', bottom: 'dirt' },
  'minecraft:oak_log': { top: 'oak_log_top', side: 'oak_log', bottom: 'oak_log_top' },
  'minecraft:spruce_log': { top: 'spruce_log_top', side: 'spruce_log', bottom: 'spruce_log_top' },
  'minecraft:birch_log': { top: 'birch_log_top', side: 'birch_log', bottom: 'birch_log_top' },
  'minecraft:jungle_log': { top: 'jungle_log_top', side: 'jungle_log', bottom: 'jungle_log_top' },
  'minecraft:acacia_log': { top: 'acacia_log_top', side: 'acacia_log', bottom: 'acacia_log_top' },
  'minecraft:dark_oak_log': { top: 'dark_oak_log_top', side: 'dark_oak_log', bottom: 'dark_oak_log_top' },
  'minecraft:sandstone': { top: 'sandstone_top', side: 'sandstone', bottom: 'sandstone_bottom' },
  'minecraft:red_sandstone': { top: 'red_sandstone_top', side: 'red_sandstone', bottom: 'red_sandstone_bottom' },
  'minecraft:crafting_table': { top: 'crafting_table_top', side: 'crafting_table_front', bottom: 'oak_planks' },
  'minecraft:furnace': { top: 'furnace_top', side: 'furnace_front', bottom: 'furnace_top' },
  'minecraft:tnt': { top: 'tnt_top', side: 'tnt_side', bottom: 'tnt_bottom' },
  'minecraft:quartz_block': { top: 'quartz_block_top', side: 'quartz_block_side', bottom: 'quartz_block_bottom' },
  'minecraft:basalt': { top: 'basalt_top', side: 'basalt_side', bottom: 'basalt_top' },
  'minecraft:barrel': { top: 'barrel_top', side: 'barrel_side', bottom: 'barrel_bottom' },
};

// Function to get texture URL from a Minecraft texture service
function getTextureURL(blockName) {
  const textureName = TEXTURE_MAP[blockName] || 'stone';
  // Using a public Minecraft texture API
  return `https://raw.githubusercontent.com/InventivetalentDev/minecraft-assets/1.20.4/assets/minecraft/textures/block/${textureName}.png`;
}

// Custom hook to load multiple textures (including multi-face)
function useMinecraftTextures(blocks) {
  const [textures, setTextures] = useState({});
  const [multiFaceTextures, setMultiFaceTextures] = useState({});
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const textureLoader = new THREE.TextureLoader();
    const uniqueBlocks = [...new Set(blocks.map(b => b.name))];
    const loadedTextures = {};
    const loadedMultiFace = {};
    let totalToLoad = 0;
    let loadedCount = 0;

    if (uniqueBlocks.length === 0) {
      setLoading(false);
      return;
    }

    // Collect all unique texture names to load
    const textureNames = new Set();
    uniqueBlocks.forEach(blockName => {
      const multiFace = MULTI_FACE_BLOCKS[blockName];
      if (multiFace) {
        textureNames.add(multiFace.top);
        textureNames.add(multiFace.side);
        textureNames.add(multiFace.bottom);
      } else {
        const textureName = TEXTURE_MAP[blockName] || null;
        if (textureName) textureNames.add(textureName);
      }
    });

    totalToLoad = textureNames.size;
    if (totalToLoad === 0) {
      setLoading(false);
      return;
    }

    const loadedTexturesByName = {};
    
    const checkDone = () => {
      loadedCount++;
      if (loadedCount >= totalToLoad) {
        // Build per-block texture maps
        uniqueBlocks.forEach(blockName => {
          const multiFace = MULTI_FACE_BLOCKS[blockName];
          if (multiFace) {
            const top = loadedTexturesByName[multiFace.top];
            const side = loadedTexturesByName[multiFace.side];
            const bottom = loadedTexturesByName[multiFace.bottom];
            if (top && side && bottom) {
              loadedMultiFace[blockName] = [side, side, top, bottom, side, side];
            } else {
              // Fallback to single texture
              loadedTextures[blockName] = side || top || bottom || null;
            }
          } else {
            const textureName = TEXTURE_MAP[blockName];
            if (textureName && loadedTexturesByName[textureName]) {
              loadedTextures[blockName] = loadedTexturesByName[textureName];
            }
          }
        });
        
        setTextures(loadedTextures);
        setMultiFaceTextures(loadedMultiFace);
        setLoading(false);
      }
    };

    textureNames.forEach(textureName => {
      const url = `https://raw.githubusercontent.com/InventivetalentDev/minecraft-assets/1.20.4/assets/minecraft/textures/block/${textureName}.png`;
      
      textureLoader.load(
        url,
        (texture) => {
          texture.magFilter = THREE.NearestFilter;
          texture.minFilter = THREE.NearestFilter;
          texture.wrapS = THREE.RepeatWrapping;
          texture.wrapT = THREE.RepeatWrapping;
          texture.colorSpace = THREE.SRGBColorSpace;
          loadedTexturesByName[textureName] = texture;
          checkDone();
        },
        undefined,
        () => {
          checkDone();
        }
      );
    });
  }, [blocks]);

  return { textures, multiFaceTextures, loading };
}

// Minecraft-style turtle model
function TurtleModel({ turtle, isSelected, onClick }) {
  const groupRef = useRef();
  const { position, facing, mode, state } = turtle;
  const activeMode = state || mode || 'idle';

  useFrame((state) => {
    if (groupRef.current && isSelected) {
      groupRef.current.children[0].position.y = Math.sin(state.clock.elapsedTime * 2) * 0.05;
    }
  });

  if (!position) return null;

  // Calculate rotation based on facing (0=North(-Z), 1=East(+X), 2=South(+Z), 3=West(-X))
  const facingRotations = [Math.PI, -Math.PI/2, 0, Math.PI/2];
  const rotation = facing !== undefined ? [0, facingRotations[facing], 0] : [0, 0, 0];

  const color = activeMode === 'mining' ? '#4ade80' :
                activeMode === 'exploring' ? '#60a5fa' :
                activeMode === 'returning' || activeMode === 'goHome' ? '#f59e0b' :
                activeMode === 'refueling' ? '#ef4444' :
                activeMode === 'farming' ? '#22c55e' :
                activeMode === 'dumpInventory' || activeMode === 'dumping' ? '#a855f7' :
                activeMode === 'moving' ? '#06b6d4' :
                '#9ca3af';

  return (
    <group ref={groupRef} position={[position.x, position.y, position.z]} rotation={rotation} onClick={onClick}>
      <group>
        {/* Main shell body - rounded edges */}
        <mesh position={[0, 0.2, 0]} castShadow>
          <boxGeometry args={[0.9, 0.6, 1.0]} />
          <meshStandardMaterial 
            color={color} 
            emissive={color}
            emissiveIntensity={isSelected ? 0.5 : 0.25}
            roughness={0.3}
            metalness={0.2}
          />
        </mesh>
        
        {/* Shell pattern - hexagonal plates */}
        <mesh position={[0, 0.5, 0]}>
          <boxGeometry args={[0.5, 0.05, 0.6]} />
          <meshStandardMaterial color="#333" roughness={0.4} metalness={0.6} />
        </mesh>
        <mesh position={[-0.25, 0.5, 0.3]}>
          <boxGeometry args={[0.3, 0.05, 0.3]} />
          <meshStandardMaterial color="#333" roughness={0.4} metalness={0.6} />
        </mesh>
        <mesh position={[0.25, 0.5, 0.3]}>
          <boxGeometry args={[0.3, 0.05, 0.3]} />
          <meshStandardMaterial color="#333" roughness={0.4} metalness={0.6} />
        </mesh>
        <mesh position={[-0.25, 0.5, -0.3]}>
          <boxGeometry args={[0.3, 0.05, 0.3]} />
          <meshStandardMaterial color="#333" roughness={0.4} metalness={0.6} />
        </mesh>
        <mesh position={[0.25, 0.5, -0.3]}>
          <boxGeometry args={[0.3, 0.05, 0.3]} />
          <meshStandardMaterial color="#333" roughness={0.4} metalness={0.6} />
        </mesh>
        
        {/* Head with visor */}
        <mesh position={[0, 0.15, 0.6]} castShadow>
          <boxGeometry args={[0.55, 0.4, 0.35]} />
          <meshStandardMaterial color={color} roughness={0.3} metalness={0.1} />
        </mesh>
        
        {/* Visor/Face plate */}
        <mesh position={[0, 0.2, 0.78]}>
          <boxGeometry args={[0.45, 0.25, 0.02]} />
          <meshStandardMaterial 
            color="#1a1a1a" 
            emissive="#111" 
            roughness={0.1} 
            metalness={0.9}
          />
        </mesh>
        
        {/* Eyes/LED indicators */}
        <mesh position={[-0.13, 0.22, 0.79]}>
          <boxGeometry args={[0.08, 0.08, 0.01]} />
          <meshStandardMaterial 
            color="#00ff00" 
            emissive={activeMode === 'mining' ? "#00ff00" : activeMode === 'returning' || activeMode === 'goHome' ? "#ffaa00" : "#00aaff"} 
            emissiveIntensity={1.5}
            toneMapped={false}
          />
        </mesh>
        <mesh position={[0.13, 0.22, 0.79]}>
          <boxGeometry args={[0.08, 0.08, 0.01]} />
          <meshStandardMaterial 
            color="#00ff00" 
            emissive={activeMode === 'mining' ? "#00ff00" : activeMode === 'returning' || activeMode === 'goHome' ? "#ffaa00" : "#00aaff"} 
            emissiveIntensity={1.5}
            toneMapped={false}
          />
        </mesh>
        
        {/* LED glow */}
        <pointLight 
          position={[0, 0.2, 0.85]} 
          color={activeMode === 'mining' ? "#00ff00" : activeMode === 'returning' || activeMode === 'goHome' ? "#ffaa00" : "#00aaff"}
          intensity={0.5} 
          distance={2} 
        />
        
        {/* Legs - more mechanical looking */}
        <mesh position={[-0.32, -0.15, 0.3]} castShadow>
          <boxGeometry args={[0.18, 0.25, 0.18]} />
          <meshStandardMaterial color="#555" roughness={0.4} metalness={0.7} />
        </mesh>
        <mesh position={[0.32, -0.15, 0.3]} castShadow>
          <boxGeometry args={[0.18, 0.25, 0.18]} />
          <meshStandardMaterial color="#555" roughness={0.4} metalness={0.7} />
        </mesh>
        <mesh position={[-0.32, -0.15, -0.3]} castShadow>
          <boxGeometry args={[0.18, 0.25, 0.18]} />
          <meshStandardMaterial color="#555" roughness={0.4} metalness={0.7} />
        </mesh>
        <mesh position={[0.32, -0.15, -0.3]} castShadow>
          <boxGeometry args={[0.18, 0.25, 0.18]} />
          <meshStandardMaterial color="#555" roughness={0.4} metalness={0.7} />
        </mesh>
        
        {/* Feet */}
        <mesh position={[-0.32, -0.35, 0.3]}>
          <boxGeometry args={[0.22, 0.08, 0.25]} />
          <meshStandardMaterial color="#444" roughness={0.5} metalness={0.6} />
        </mesh>
        <mesh position={[0.32, -0.35, 0.3]}>
          <boxGeometry args={[0.22, 0.08, 0.25]} />
          <meshStandardMaterial color="#444" roughness={0.5} metalness={0.6} />
        </mesh>
        <mesh position={[-0.32, -0.35, -0.3]}>
          <boxGeometry args={[0.22, 0.08, 0.25]} />
          <meshStandardMaterial color="#444" roughness={0.5} metalness={0.6} />
        </mesh>
        <mesh position={[0.32, -0.35, -0.3]}>
          <boxGeometry args={[0.22, 0.08, 0.25]} />
          <meshStandardMaterial color="#444" roughness={0.5} metalness={0.6} />
        </mesh>
        
        {/* Tool/Mining arm - only show when mining */}
        {activeMode === 'mining' && (
          <>
            <mesh position={[0, 0.1, 0.7]}>
              <boxGeometry args={[0.1, 0.1, 0.3]} />
              <meshStandardMaterial color="#888" metalness={0.8} roughness={0.2} />
            </mesh>
            <mesh position={[0, 0.1, 0.9]}>
              <boxGeometry args={[0.15, 0.15, 0.1]} />
              <meshStandardMaterial 
                color="#ff6b00" 
                emissive="#ff6b00" 
                emissiveIntensity={0.5}
                metalness={0.7}
              />
            </mesh>
          </>
        )}
        
        {/* Antenna */}
        <mesh position={[0, 0.5, -0.2]}>
          <cylinderGeometry args={[0.02, 0.02, 0.4, 8]} />
          <meshStandardMaterial color="#666" metalness={0.8} />
        </mesh>
        <mesh position={[0, 0.72, -0.2]}>
          <sphereGeometry args={[0.06, 8, 8]} />
          <meshStandardMaterial 
            color="#ff0000" 
            emissive="#ff0000" 
            emissiveIntensity={0.8}
          />
        </mesh>
        
        {/* Ambient glow around turtle */}
        <pointLight 
          position={[0, 0.2, 0]} 
          color={color}
          intensity={isSelected ? 1 : 0.3} 
          distance={3} 
        />
      </group>
      
      {/* Selection indicator */}
      {isSelected && (
        <>
          <mesh position={[0, 1.3, 0]}>
            <coneGeometry args={[0.25, 0.4, 4]} />
            <meshStandardMaterial 
              color="#ffffff" 
              emissive="#ffffff" 
              emissiveIntensity={1.2}
              transparent
              opacity={0.8}
            />
          </mesh>
          
          {/* Animated selection ring */}
          <mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.4, 0]}>
            <ringGeometry args={[1.1, 1.3, 64]} />
            <meshBasicMaterial 
              color={color} 
              side={THREE.DoubleSide} 
              transparent 
              opacity={0.6} 
            />
          </mesh>
        </>
      )}

      {/* Turtle ID label */}
      <Text
        position={[0, 1.6, 0]}
        fontSize={0.35}
        color="white"
        anchorX="center"
        anchorY="middle"
      >
        🐢 {turtle.turtleID}
      </Text>
    </group>
  );
}

// Path trail component
function PathTrail({ turtle }) {
  const { position, homePosition } = turtle;

  if (!position || !homePosition) return null;

  const points = [
    new THREE.Vector3(position.x, position.y, position.z),
    new THREE.Vector3(homePosition.x, homePosition.y, homePosition.z)
  ];

  return (
    <Line
      points={points}
      color="#60a5fa"
      lineWidth={2}
      transparent
      opacity={0.3}
      dashed
      dashScale={2}
    />
  );
}

// Get color and texture info for block type
function getBlockAppearance(blockName) {
  if (!blockName) return { color: '#888', pattern: 'solid' };
  
  const name = blockName.toLowerCase();
  
  // Ores - bright colors with sparkle
  if (name.includes('diamond')) return { color: '#00ffff', pattern: 'ore', emissive: '#00ffff', intensity: 0.3 };
  if (name.includes('emerald')) return { color: '#00ff00', pattern: 'ore', emissive: '#00ff00', intensity: 0.3 };
  if (name.includes('gold')) return { color: '#ffd700', pattern: 'ore', emissive: '#ffd700', intensity: 0.2 };
  if (name.includes('iron')) return { color: '#d4d4d4', pattern: 'ore' };
  if (name.includes('coal')) return { color: '#1a1a1a', pattern: 'ore' };
  if (name.includes('redstone')) return { color: '#ff0000', pattern: 'ore', emissive: '#ff0000', intensity: 0.2 };
  if (name.includes('lapis')) return { color: '#1e40af', pattern: 'ore' };
  if (name.includes('copper')) return { color: '#ff8c00', pattern: 'ore' };
  
  // Common blocks - textured
  if (name.includes('stone') && !name.includes('cobble')) return { color: '#7f7f7f', pattern: 'stone' };
  if (name.includes('cobblestone')) return { color: '#808080', pattern: 'cobble' };
  if (name.includes('dirt')) return { color: '#8b4513', pattern: 'dirt' };
  if (name.includes('grass')) return { color: '#228b22', pattern: 'grass' };
  if (name.includes('sand')) return { color: '#f4a460', pattern: 'sand' };
  if (name.includes('gravel')) return { color: '#808080', pattern: 'gravel' };
  if (name.includes('bedrock')) return { color: '#222', pattern: 'solid' };
  if (name.includes('obsidian')) return { color: '#1a0033', pattern: 'solid' };
  if (name.includes('netherrack')) return { color: '#8b0000', pattern: 'netherrack' };
  
  return { color: '#666666', pattern: 'solid' };
}

// WorldBlocks component using chunked InstancedMesh rendering for performance
function WorldBlocks({ blocks, interactionMode, selectedTurtleId, onBlockClick }) {
  const [hoveredBlock, setHoveredBlock] = useState(null);
  const { textures, multiFaceTextures, loading } = useMinecraftTextures(blocks);
  
  // Chunk size (16x16 like Minecraft)
  const CHUNK_SIZE = 16;
  
  // Group blocks into chunks and by block type within each chunk
  const chunks = useMemo(() => {
    const chunkMap = new Map();
    
    blocks.forEach(block => {
      const chunkX = Math.floor(block.x / CHUNK_SIZE);
      const chunkZ = Math.floor(block.z / CHUNK_SIZE);
      const chunkKey = `${chunkX},${chunkZ}`;
      
      if (!chunkMap.has(chunkKey)) {
        chunkMap.set(chunkKey, { key: chunkKey, chunkX, chunkZ, blocksByType: new Map() });
      }
      
      const chunk = chunkMap.get(chunkKey);
      if (!chunk.blocksByType.has(block.name)) {
        chunk.blocksByType.set(block.name, []);
      }
      chunk.blocksByType.get(block.name).push(block);
    });
    
    return Array.from(chunkMap.values());
  }, [blocks]);

  if (loading) {
    return <Text position={[0, 5, 0]} fontSize={0.5} color="white">Loading textures...</Text>;
  }

  return (
    <group>
      {chunks.map(chunk => (
        <ChunkMesh
          key={chunk.key}
          chunk={chunk}
          textures={textures}
          multiFaceTextures={multiFaceTextures}
          hoveredBlock={hoveredBlock}
          setHoveredBlock={setHoveredBlock}
          interactionMode={interactionMode}
          selectedTurtleId={selectedTurtleId}
          onBlockClick={onBlockClick}
        />
      ))}
      
      {/* Hover label overlay */}
      {hoveredBlock && (
        <Text
          position={[hoveredBlock.x, hoveredBlock.y + 1.0, hoveredBlock.z]}
          fontSize={0.3}
          color="white"
          anchorX="center"
          anchorY="middle"
          outlineWidth={0.05}
          outlineColor="#000000"
        >
          {hoveredBlock.name.replace('minecraft:', '').replace(/_/g, ' ').toUpperCase()}
          {'\n'}
          {`(${hoveredBlock.x}, ${hoveredBlock.y}, ${hoveredBlock.z})`}
        </Text>
      )}
    </group>
  );
}

// Individual chunk rendered with InstancedMesh per block type
function ChunkMesh({ chunk, textures, multiFaceTextures, hoveredBlock, setHoveredBlock, interactionMode, selectedTurtleId, onBlockClick }) {
  return (
    <group>
      {Array.from(chunk.blocksByType.entries()).map(([blockName, blockList]) => (
        <BlockTypeInstances
          key={`${chunk.key}-${blockName}`}
          blockName={blockName}
          blockList={blockList}
          textures={textures}
          multiFaceTextures={multiFaceTextures}
          hoveredBlock={hoveredBlock}
          setHoveredBlock={setHoveredBlock}
          interactionMode={interactionMode}
          selectedTurtleId={selectedTurtleId}
          onBlockClick={onBlockClick}
        />
      ))}
    </group>
  );
}

// InstancedMesh for all blocks of one type within a chunk
function BlockTypeInstances({ blockName, blockList, textures, multiFaceTextures, hoveredBlock, setHoveredBlock, interactionMode, selectedTurtleId, onBlockClick }) {
  const meshRef = useRef();
  const appearance = useMemo(() => getBlockAppearance(blockName), [blockName]);
  const texture = textures[blockName];
  const multiFace = multiFaceTextures[blockName];
  const tempMatrix = useMemo(() => new THREE.Matrix4(), []);
  const tempColor = useMemo(() => new THREE.Color(), []);
  
  // Set instance matrices
  useEffect(() => {
    if (!meshRef.current) return;
    
    blockList.forEach((block, i) => {
      tempMatrix.setPosition(block.x, block.y, block.z);
      meshRef.current.setMatrixAt(i, tempMatrix);
      // Default color (white for textured, appearance color for untextured)
      tempColor.set(texture || multiFace ? '#ffffff' : appearance.color);
      meshRef.current.setColorAt(i, tempColor);
    });
    
    meshRef.current.instanceMatrix.needsUpdate = true;
    if (meshRef.current.instanceColor) meshRef.current.instanceColor.needsUpdate = true;
  }, [blockList, texture, multiFace, appearance, tempMatrix, tempColor]);
  
  // Update hover highlighting
  useEffect(() => {
    if (!meshRef.current || !meshRef.current.instanceColor) return;
    
    blockList.forEach((block, i) => {
      const isHovered = hoveredBlock && 
        hoveredBlock.x === block.x && 
        hoveredBlock.y === block.y && 
        hoveredBlock.z === block.z;
      
      if (isHovered) {
        tempColor.set('#ffffff');
        meshRef.current.setColorAt(i, tempColor);
      } else {
        tempColor.set(texture || multiFace ? '#ffffff' : appearance.color);
        meshRef.current.setColorAt(i, tempColor);
      }
    });
    meshRef.current.instanceColor.needsUpdate = true;
  }, [hoveredBlock, blockList, texture, multiFace, appearance, tempColor]);
  
  const handlePointerMove = useCallback((e) => {
    e.stopPropagation();
    const instanceId = e.instanceId;
    if (instanceId !== undefined && instanceId < blockList.length) {
      setHoveredBlock(blockList[instanceId]);
    }
  }, [blockList, setHoveredBlock]);
  
  const handlePointerOut = useCallback(() => {
    setHoveredBlock(null);
  }, [setHoveredBlock]);
  
  const handleClick = useCallback((e) => {
    e.stopPropagation();
    const instanceId = e.instanceId;
    if (instanceId !== undefined && instanceId < blockList.length) {
      const block = blockList[instanceId];
      
      if (interactionMode === INTERACTION_MODE.MOVE && selectedTurtleId && onBlockClick) {
        // In MOVE mode, click block surface to send turtle to adjacent position
        const normal = e.face?.normal;
        const target = {
          x: block.x + (normal?.x || 0),
          y: block.y + (normal?.y || 0),
          z: block.z + (normal?.z || 0)
        };
        onBlockClick({ type: 'move', target, block });
      } else if (interactionMode === INTERACTION_MODE.BUILD && onBlockClick) {
        const normal = e.face?.normal;
        const target = {
          x: block.x + (normal?.x || 0),
          y: block.y + (normal?.y || 0),
          z: block.z + (normal?.z || 0)
        };
        onBlockClick({ type: 'build', target, block });
      } else if (interactionMode === INTERACTION_MODE.SELECT && onBlockClick) {
        onBlockClick({ type: 'select', block });
      }
    }
  }, [blockList, interactionMode, selectedTurtleId, onBlockClick]);
  
  // For multi-face blocks, we can't easily use InstancedMesh with different material per face,
  // so we fall back to individual meshes for those (they're fewer — grass, logs, etc.)
  if (multiFace) {
    return (
      <group>
        {blockList.map((block) => {
          const blockKey = `${block.x},${block.y},${block.z}`;
          const isHovered = hoveredBlock && 
            hoveredBlock.x === block.x && 
            hoveredBlock.y === block.y && 
            hoveredBlock.z === block.z;
          return (
            <mesh
              key={blockKey}
              position={[block.x, block.y, block.z]}
              onPointerOver={(e) => { e.stopPropagation(); setHoveredBlock(block); }}
              onPointerOut={() => setHoveredBlock(null)}
              onClick={(e) => {
                e.stopPropagation();
                if (interactionMode === INTERACTION_MODE.MOVE && selectedTurtleId && onBlockClick) {
                  const normal = e.face?.normal;
                  onBlockClick({ type: 'move', target: { x: block.x + (normal?.x || 0), y: block.y + (normal?.y || 0), z: block.z + (normal?.z || 0) }, block });
                } else if (interactionMode === INTERACTION_MODE.BUILD && onBlockClick) {
                  const normal = e.face?.normal;
                  onBlockClick({ type: 'build', target: { x: block.x + (normal?.x || 0), y: block.y + (normal?.y || 0), z: block.z + (normal?.z || 0) }, block });
                } else if (interactionMode === INTERACTION_MODE.SELECT && onBlockClick) {
                  onBlockClick({ type: 'select', block });
                }
              }}
            >
              <boxGeometry args={[1.0, 1.0, 1.0]} />
              {multiFace.map((faceTexture, i) => (
                <meshStandardMaterial
                  key={i}
                  attach={`material-${i}`}
                  map={faceTexture}
                  color="#ffffff"
                  emissive={appearance.emissive || '#000000'}
                  emissiveIntensity={isHovered ? 0.25 : (appearance.intensity || 0.02)}
                  roughness={0.8}
                  metalness={0.0}
                  transparent
                  opacity={isHovered ? 0.98 : 0.9}
                />
              ))}
            </mesh>
          );
        })}
      </group>
    );
  }
  
  return (
    <instancedMesh
      ref={meshRef}
      args={[null, null, blockList.length]}
      onPointerMove={handlePointerMove}
      onPointerOut={handlePointerOut}
      onClick={handleClick}
    >
      <boxGeometry args={[1.0, 1.0, 1.0]} />
      <meshStandardMaterial
        map={texture}
        color={texture ? '#ffffff' : appearance.color}
        emissive={appearance.emissive || appearance.color}
        emissiveIntensity={appearance.intensity || 0.05}
        roughness={appearance.pattern === 'ore' ? 0.4 : 0.8}
        metalness={appearance.pattern === 'ore' ? 0.2 : 0.0}
        transparent
        opacity={0.9}
      />
    </instancedMesh>
  );
}

// Path trail component (old version removed above)
function OldPathTrail({ turtle }) {
  const { position, homePosition } = turtle;

  if (!position || !homePosition) return null;

  const points = [
    new THREE.Vector3(position.x, position.y, position.z),
    new THREE.Vector3(homePosition.x, homePosition.y, homePosition.z)
  ];

  return (
    <Line
      points={points}
      color="#60a5fa"
      lineWidth={2}
      dashed
      dashScale={2}
      transparent
      opacity={0.5}
    />
  );
}

// Home marker component
function HomeMarker({ position }) {
  if (!position) return null;

  return (
    <group position={[position.x, position.y, position.z]}>
      <mesh>
        <cylinderGeometry args={[1, 0.5, 0.5, 6]} />
        <meshStandardMaterial color="#10b981" emissive="#10b981" emissiveIntensity={0.3} />
      </mesh>
      <Text
        position={[0, 1.2, 0]}
        fontSize={0.5}
        color="#10b981"
        anchorX="center"
        anchorY="middle"
      >
        HOME
      </Text>
    </group>
  );
}

// Mining area wireframe component
function MiningArea({ area, turtle, isSelected, onClick }) {
  const meshRef = useRef();
  const [hovered, setHovered] = useState(false);

  // Calculate dimensions
  const width = Math.abs(area.endX - area.startX) + 1;
  const height = Math.abs(area.endY - area.startY) + 1;
  const depth = Math.abs(area.endZ - area.startZ) + 1;

  // Calculate center position
  const centerX = (area.startX + area.endX) / 2;
  const centerY = (area.startY + area.endY) / 2;
  const centerZ = (area.startZ + area.endZ) / 2;

  // Color based on turtle or status
  const getColor = () => {
    if (area.status === 'completed') return '#10b981'; // green
    if (area.status === 'mining') return '#f59e0b'; // orange
    if (turtle) return turtle.color || '#3b82f6'; // turtle color or blue
    return '#6366f1'; // default purple
  };

  const color = getColor();
  const opacity = isSelected ? 0.3 : hovered ? 0.2 : 0.1;
  const lineWidth = isSelected ? 2.5 : hovered ? 2 : 1.5;

  // Animate rotation slightly
  useFrame((state) => {
    if (meshRef.current && isSelected) {
      meshRef.current.rotation.y = Math.sin(state.clock.elapsedTime * 0.5) * 0.1;
    }
  });

  return (
    <group 
      position={[centerX, centerY, centerZ]}
      onClick={onClick}
      onPointerOver={() => setHovered(true)}
      onPointerOut={() => setHovered(false)}
      ref={meshRef}
    >
      {/* Wireframe box */}
      <lineSegments>
        <edgesGeometry args={[new THREE.BoxGeometry(width, height, depth)]} />
        <lineBasicMaterial color={color} linewidth={lineWidth} />
      </lineSegments>

      {/* Semi-transparent fill */}
      <mesh>
        <boxGeometry args={[width, height, depth]} />
        <meshStandardMaterial
          color={color}
          transparent
          opacity={opacity}
          side={THREE.DoubleSide}
        />
      </mesh>

      {/* Label */}
      <Text
        position={[0, height / 2 + 1, 0]}
        fontSize={0.5}
        color={color}
        anchorX="center"
        anchorY="middle"
      >
        {area.areaName || `Area ${area.areaID}`}
      </Text>

      {/* Dimensions label */}
      <Text
        position={[0, height / 2 + 0.3, 0]}
        fontSize={0.3}
        color="white"
        anchorX="center"
        anchorY="middle"
      >
        {width}×{height}×{depth}
      </Text>

      {/* Status indicator */}
      {area.status === 'mining' && (
        <mesh position={[0, height / 2 + 1.8, 0]}>
          <sphereGeometry args={[0.2, 16, 16]} />
          <meshStandardMaterial color="#f59e0b" emissive="#f59e0b" emissiveIntensity={0.8} />
        </mesh>
      )}
    </group>
  );
}

// Player marker component
function PlayerMarker({ player }) {
  const meshRef = useRef();
  
  // Bobbing animation
  useFrame((state) => {
    if (meshRef.current) {
      meshRef.current.position.y = player.position.y + Math.sin(state.clock.elapsedTime * 2) * 0.1;
    }
  });

  return (
    <group position={[player.position.x, player.position.y, player.position.z]}>
      {/* Player head (Steve-like) */}
      <mesh ref={meshRef} position={[0, 1, 0]}>
        <boxGeometry args={[0.6, 0.6, 0.6]} />
        <meshStandardMaterial 
          color="#8b7355"
          emissive="#4a90e2"
          emissiveIntensity={0.3}
        />
      </mesh>

      {/* Body */}
      <mesh position={[0, 0.2, 0]}>
        <boxGeometry args={[0.6, 0.9, 0.3]} />
        <meshStandardMaterial color="#4a90e2" />
      </mesh>

      {/* Glow effect */}
      <pointLight color="#4a90e2" intensity={1} distance={3} />

      {/* Label */}
      <Text
        position={[0, 2, 0]}
        fontSize={0.4}
        color="#4a90e2"
        anchorX="center"
        anchorY="middle"
        outlineWidth={0.05}
        outlineColor="#000000"
      >
        Player {player.playerID}
      </Text>
    </group>
  );
}

// Move target preview (ghost block showing where turtle will go)
function MoveTargetPreview({ position }) {
  const meshRef = useRef();
  
  useFrame((state) => {
    if (meshRef.current) {
      meshRef.current.position.y = position.y + Math.sin(state.clock.elapsedTime * 3) * 0.1;
      meshRef.current.material.opacity = 0.3 + Math.sin(state.clock.elapsedTime * 2) * 0.15;
    }
  });

  return (
    <group>
      <mesh ref={meshRef} position={[position.x, position.y, position.z]}>
        <boxGeometry args={[0.8, 0.8, 0.8]} />
        <meshStandardMaterial 
          color="#3b82f6" 
          transparent 
          opacity={0.4}
          emissive="#3b82f6"
          emissiveIntensity={0.5}
        />
      </mesh>
      <Text
        position={[position.x, position.y + 1.2, position.z]}
        fontSize={0.3}
        color="#3b82f6"
        anchorX="center"
        anchorY="middle"
        outlineWidth={0.04}
        outlineColor="#000000"
      >
        MOVE HERE
      </Text>
    </group>
  );
}

// Build preview (ghost block showing where block will be placed)
function BuildPreview({ position }) {
  const meshRef = useRef();
  
  useFrame((state) => {
    if (meshRef.current) {
      meshRef.current.material.opacity = 0.3 + Math.sin(state.clock.elapsedTime * 2) * 0.15;
    }
  });

  return (
    <mesh ref={meshRef} position={[position.x, position.y, position.z]}>
      <boxGeometry args={[1.0, 1.0, 1.0]} />
      <meshStandardMaterial
        color="#22c55e"
        transparent
        opacity={0.4}
        emissive="#22c55e"
        emissiveIntensity={0.5}
        wireframe={false}
      />
    </mesh>
  );
}

// Area selection wireframe for SELECT mode
function SelectionArea({ start, end }) {
  if (!start || !end) return null;
  
  const minX = Math.min(start.x, end.x);
  const minY = Math.min(start.y, end.y);
  const minZ = Math.min(start.z, end.z);
  const maxX = Math.max(start.x, end.x);
  const maxY = Math.max(start.y, end.y);
  const maxZ = Math.max(start.z, end.z);
  
  const width = maxX - minX + 1;
  const height = maxY - minY + 1;
  const depth = maxZ - minZ + 1;
  const centerX = (minX + maxX) / 2;
  const centerY = (minY + maxY) / 2;
  const centerZ = (minZ + maxZ) / 2;

  return (
    <group position={[centerX, centerY, centerZ]}>
      <lineSegments>
        <edgesGeometry args={[new THREE.BoxGeometry(width, height, depth)]} />
        <lineBasicMaterial color="#f59e0b" linewidth={2} />
      </lineSegments>
      <mesh>
        <boxGeometry args={[width, height, depth]} />
        <meshStandardMaterial
          color="#f59e0b"
          transparent
          opacity={0.1}
          side={THREE.DoubleSide}
        />
      </mesh>
      <Text
        position={[0, height / 2 + 0.8, 0]}
        fontSize={0.4}
        color="#f59e0b"
        anchorX="center"
        anchorY="middle"
        outlineWidth={0.04}
        outlineColor="#000000"
      >
        {`${width}×${height}×${depth} Selection`}
      </Text>
    </group>
  );
}

// Main scene component
function Scene({ interactionMode, onInteraction }) {
  const turtles = useTurtleStore((state) => state.getTurtleArray());
  const players = useTurtleStore((state) => Object.values(state.players || {}));
  const selectedTurtleId = useTurtleStore((state) => state.selectedTurtleId);
  const selectTurtle = useTurtleStore((state) => state.selectTurtle);
  const worldBlocks = useTurtleStore((state) => state.worldBlocks || []);
  
  // Mining areas state
  const [miningAreas, setMiningAreas] = useState([]);
  const [selectedAreaId, setSelectedAreaId] = useState(null);

  // Load mining areas
  useEffect(() => {
    const fetchMiningAreas = async () => {
      try {
        const response = await fetch('http://localhost:3001/api/mining-areas');
        if (response.ok) {
          const data = await response.json();
          setMiningAreas(data);
        }
      } catch (error) {
        console.error('Failed to fetch mining areas:', error);
      }
    };

    fetchMiningAreas();
    const interval = setInterval(fetchMiningAreas, 5000); // Refresh every 5 seconds
    return () => clearInterval(interval);
  }, []);

  // Calculate center point for camera focus
  const centerPoint = useMemo(() => {
    if (turtles.length === 0) return [0, 0, 0];
    
    let sumX = 0, sumY = 0, sumZ = 0;
    let count = 0;

    turtles.forEach(turtle => {
      if (turtle.position) {
        sumX += turtle.position.x;
        sumY += turtle.position.y;
        sumZ += turtle.position.z;
        count++;
      }
    });

    if (count === 0) return [0, 0, 0];
    return [sumX / count, sumY / count, sumZ / count];
  }, [turtles]);

  // Get home position from first turtle
  const homePosition = turtles.find(t => t.homePosition)?.homePosition;

  return (
    <>
      <ambientLight intensity={0.6} />
      <pointLight position={[10, 10, 10]} intensity={1.2} />
      <pointLight position={[-10, -10, -10]} intensity={0.6} />
      <pointLight position={[0, 20, 0]} intensity={0.8} color="#ffffff" />

      {/* Grid */}
      <Grid
        args={[100, 100]}
        cellSize={1}
        cellThickness={0.5}
        cellColor="#1e293b"
        sectionSize={5}
        sectionThickness={1}
        sectionColor="#334155"
        fadeDistance={50}
        fadeStrength={1}
        followCamera={false}
        infiniteGrid
      />

      {/* Render discovered blocks */}
      <WorldBlocks blocks={worldBlocks} />

      {/* Mining areas */}
      {miningAreas.map((area) => {
        const turtle = turtles.find(t => t.turtleID === area.turtleID);
        return (
          <MiningArea
            key={area.areaID}
            area={area}
            turtle={turtle}
            isSelected={selectedAreaId === area.areaID}
            onClick={() => setSelectedAreaId(selectedAreaId === area.areaID ? null : area.areaID)}
          />
        );
      })}

      {/* Home marker */}
      {homePosition && <HomeMarker position={homePosition} />}

      {/* Turtles and paths */}
      {turtles.map((turtle) => (
        <React.Fragment key={turtle.turtleID}>
          <PathTrail turtle={turtle} />
          <TurtleModel
            turtle={turtle}
            isSelected={selectedTurtleId === turtle.turtleID}
            onClick={() => selectTurtle(turtle.turtleID)}
          />
        </React.Fragment>
      ))}

      {/* Players */}
      {players.map((player) => (
        <PlayerMarker key={player.playerID} player={player} />
      ))}

      {/* Camera controls */}
      <OrbitControls
        target={centerPoint}
        enableDamping
        dampingFactor={0.05}
        minDistance={5}
        maxDistance={100}
      />
    </>
  );
}

// Main Map3D component
export default function Map3D() {
  return (
    <div style={{ width: '100%', height: '100%', background: '#0a0e1a' }}>
      <Canvas
        camera={{ position: [15, 15, 15], fov: 60 }}
        style={{ background: '#0a0e1a' }}
      >
        <Scene />
      </Canvas>
    </div>
  );
}
