import { Asset } from 'expo-asset';
import { GLView } from 'expo-gl';
import { Renderer } from 'expo-three';
import React, { useEffect, useRef, useState } from 'react';
import { Dimensions, PanResponder, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

import background1 from '@/assets/images/background-1.jpg';

const { width, height } = Dimensions.get('window');

interface HexagonTile {
  position: THREE.Vector3;
  mesh?: THREE.Mesh | null;
  stroke?: THREE.Mesh | null;
  occupied: boolean;
  unit?: THREE.Mesh;
  biome: 'desert' | 'grass' | 'water' | 'forest' | 'rock';
  modelPath?: string;
}

interface Unit {
  id: string;
  name: string;
  color: number;
  cost: number;
  level: number;
}

export default function TFTGameScene() {
  const sceneRef = useRef<THREE.Scene | null>(null);
  const cameraRef = useRef<THREE.PerspectiveCamera | null>(null);
  const rendererRef = useRef<THREE.WebGLRenderer | null>(null);
  const tilesRef = useRef<HexagonTile[][]>([]);
  const animationFrameRef = useRef<number | null>(null);
  const [selectedUnit, setSelectedUnit] = useState<Unit | null>(null);
  const [gold, setGold] = useState(10);
  const [isDragging, setIsDragging] = useState(false);
  const [dragStartPosition, setDragStartPosition] = useState({ x: 0, y: 0 });
  const [draggedTile, setDraggedTile] = useState<{ row: number; col: number } | null>(null);
  const [dragPosition, setDragPosition] = useState({ x: 0, y: 0 });
  const [draggedUnitMesh, setDraggedUnitMesh] = useState<THREE.Mesh | null>(null);
  const [availableUnits, setAvailableUnits] = useState<Unit[]>([
    { id: '1', name: 'Warrior', color: 0xff6b6b, cost: 3, level: 1 },
    { id: '2', name: 'Mage', color: 0x4ecdc4, cost: 4, level: 1 },
    { id: '3', name: 'Archer', color: 0x45b7d1, cost: 2, level: 1 },
    { id: '4', name: 'Tank', color: 0x96ceb4, cost: 5, level: 1 },
    { id: '5', name: 'Assassin', color: 0xfeca57, cost: 3, level: 1 },
    { id: '6', name: 'Knight', color: 0x9b59b6, cost: 4, level: 1 },
    { id: '7', name: 'Priest', color: 0xe74c3c, cost: 2, level: 1 },
    { id: '8', name: 'Wizard', color: 0x3498db, cost: 3, level: 1 },
    { id: '9', name: 'Ranger', color: 0x2ecc71, cost: 2, level: 1 },
    { id: '10', name: 'Guardian', color: 0xf39c12, cost: 4, level: 1 },
    { id: '11', name: 'Berserker', color: 0xe67e22, cost: 3, level: 1 },
    { id: '12', name: 'Sorcerer', color: 0x8e44ad, cost: 5, level: 1 },
    { id: '13', name: 'Scout', color: 0x16a085, cost: 2, level: 1 },
    { id: '14', name: 'Paladin', color: 0xc0392b, cost: 4, level: 1 },
    { id: '15', name: 'Necromancer', color: 0x7f8c8d, cost: 3, level: 1 },
    { id: '16', name: 'Dragon', color: 0xe74c3c, cost: 5, level: 1 },
  ]);

  // GLB model loader
  const gltfLoader = new GLTFLoader();

  // Load GLB model with proper asset handling
  const loadGLBModel = async (modelPath: string): Promise<THREE.Group | null> => {
    try {
      // Use static require for GLB models
      let asset;
      switch (modelPath) {
        case 'hex_sand_detail.gltf.glb':
          asset = Asset.fromModule(require('../assets/arena/hex_sand_detail.gltf.glb'));
          break;
        case 'hex_forest.gltf.glb':
          asset = Asset.fromModule(require('../assets/arena/hex_forest.gltf.glb'));
          break;
        case 'hex_water_detail.gltf.glb':
          asset = Asset.fromModule(require('../assets/arena/hex_water_detail.gltf.glb'));
          break;
        case 'hex_rock_detail.gltf.glb':
          asset = Asset.fromModule(require('../assets/arena/hex_rock_detail.gltf.glb'));
          break;
        case 'hex_sand_roadA.gltf.glb':
          asset = Asset.fromModule(require('../assets/arena/hex_sand_roadA.gltf.glb'));
          break;
        default:
          console.log('Model not found:', modelPath);
          return null;
      }
      
      await asset.downloadAsync();
      
      return new Promise((resolve, reject) => {
        gltfLoader.load(
          asset.uri,
          (gltf) => {
            const model = gltf.scene;
            // Scale to fit within hexagon (radius = 0.5)
            model.scale.set(0.4, 0.4, 0.4);
            // Rotate model to align with our hexagons (vertical)
            model.rotation.y = Math.PI / 6; // 30 degrees to align with our hexagons
            // Position underneath hexagon with minimal gap
            model.position.y = -0.01; // Minimal gap
            resolve(model);
          },
          undefined,
          (error) => {
            console.error('Error loading GLB model:', error);
            reject(error);
          }
        );
      });
    } catch (error) {
      console.error('Error loading GLB model:', error);
      return null;
    }
  };

  // Create enhanced geometry for different biomes
  const createEnhancedGeometry = (biome: string, radius: number = 0.5) => {
    switch (biome) {
      case 'desert':
        // Create sand-like geometry with bumps
        const sandGeometry = new THREE.CylinderGeometry(radius, radius, 0.1, 6);
        const sandMaterial = new THREE.MeshLambertMaterial({ 
          color: 0xd2b48c,
          transparent: true,
          opacity: 0.9
        });
        return new THREE.Mesh(sandGeometry, sandMaterial);
        
      case 'water':
        // Create water-like geometry with waves
        const waterGeometry = new THREE.CylinderGeometry(radius, radius, 0.08, 6);
        const waterMaterial = new THREE.MeshLambertMaterial({ 
          color: 0x87CEEB,
          transparent: true,
          opacity: 0.7
        });
        return new THREE.Mesh(waterGeometry, waterMaterial);
        
      case 'forest':
        // Create forest-like geometry with texture
        const forestGeometry = new THREE.CylinderGeometry(radius, radius, 0.12, 6);
        const forestMaterial = new THREE.MeshLambertMaterial({ 
          color: 0x228B22,
          transparent: true,
          opacity: 0.9
        });
        return new THREE.Mesh(forestGeometry, forestMaterial);
        
      case 'rock':
        // Create rock-like geometry with roughness
        const rockGeometry = new THREE.CylinderGeometry(radius, radius, 0.15, 6);
        const rockMaterial = new THREE.MeshLambertMaterial({ 
          color: 0x696969,
          transparent: true,
          opacity: 0.9
        });
        return new THREE.Mesh(rockGeometry, rockMaterial);
        
      default:
        // Default grass geometry
        const grassGeometry = new THREE.CylinderGeometry(radius, radius, 0.1, 6);
        const grassMaterial = new THREE.MeshLambertMaterial({ 
          color: 0x90EE90,
          transparent: true,
          opacity: 0.9
        });
        return new THREE.Mesh(grassGeometry, grassMaterial);
    }
  };

  // Hexagon geometry helper
  const createHexagonGeometry = (radius: number, height: number) => {
    const geometry = new THREE.CylinderGeometry(radius, radius, height, 6);
    return geometry;
  };

  // Create a single hexagon tile with GLB models
  const createHexagonTile = async (x: number, z: number, radius: number = 0.5, biome: 'desert' | 'grass' | 'water' | 'forest' | 'rock' = 'grass') => {
    // Biome-based model paths
    let modelPath: string | undefined;
    
    switch (biome) {
      case 'desert':
        modelPath = 'hex_sand_detail.gltf.glb';
        break;
      case 'grass':
        modelPath = 'hex_forest.gltf.glb';
        break;
      case 'water':
        modelPath = 'hex_water_detail.gltf.glb';
        break;
      case 'forest':
        modelPath = 'hex_forest.gltf.glb';
        break;
      case 'rock':
        modelPath = 'hex_rock_detail.gltf.glb';
        break;
      default:
        modelPath = 'hex_forest.gltf.glb';
    }
    
    return {
      position: new THREE.Vector3(x, 0, z),
      mesh: null, // We don't need our custom mesh anymore
      stroke: null, // We don't need our custom stroke anymore
      occupied: false,
      biome,
      modelPath
    };
  };

  // Create a unit cube with proper level scaling
  const createUnitCube = (color: number = 0xff6b6b, level: number = 1) => {
    const geometry = new THREE.BoxGeometry(0.3, 0.3, 0.3);
    const material = new THREE.MeshLambertMaterial({ color });
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.y = 0.5; // Position above GLB models
    
    // TFT style scaling: Level 1 = normal, Level 2 = 1.2x, Level 3 = 1.4x, Level 4 = 1.6x
    const scaleMultiplier = 1 + (level - 1) * 0.2;
    mesh.scale.set(scaleMultiplier, scaleMultiplier, scaleMultiplier);
    
    return mesh;
  };

  // Create the beautiful 6x6 hexagonal arena with GLB models
  const createArena = async () => {
    const tiles: HexagonTile[][] = [];
    const hexRadius = 0.5;
    const hexWidth = hexRadius * 2;
    const hexHeight = hexRadius * Math.sqrt(3);
    
    // Calculate arena center offset to center it on screen
    const arenaWidth = 5 * hexWidth * 0.75; // 6 columns
    const arenaHeight = 5 * hexHeight; // 6 rows
    const centerX = -arenaWidth / 2;
    const centerZ = -arenaHeight / 2;
    
    // Define biome layout based on the image with roads
    const biomeLayout = [
      ['desert', 'desert', 'desert', 'grass', 'grass', 'grass'],
      ['desert', 'desert', 'grass', 'grass', 'grass', 'grass'],
      ['desert', 'grass', 'grass', 'grass', 'grass', 'water'],
      ['grass', 'grass', 'grass', 'forest', 'water', 'water'],
      ['grass', 'grass', 'forest', 'water', 'water', 'water'],
      ['grass', 'forest', 'water', 'water', 'water', 'water']
    ];
    
    // Define road layout (connecting different biomes)
    const roadLayout = [
      [false, false, false, false, false, false],
      [false, false, true, false, false, false],
      [false, true, false, true, false, false],
      [false, false, true, false, true, false],
      [false, false, false, true, false, true],
      [false, false, false, false, true, false]
    ];
    
    for (let row = 0; row < 6; row++) {
      tiles[row] = [];
      for (let col = 0; col < 6; col++) {
        // Calculate position with offset for hexagonal grid, centered
        const x = centerX + col * hexWidth * 0.75;
        const z = centerZ + row * hexHeight + (col % 2) * (hexHeight / 2);
        
        // Get biome from layout
        const biome = biomeLayout[row][col] as 'desert' | 'grass' | 'water' | 'forest' | 'rock';
        const hasRoad = roadLayout[row][col];
        
        const tile = await createHexagonTile(x, z, hexRadius, biome);
        tiles[row][col] = tile;
        
        if (sceneRef.current) {
          // Only add GLB model - no custom hexagons
          if (tile.modelPath) {
            try {
              const model = await loadGLBModel(tile.modelPath);
              if (model) {
                // Center the model with the hexagon position
                model.position.copy(tile.position);
                model.position.y = 0.0; // At ground level
                
                // Add color tint based on area (player vs enemy)
                const isPlayerArea = row >= 3; // Bottom 3 rows are player area
                if (isPlayerArea) {
                  // Player area - normal colors
                  model.children.forEach(child => {
                    if (child instanceof THREE.Mesh && child.material) {
                      if (Array.isArray(child.material)) {
                        child.material.forEach(mat => {
                          if (mat instanceof THREE.MeshLambertMaterial) {
                            mat.emissive = new THREE.Color(0x00ff00);
                            mat.emissiveIntensity = 0.1;
                          }
                        });
                      } else if (child.material instanceof THREE.MeshLambertMaterial) {
                        child.material.emissive = new THREE.Color(0x00ff00);
                        child.material.emissiveIntensity = 0.1;
                      }
                    }
                  });
                } else {
                  // Enemy area - red tint
                  model.children.forEach(child => {
                    if (child instanceof THREE.Mesh && child.material) {
                      if (Array.isArray(child.material)) {
                        child.material.forEach(mat => {
                          if (mat instanceof THREE.MeshLambertMaterial) {
                            mat.emissive = new THREE.Color(0xff0000);
                            mat.emissiveIntensity = 0.2;
                          }
                        });
                      } else if (child.material instanceof THREE.MeshLambertMaterial) {
                        child.material.emissive = new THREE.Color(0xff0000);
                        child.material.emissiveIntensity = 0.2;
                      }
                    }
                  });
                }
                
                sceneRef.current.add(model);
              }
            } catch (error) {
              console.log('Using fallback geometry for tile');
            }
          }
        }
      }
    }
    
    tilesRef.current = tiles;
    
    // Add bases to arena corners (outside the arena) - REMOVED
    // if (sceneRef.current) {
    //   // Player base (bottom right corner) - Castle style
    //   const playerBaseGeometry = new THREE.CylinderGeometry(1.5, 1.5, 0.4, 8);
    //   const playerBaseMaterial = new THREE.MeshLambertMaterial({ 
    //     color: 0x4a90e2,
    //     transparent: true,
    //     opacity: 0.9
    //   });
    //   const playerBase = new THREE.Mesh(playerBaseGeometry, playerBaseMaterial);
    //   playerBase.position.set(centerX + 6 * hexWidth * 0.75, 0.2, centerZ + 6 * hexHeight);
    //   sceneRef.current.add(playerBase);
    //   
    //   // Enemy base (top left corner) - Tower style
    //   const enemyBaseGeometry = new THREE.CylinderGeometry(1.2, 1.2, 0.6, 8);
    //   const enemyBaseMaterial = new THREE.MeshLambertMaterial({ 
    //     color: 0x666666,
    //     transparent: true,
    //     opacity: 0.9
    //   });
    //   const enemyBase = new THREE.Mesh(enemyBaseGeometry, enemyBaseMaterial);
    //   enemyBase.position.set(centerX - hexWidth * 0.75, 0.3, centerZ - hexHeight);
    //   sceneRef.current.add(enemyBase);
    //   
    //   // Add some decorative structures
    //   addDecorations(centerX, centerZ, hexWidth, hexHeight);
    // }
  };

  // Add decorative structures to the arena
  const addDecorations = async (centerX: number, centerZ: number, hexWidth: number, hexHeight: number) => {
    if (!sceneRef.current) return;
    
    // Add a castle in the center grass area
    const castleGeometry = new THREE.BoxGeometry(1.2, 1.5, 1.2);
    const castleMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 });
    const castle = new THREE.Mesh(castleGeometry, castleMaterial);
    castle.position.set(centerX + 2 * hexWidth * 0.75, 0.75, centerZ + 2 * hexHeight);
    sceneRef.current.add(castle);
    
    // Add castle towers
    for (let i = 0; i < 4; i++) {
      const towerGeometry = new THREE.CylinderGeometry(0.2, 0.2, 0.8, 8);
      const towerMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 });
      const tower = new THREE.Mesh(towerGeometry, towerMaterial);
      const angle = (i * Math.PI) / 2;
      tower.position.set(
        centerX + 2 * hexWidth * 0.75 + Math.cos(angle) * 0.8,
        0.4,
        centerZ + 2 * hexHeight + Math.sin(angle) * 0.8
      );
      sceneRef.current.add(tower);
    }
    
    // Add a windmill in the water area
    const windmillGeometry = new THREE.CylinderGeometry(0.3, 0.3, 1.0, 8);
    const windmillMaterial = new THREE.MeshLambertMaterial({ color: 0xDEB887 });
    const windmill = new THREE.Mesh(windmillGeometry, windmillMaterial);
    windmill.position.set(centerX + 4 * hexWidth * 0.75, 0.5, centerZ + 4 * hexHeight);
    sceneRef.current.add(windmill);
    
    // Add windmill blades
    const bladeGeometry = new THREE.BoxGeometry(0.1, 0.8, 0.05);
    const bladeMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 });
    for (let i = 0; i < 4; i++) {
      const blade = new THREE.Mesh(bladeGeometry, bladeMaterial);
      const angle = (i * Math.PI) / 2;
      blade.position.set(
        centerX + 4 * hexWidth * 0.75 + Math.cos(angle) * 0.4,
        1.0,
        centerZ + 4 * hexHeight + Math.sin(angle) * 0.4
      );
      blade.rotation.y = angle;
      sceneRef.current.add(blade);
    }
    
    // Add some trees in the forest area using GLB models
    for (let i = 0; i < 3; i++) {
      try {
        const treeModel = await loadGLBModel('hex_forest.gltf.glb');
        if (treeModel) {
          treeModel.position.set(
            centerX + (3 + i) * hexWidth * 0.75,
            0.4,
            centerZ + (4 + i % 2) * hexHeight
          );
          treeModel.scale.set(0.3, 0.3, 0.3);
          sceneRef.current.add(treeModel);
        } else {
          // Fallback to geometry
          const treeGeometry = new THREE.ConeGeometry(0.3, 0.8, 8);
          const treeMaterial = new THREE.MeshLambertMaterial({ color: 0x228B22 });
          const tree = new THREE.Mesh(treeGeometry, treeMaterial);
          tree.position.set(
            centerX + (3 + i) * hexWidth * 0.75,
            0.4,
            centerZ + (4 + i % 2) * hexHeight
          );
          sceneRef.current.add(tree);
        }
      } catch (error) {
        console.log('Tree model not loaded, using fallback');
        const treeGeometry = new THREE.ConeGeometry(0.3, 0.8, 8);
        const treeMaterial = new THREE.MeshLambertMaterial({ color: 0x228B22 });
        const tree = new THREE.Mesh(treeGeometry, treeMaterial);
        tree.position.set(
          centerX + (3 + i) * hexWidth * 0.75,
          0.4,
          centerZ + (4 + i % 2) * hexHeight
        );
        sceneRef.current.add(tree);
      }
    }
    
    // Add rocks in the desert area using GLB models
    for (let i = 0; i < 2; i++) {
      try {
        const rockModel = await loadGLBModel('hex_rock_detail.gltf.glb');
        if (rockModel) {
          rockModel.position.set(
            centerX + i * hexWidth * 0.75,
            0.1,
            centerZ + i * hexHeight
          );
          rockModel.scale.set(0.2, 0.2, 0.2);
          sceneRef.current.add(rockModel);
        } else {
          // Fallback to geometry
          const rockGeometry = new THREE.DodecahedronGeometry(0.2);
          const rockMaterial = new THREE.MeshLambertMaterial({ color: 0x696969 });
          const rock = new THREE.Mesh(rockGeometry, rockMaterial);
          rock.position.set(
            centerX + i * hexWidth * 0.75,
            0.1,
            centerZ + i * hexHeight
          );
          sceneRef.current.add(rock);
        }
      } catch (error) {
        console.log('Rock model not loaded, using fallback');
        const rockGeometry = new THREE.DodecahedronGeometry(0.2);
        const rockMaterial = new THREE.MeshLambertMaterial({ color: 0x696969 });
        const rock = new THREE.Mesh(rockGeometry, rockMaterial);
        rock.position.set(
          centerX + i * hexWidth * 0.75,
          0.1,
          centerZ + i * hexHeight
        );
        sceneRef.current.add(rock);
      }
    }
    
    // Add a bridge over water
    const bridgeGeometry = new THREE.BoxGeometry(1.0, 0.1, 0.3);
    const bridgeMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 });
    const bridge = new THREE.Mesh(bridgeGeometry, bridgeMaterial);
    bridge.position.set(centerX + 3 * hexWidth * 0.75, 0.15, centerZ + 4 * hexHeight);
    sceneRef.current.add(bridge);
    
    // Add some houses in the grass area
    for (let i = 0; i < 2; i++) {
      const houseGeometry = new THREE.BoxGeometry(0.6, 0.4, 0.6);
      const houseMaterial = new THREE.MeshLambertMaterial({ color: 0xDEB887 });
      const house = new THREE.Mesh(houseGeometry, houseMaterial);
      house.position.set(
        centerX + (1 + i) * hexWidth * 0.75,
        0.2,
        centerZ + (3 + i) * hexHeight
      );
      sceneRef.current.add(house);
      
      // Add roof
      const roofGeometry = new THREE.ConeGeometry(0.4, 0.3, 4);
      const roofMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 });
      const roof = new THREE.Mesh(roofGeometry, roofMaterial);
      roof.position.set(
        centerX + (1 + i) * hexWidth * 0.75,
        0.55,
        centerZ + (3 + i) * hexHeight
      );
      roof.rotation.y = Math.PI / 4;
      sceneRef.current.add(roof);
    }
  };

  // Handle unit purchase
  const handleUnitPurchase = (unit: Unit) => {
    if (gold >= unit.cost) {
      setGold(gold - unit.cost);
      setSelectedUnit(unit);
      console.log('Unit selected:', unit.name); // Debug log
    }
  };

  // Handle tile placement with proper merge logic
  const handleTilePlacement = (row: number, col: number) => {
    if (selectedUnit && tilesRef.current[row] && tilesRef.current[row][col]) {
      const tile = tilesRef.current[row][col];
      if (!tile.occupied) {
        // Check for merge first
        const wasMerged = checkForMerge(selectedUnit);
        
        if (!wasMerged) {
          // Place new unit normally - add to scene directly since we don't have tile.mesh
          const unit = createUnitCube(selectedUnit.color, selectedUnit.level);
          unit.position.copy(tile.position);
          unit.position.y = 0.5; // Position above GLB model
          if (sceneRef.current) {
            sceneRef.current.add(unit);
          }
          tile.occupied = true;
          tile.unit = unit;
        }
        
        setSelectedUnit(null);
      }
    }
  };

  // Add some sample units to the arena (only in user area)
  const addSampleUnits = () => {
    const sampleUnits = [
      { row: 4, col: 2, unit: availableUnits[0] }, // Warrior
      { row: 5, col: 3, unit: availableUnits[1] }, // Mage
      { row: 4, col: 4, unit: availableUnits[2] }, // Archer
    ];

    sampleUnits.forEach(({ row, col, unit }) => {
      if (tilesRef.current[row] && tilesRef.current[row][col]) {
        const tile = tilesRef.current[row][col];
        const mesh = createUnitCube(unit.color, unit.level);
        mesh.position.copy(tile.position);
        mesh.position.y = 0.5; // Position above GLB model
        if (sceneRef.current) {
          sceneRef.current.add(mesh);
        }
        tile.occupied = true;
        tile.unit = mesh;
      }
    });
  };

  // Get tile at screen position
  const getTileAtPosition = (x: number, y: number) => {
    if (!cameraRef.current) return null;

    const mouse = new THREE.Vector2();
    mouse.x = (x / width) * 2 - 1;
    mouse.y = -(y / height) * 2 + 1;

    const raycaster = new THREE.Raycaster();
    raycaster.setFromCamera(mouse, cameraRef.current);

    // Get all GLB models from the scene
    const modelMeshes: THREE.Mesh[] = [];
    if (sceneRef.current) {
      sceneRef.current.children.forEach(child => {
        if (child.type === 'Group') {
          child.children.forEach(groupChild => {
            if (groupChild.type === 'Mesh') {
              modelMeshes.push(groupChild as THREE.Mesh);
            }
          });
        }
      });
    }

    const intersects = raycaster.intersectObjects(modelMeshes);
    
    if (intersects.length > 0) {
      const intersectedMesh = intersects[0].object;
      
      // Find the tile based on the intersected mesh position
      for (let row = 0; row < 6; row++) {
        for (let col = 0; col < 6; col++) {
          const tile = tilesRef.current[row][col];
          // Check if the intersected mesh belongs to this tile's position
          if (tile.position.distanceTo(intersectedMesh.position) < 0.5) {
            return { row, col, tile };
          }
        }
      }
    }
    return null;
  };

  // PanResponder for drag and drop
  const panResponder = PanResponder.create({
    onStartShouldSetPanResponder: () => true,
    onMoveShouldSetPanResponder: () => true,
    onPanResponderGrant: (event) => {
      const touch = event.nativeEvent;
      console.log('Drag started at:', touch.locationX, touch.locationY); // Debug log
      setDragStartPosition({ x: touch.locationX, y: touch.locationY });
      setDragPosition({ x: touch.locationX, y: touch.locationY });
      setIsDragging(true);

      // Check if we're dragging an existing unit
      const tileInfo = getTileAtPosition(touch.locationX, touch.locationY);
      console.log('Tile info:', tileInfo); // Debug log
      
      if (tileInfo && tileInfo.tile.occupied && tileInfo.row >= 3) {
        console.log('Dragging existing unit'); // Debug log
        // Dragging an existing unit from user area
        setDraggedTile({ row: tileInfo.row, col: tileInfo.col });
        setSelectedUnit(null); // Clear selected unit since we're moving existing one
        
        // Create a copy of the unit for dragging
        if (tileInfo.tile.unit) {
          const unitGeometry = new THREE.BoxGeometry(0.3, 0.3, 0.3);
          const unitMaterial = new THREE.MeshLambertMaterial({ 
            color: tileInfo.tile.unit.material instanceof THREE.MeshLambertMaterial 
              ? tileInfo.tile.unit.material.color 
              : 0xff6b6b,
            transparent: true,
            opacity: 0.8
          });
          const dragMesh = new THREE.Mesh(unitGeometry, unitMaterial);
          dragMesh.position.y = 0.5;
          dragMesh.scale.copy(tileInfo.tile.unit.scale); // Copy the scale (level)
          setDraggedUnitMesh(dragMesh);
          
          // Add to scene immediately
          if (sceneRef.current) {
            sceneRef.current.add(dragMesh);
          }
          
          // Hide the original unit temporarily
          tileInfo.tile.unit.visible = false;
        }
      } else if (selectedUnit) {
        console.log('Dragging new unit:', selectedUnit.name); // Debug log
        // Dragging a new unit from bottom panel
        setDraggedTile(null);
        
        // Create a new unit mesh for dragging
        const unitGeometry = new THREE.BoxGeometry(0.3, 0.3, 0.3);
        const unitMaterial = new THREE.MeshLambertMaterial({ 
          color: selectedUnit.color,
          transparent: true,
          opacity: 0.8
        });
        const dragMesh = new THREE.Mesh(unitGeometry, unitMaterial);
        dragMesh.position.y = 0.5;
        
        // Apply proper level scaling
        const scaleMultiplier = 1 + (selectedUnit.level - 1) * 0.2;
        dragMesh.scale.set(scaleMultiplier, scaleMultiplier, scaleMultiplier);
        
        setDraggedUnitMesh(dragMesh);
        
        // Add to scene immediately
        if (sceneRef.current) {
          sceneRef.current.add(dragMesh);
        }
      }
    },
    onPanResponderMove: (event) => {
      if (!isDragging) return;

      const touch = event.nativeEvent;
      setDragPosition({ x: touch.locationX, y: touch.locationY });
      const tileInfo = getTileAtPosition(touch.locationX, touch.locationY);
      
      // Update dragged unit position to follow touch
      if (draggedUnitMesh && cameraRef.current) {
        const mouse = new THREE.Vector2();
        mouse.x = (touch.locationX / width) * 2 - 1;
        mouse.y = -(touch.locationY / height) * 2 + 1;

        const raycaster = new THREE.Raycaster();
        raycaster.setFromCamera(mouse, cameraRef.current);
        
        // Get intersection with a plane at y=0
        const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
        const intersection = new THREE.Vector3();
        raycaster.ray.intersectPlane(plane, intersection);
        
        draggedUnitMesh.position.set(intersection.x, 0.5, intersection.z);
      }
    },
    onPanResponderRelease: (event) => {
      if (!isDragging) return;

      const touch = event.nativeEvent;
      console.log('Drag ended at:', touch.locationX, touch.locationY); // Debug log
      const tileInfo = getTileAtPosition(touch.locationX, touch.locationY);
      console.log('Final tile info:', tileInfo); // Debug log
      
      if (draggedTile) {
        console.log('Moving existing unit'); // Debug log
        // Moving an existing unit
        if (tileInfo && !tileInfo.tile.occupied && tileInfo.row >= 3) {
          console.log('Moving unit to new position'); // Debug log
          // Move unit to new position
          const sourceTile = tilesRef.current[draggedTile.row][draggedTile.col];
          const targetTile = tilesRef.current[tileInfo.row][tileInfo.col];
          
          if (sourceTile.unit) {
            // Show the original unit again
            sourceTile.unit.visible = true;
            
            // Remove unit from scene
            if (sceneRef.current) {
              sceneRef.current.remove(sourceTile.unit);
            }
            sourceTile.occupied = false;
            
            // Add unit to new position
            sourceTile.unit.position.copy(targetTile.position);
            sourceTile.unit.position.y = 0.5;
            if (sceneRef.current) {
              sceneRef.current.add(sourceTile.unit);
            }
            targetTile.occupied = true;
            targetTile.unit = sourceTile.unit;
            
            // Clear source tile unit reference
            sourceTile.unit = undefined;
          }
        } else {
          console.log('Reset dragged unit'); // Debug log
          // Reset the dragged unit if placement failed
          const sourceTile = tilesRef.current[draggedTile.row][draggedTile.col];
          if (sourceTile.unit) {
            sourceTile.unit.visible = true;
          }
        }
        setDraggedTile(null);
      } else if (selectedUnit) {
        console.log('Placing new unit:', selectedUnit.name); // Debug log
        // Placing a new unit
        if (tileInfo && !tileInfo.tile.occupied && tileInfo.row >= 3) {
          console.log('Placing unit at:', tileInfo.row, tileInfo.col); // Debug log
          // Place new unit normally - add to scene directly since we don't have tile.mesh
          const unit = createUnitCube(selectedUnit.color, selectedUnit.level);
          unit.position.copy(tileInfo.tile.position);
          unit.position.y = 0.5; // Position above GLB model
          if (sceneRef.current) {
            sceneRef.current.add(unit);
          }
          tileInfo.tile.occupied = true;
          tileInfo.tile.unit = unit;
          setSelectedUnit(null);
        }
      }
      
      // Remove dragged unit mesh from scene
      if (draggedUnitMesh && sceneRef.current) {
        sceneRef.current.remove(draggedUnitMesh);
      }
      setDraggedUnitMesh(null);
      
      setIsDragging(false);
    },
    onPanResponderTerminate: (event) => {
      if (!isDragging) return;

      const touch = event.nativeEvent;
      const tileInfo = getTileAtPosition(touch.locationX, touch.locationY);
      
      if (draggedTile) {
        // Moving an existing unit
        if (tileInfo && !tileInfo.tile.occupied && tileInfo.row >= 3) {
          // Move unit to new position
          const sourceTile = tilesRef.current[draggedTile.row][draggedTile.col];
          const targetTile = tilesRef.current[tileInfo.row][tileInfo.col];
          
          if (sourceTile.unit) {
            // Show the original unit again
            sourceTile.unit.visible = true;
            
            // Remove unit from scene
            if (sceneRef.current) {
              sceneRef.current.remove(sourceTile.unit);
            }
            sourceTile.occupied = false;
            
            // Add unit to new position
            sourceTile.unit.position.copy(targetTile.position);
            sourceTile.unit.position.y = 0.5;
            if (sceneRef.current) {
              sceneRef.current.add(sourceTile.unit);
            }
            targetTile.occupied = true;
            targetTile.unit = sourceTile.unit;
            
            // Clear source tile unit reference
            sourceTile.unit = undefined;
          }
        } else {
          // Reset the dragged unit if placement failed
          const sourceTile = tilesRef.current[draggedTile.row][draggedTile.col];
          if (sourceTile.unit) {
            sourceTile.unit.visible = true;
          }
        }
        setDraggedTile(null);
      } else if (selectedUnit) {
        // Placing a new unit
        if (tileInfo && !tileInfo.tile.occupied && tileInfo.row >= 3) {
          // Place new unit normally - add to scene directly since we don't have tile.mesh
          const unit = createUnitCube(selectedUnit.color, selectedUnit.level);
          unit.position.copy(tileInfo.tile.position);
          unit.position.y = 0.5; // Position above GLB model
          if (sceneRef.current) {
            sceneRef.current.add(unit);
          }
          tileInfo.tile.occupied = true;
          tileInfo.tile.unit = unit;
          setSelectedUnit(null);
        }
      }
      
      // Remove dragged unit mesh from scene
      if (draggedUnitMesh && sceneRef.current) {
        sceneRef.current.remove(draggedUnitMesh);
      }
      setDraggedUnitMesh(null);
      
      setIsDragging(false);
    },
  });

  // Setup scene
  const setupScene = async (gl: any) => {
    // Create renderer
    const renderer = new Renderer({ gl });
    rendererRef.current = renderer;

    // Create scene with beautiful background
    const scene = new THREE.Scene();
    scene.background = new THREE.Color(0x1a1a2e); // Beautiful dark blue for TFT theme
    sceneRef.current = scene;

    // Load and set background image
    try {
      const bgAsset = Asset.fromModule(background1);
      await bgAsset.downloadAsync();
      
      console.log('Asset URI:', bgAsset.uri);
      
      // Create a new texture loader with more aggressive settings
      const textureLoader = new THREE.TextureLoader();
      
      // Try multiple approaches to load the texture
      const loadTexture = () => {
        textureLoader.load(
          bgAsset.uri,
          (texture) => {
            console.log('Background texture loaded successfully');
            if (sceneRef.current) {
              sceneRef.current.background = texture;
            }
          },
          (progress) => {
            console.log('Loading progress:', progress);
          },
          (error) => {
            console.log('Error loading background texture:', error);
            // Try again with a different approach
            setTimeout(() => {
              console.log('Retrying texture load...');
              textureLoader.load(
                bgAsset.uri,
                (texture) => {
                  console.log('Background texture loaded on retry');
                  if (sceneRef.current) {
                    sceneRef.current.background = texture;
                  }
                },
                undefined,
                (retryError) => {
                  console.log('Retry failed:', retryError);
                }
              );
            }, 1000);
          }
        );
      };
      
      // Start loading
      loadTexture();
      
    } catch (error) {
      console.log('Failed to load background image:', error);
      // Keep the default color
    }

    // Create fixed camera - positioned to show arena and bases
    const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
    camera.position.set(0, 12, 12); // Closer to arena
    camera.lookAt(0, 0, 0);
    cameraRef.current = camera;

    // Add lighting
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.7);
    scene.add(ambientLight);

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

    // Create arena with GLB models
    await createArena();
    addSampleUnits();

    // Animation loop - no camera movement
    const animate = () => {
      animationFrameRef.current = requestAnimationFrame(animate);
      renderer.render(scene, camera);
      gl.endFrameEXP();
    };

    animate();
  };

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      if (animationFrameRef.current) {
        cancelAnimationFrame(animationFrameRef.current);
      }
    };
  }, []);

  // Get units on arena with proper level detection
  const getUnitsOnArena = (): Unit[] => {
    const units: Unit[] = [];
    tilesRef.current.forEach(row => {
      row.forEach(tile => {
        if (tile.occupied && tile.unit) {
          const unitColor = (tile.unit.material as any)?.color?.getHexString();
          const unitData = availableUnits.find(u => u.color.toString(16) === unitColor);
          if (unitData) {
            // Calculate level based on scale
            const scale = tile.unit.scale.x;
            const level = Math.round((scale - 1) / 0.2) + 1;
            units.push({ ...unitData, level: Math.max(1, Math.min(4, level)) });
          }
        }
      });
    });
    return units;
  };

  // Check for merging opportunities
  const checkForMerge = (newUnit: Unit) => {
    const arenaUnits = getUnitsOnArena();
    const sameTypeUnits = arenaUnits.filter(u => u.name === newUnit.name);
    
    // TFT style: need 3 units of same type to merge
    if (sameTypeUnits.length >= 2) {
      // Calculate new level based on TFT rules
      const totalUnits = sameTypeUnits.length + 1; // +1 for the new unit
      const newLevel = Math.min(4, Math.floor(totalUnits / 3) + 1);
      
      // Create merged unit
      const mergedUnit: Unit = {
        ...newUnit,
        level: newLevel
      };
      
      // Remove old units from arena
      let removedCount = 0;
      tilesRef.current.forEach(row => {
        row.forEach(tile => {
          if (tile.occupied && tile.unit && removedCount < 3) {
            const unitColor = (tile.unit.material as any)?.color?.getHexString();
            const unitData = availableUnits.find(u => u.color.toString(16) === unitColor && u.name === newUnit.name);
            if (unitData) {
              // Remove unit from scene
              if (sceneRef.current) {
                sceneRef.current.remove(tile.unit);
              }
              tile.occupied = false;
              tile.unit = undefined;
              removedCount++;
            }
          }
        });
      });
      
      // Add merged unit to first empty tile
      for (let row = 3; row < 6; row++) {
        for (let col = 0; col < 6; col++) {
          const tile = tilesRef.current[row][col];
          if (!tile.occupied) {
            const mergedMesh = createUnitCube(mergedUnit.color, mergedUnit.level);
            mergedMesh.position.copy(tile.position); // Position the merged unit
            mergedMesh.position.y = 0.5; // Position above GLB model
            if (sceneRef.current) {
              sceneRef.current.add(mergedMesh);
            }
            tile.occupied = true;
            tile.unit = mergedMesh;
            return true; // Merged successfully
          }
        }
      }
    }
    
    return false; // No merge
  };

  return (
    <View style={styles.container}>
      <View {...panResponder.panHandlers} style={styles.glContainer}>
        <GLView style={styles.glView} onContextCreate={setupScene} />
      </View>
      
      {/* Gold Display - Top Right */}
      <View style={styles.goldDisplay}>
        <Text style={styles.goldIcon}>💰</Text>
        <Text style={styles.goldText}>{gold}</Text>
      </View>
      
      {/* Horizontal Card Slider */}
      <View style={styles.cardSlider}>
        <View style={styles.sliderContainer}>
          {/* Main Cards (4 visible) */}
          <View style={styles.mainCardsContainer}>
            {availableUnits.slice(0, 4).map((unit, index) => {
              const isSelected = selectedUnit?.id === unit.id;
              
              return (
                <TouchableOpacity
                  key={unit.id}
                  style={[
                    styles.unitCard,
                    { 
                      transform: [{ scale: isSelected ? 1.1 : 1.0 }],
                      zIndex: isSelected ? 10 : 1
                    },
                    isSelected && styles.selectedUnitCard
                  ]}
                  onPress={() => handleUnitPurchase(unit)}
                  disabled={gold < unit.cost}
                >
                  {/* Card Back Pattern */}
                  <View style={styles.cardBack}>
                    <View style={styles.cardPattern}>
                      <View style={styles.eyePattern}>
                        <View style={styles.eyeCenter} />
                        <View style={styles.eyeTriangle} />
                      </View>
                    </View>
                  </View>
                  
                  {/* Unit Info Overlay */}
                  <View style={styles.cardInfo}>
                    <Text style={styles.unitName}>{unit.name}</Text>
                    <View style={styles.levelContainer}>
                      <Text style={styles.unitLevel}>★ {unit.level}</Text>
                    </View>
                    <Text style={styles.unitCost}>{unit.cost}</Text>
                  </View>
                </TouchableOpacity>
              );
            })}
          </View>
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#1a1a2e',
  },
  glView: {
    flex: 1,
  },
  glContainer: {
    flex: 1,
  },
  goldDisplay: {
    position: 'absolute',
    top: 50,
    right: 20,
    backgroundColor: 'rgba(0, 0, 0, 0.8)',
    paddingHorizontal: 15,
    paddingVertical: 10,
    borderRadius: 25,
    flexDirection: 'row',
    alignItems: 'center',
    shadowColor: '#feca57',
    shadowOffset: {
      width: 0,
      height: 0,
    },
    shadowOpacity: 0.5,
    shadowRadius: 10,
    elevation: 10,
  },
  goldIcon: {
    fontSize: 20,
    marginRight: 8,
  },
  goldText: {
    color: '#feca57',
    fontSize: 18,
    fontWeight: 'bold',
  },
  cardSlider: {
    position: 'absolute',
    bottom: 30,
    left: 0,
    right: 0,
    alignItems: 'center',
  },
  sliderContainer: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
    width: '100%',
    height: 100,
  },
  mainCardsContainer: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
    width: '100%',
    height: 100,
  },
  unitCard: {
    padding: 12,
    borderRadius: 15,
    alignItems: 'center',
    minWidth: 70,
    height: 100,
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 4,
    },
    shadowOpacity: 0.3,
    shadowRadius: 8,
    elevation: 8,
    borderWidth: 2,
    borderColor: 'rgba(255, 255, 255, 0.2)',
    backgroundColor: 'rgba(0, 0, 0, 0.8)',
    position: 'relative',
    marginHorizontal: 5,
  },
  selectedUnitCard: {
    borderWidth: 3,
    borderColor: '#ffffff',
    shadowColor: '#ffffff',
    shadowOffset: {
      width: 0,
      height: 0,
    },
    shadowOpacity: 0.8,
    shadowRadius: 15,
    elevation: 15,
    backgroundColor: 'rgba(255, 255, 255, 0.1)',
  },
  unitName: {
    color: '#ffffff',
    fontSize: 12,
    fontWeight: 'bold',
    textAlign: 'center',
  },
  unitLevel: {
    color: '#feca57',
    fontSize: 12,
    fontWeight: 'bold',
    marginTop: 2,
  },
  unitCost: {
    color: '#feca57',
    fontSize: 16,
    fontWeight: 'bold',
    marginTop: 4,
  },
  cardBack: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    borderRadius: 20,
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 1,
  },
  cardPattern: {
    width: '100%',
    height: '100%',
    borderRadius: 20,
    backgroundColor: 'rgba(255, 255, 255, 0.1)',
    justifyContent: 'center',
    alignItems: 'center',
  },
  eyePattern: {
    width: '80%',
    height: '80%',
    borderRadius: 40,
    backgroundColor: 'rgba(255, 255, 255, 0.2)',
    justifyContent: 'center',
    alignItems: 'center',
  },
  eyeCenter: {
    width: '60%',
    height: '60%',
    borderRadius: 30,
    backgroundColor: 'rgba(255, 255, 255, 0.3)',
  },
  eyeTriangle: {
    position: 'absolute',
    top: '50%',
    left: '50%',
    width: 0,
    height: 0,
    borderLeftWidth: 10,
    borderRightWidth: 10,
    borderBottomWidth: 20,
    borderStyle: 'solid',
    borderLeftColor: 'transparent',
    borderRightColor: 'transparent',
    borderBottomColor: 'transparent',
    transform: [{ rotate: '90deg' }],
  },
  cardInfo: {
    position: 'absolute',
    bottom: 10,
    left: 0,
    right: 0,
    alignItems: 'center',
    zIndex: 2,
  },
  levelContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    marginTop: 2,
  },
});
