import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';

// 게임 상수
const GAME_DURATION = 180;
const MAP_SIZE = 1000;
const TANK_HEIGHT = 0.5;
const ENEMY_GROUND_HEIGHT = 0;
const ENEMY_SCALE = 10;
const MAX_HEALTH = 1000;
const ENEMY_MOVE_SPEED = 0.1;
const ENEMY_COUNT_MAX = 3;
const PARTICLE_COUNT = 15;
const BUILDING_COUNT = 30;
const ENEMY_CONFIG = {
    ATTACK_RANGE: 100,
    ATTACK_INTERVAL: 2000,
    BULLET_SPEED: 2
};

// TankPlayer 클래스
class TankPlayer {
    constructor() {
        this.body = null;
        this.turret = null;
        this.position = new THREE.Vector3(0, 0, 0);
        this.rotation = new THREE.Euler(0, 0, 0);
        this.turretRotation = 0;
        this.moveSpeed = 0.5;
        this.turnSpeed = 0.03;
        this.turretGroup = new THREE.Group();
        this.health = MAX_HEALTH;
        this.isLoaded = false;
        this.ammo = 1;  // 변경: 10 -> 1
        this.maxAmmo = 1;  // 추가: 최대 포탄 수
        this.isReloading = false;  // 추가: 재장전 상태
        this.reloadTime = 3000;  // 추가: 3초 재장전 시간
        this.lastShootTime = 0;
        this.bullets = [];
    }

    async initialize(scene, loader) {
        try {
            const bodyResult = await loader.loadAsync('/models/abramsBody.glb');
            this.body = bodyResult.scene;
            this.body.position.copy(this.position);
            
            const turretResult = await loader.loadAsync('/models/abramsTurret.glb');
            this.turret = turretResult.scene;
            
            this.turretGroup.position.y = 0.2;
            this.turretGroup.add(this.turret);
            this.body.add(this.turretGroup);
            
            this.body.traverse((child) => {
                if (child.isMesh) {
                    child.castShadow = true;
                    child.receiveShadow = true;
                }
            });
            
            this.turret.traverse((child) => {
                if (child.isMesh) {
                    child.castShadow = true;
                    child.receiveShadow = true;
                }
            });

            scene.add(this.body);
            this.isLoaded = true;
            this.updateAmmoDisplay();  // 추가: 초기 탄약 표시
            
        } catch (error) {
            console.error('Error loading tank models:', error);
            this.isLoaded = false;
        }
    }

    shoot(scene) {
    if (this.isReloading || this.ammo <= 0) return null;

    // 발사음 효과 추가
    const sounds = ['sounds/mbtfire1.ogg', 'sounds/mbtfire2.ogg', 'sounds/mbtfire3.ogg', 'sounds/mbtfire4.ogg'];
    const randomSound = sounds[Math.floor(Math.random() * sounds.length)];
    const audio = new Audio(randomSound);
    audio.volume = 0.5;
    audio.play();

    const bullet = this.createBullet(scene);
    if (bullet) {
        this.ammo--;
        this.updateAmmoDisplay();
        this.startReload();
    }
    return bullet;
}

    createBullet(scene) {
        const bulletGeometry = new THREE.SphereGeometry(0.2);
        const bulletMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        const bullet = new THREE.Mesh(bulletGeometry, bulletMaterial);

        const bulletOffset = new THREE.Vector3(0, 0.5, 2);
        bulletOffset.applyQuaternion(this.turretGroup.quaternion);
        bulletOffset.applyQuaternion(this.body.quaternion);
        bullet.position.copy(this.body.position).add(bulletOffset);

        const direction = new THREE.Vector3(0, 0, 1);
        direction.applyQuaternion(this.turretGroup.quaternion);
        direction.applyQuaternion(this.body.quaternion);
        bullet.velocity = direction.multiplyScalar(2);

        scene.add(bullet);
        this.bullets.push(bullet);

        return bullet;
    }

    update(mouseX, mouseY, scene) {
        if (!this.body || !this.turretGroup) return;

        const absoluteTurretRotation = mouseX;
        this.turretGroup.rotation.y = absoluteTurretRotation - this.body.rotation.y;
        this.turretRotation = absoluteTurretRotation;

        for (let i = this.bullets.length - 1; i >= 0; i--) {
            const bullet = this.bullets[i];
            bullet.position.add(bullet.velocity);

            if (
                Math.abs(bullet.position.x) > MAP_SIZE / 2 ||
                Math.abs(bullet.position.z) > MAP_SIZE / 2
            ) {
                scene.remove(bullet);
                this.bullets.splice(i, 1);
            }
        }
    }

    move(direction) {
    if (!this.body) return;
    
    const moveVector = new THREE.Vector3();
    moveVector.x = direction.x * this.moveSpeed;
    moveVector.z = direction.z * this.moveSpeed;
    
    // 새로운 위치 계산
    const newPosition = this.body.position.clone().add(moveVector);
    
    // 새로운 위치의 지형 높이 가져오기
    const heightAtNewPos = window.gameInstance.getHeightAtPosition(newPosition.x, newPosition.z);
    
    // 탱크 높이만큼 더해서 지형 위에 위치시킴
    newPosition.y = heightAtNewPos + TANK_HEIGHT;
    
    // 경사가 너무 가파른지 체크
    const currentHeight = this.body.position.y;
    const heightDifference = Math.abs(newPosition.y - currentHeight);
    const maxClimbAngle = 0.5; // 최대 등반 각도
    
    if (heightDifference / this.moveSpeed < maxClimbAngle) {
        this.body.position.copy(newPosition);
        
        // 탱크의 방향 벡터 계산
        const forwardVector = new THREE.Vector3(0, 0, 1).applyQuaternion(this.body.quaternion);
        const rightVector = new THREE.Vector3(1, 0, 0).applyQuaternion(this.body.quaternion);
        
        // 탱크 주변의 높이 계산
        const frontHeight = window.gameInstance.getHeightAtPosition(
            newPosition.x + forwardVector.x,
            newPosition.z + forwardVector.z
        );
        const backHeight = window.gameInstance.getHeightAtPosition(
            newPosition.x - forwardVector.x,
            newPosition.z - forwardVector.z
        );
        const rightHeight = window.gameInstance.getHeightAtPosition(
            newPosition.x + rightVector.x,
            newPosition.z + rightVector.z
        );
        const leftHeight = window.gameInstance.getHeightAtPosition(
            newPosition.x - rightVector.x,
            newPosition.z - rightVector.z
        );
        
        // 탱크의 기울기 계산 및 적용
        const pitch = Math.atan2(frontHeight - backHeight, 2);
        const roll = Math.atan2(rightHeight - leftHeight, 2);
        
        // 기존 y축 회전은 유지하면서 새로운 기울기 적용
        const currentYRotation = this.body.rotation.y;
        this.body.rotation.set(pitch, currentYRotation, roll);
    }
}

    rotate(angle) {
        if (!this.body) return;
        
        // y축 회전 적용
        this.body.rotation.y += angle * this.turnSpeed;
        
        // 현재 위치에서의 지형에 맞춰 탱크 기울기 조정
        const position = this.body.position;
        const forwardVector = new THREE.Vector3(0, 0, 1).applyQuaternion(this.body.quaternion);
        const rightVector = new THREE.Vector3(1, 0, 0).applyQuaternion(this.body.quaternion);
        
        // 탱크 주변의 높이 계산
        const frontHeight = window.gameInstance.getHeightAtPosition(
            position.x + forwardVector.x,
            position.z + forwardVector.z
        );
        const backHeight = window.gameInstance.getHeightAtPosition(
            position.x - forwardVector.x,
            position.z - forwardVector.z
        );
        const rightHeight = window.gameInstance.getHeightAtPosition(
            position.x + rightVector.x,
            position.z + rightVector.z
        );
        const leftHeight = window.gameInstance.getHeightAtPosition(
            position.x - rightVector.x,
            position.z - rightVector.z
        );
        
        // 탱크의 기울기 계산 및 적용
        const pitch = Math.atan2(frontHeight - backHeight, 2);
        const roll = Math.atan2(rightHeight - leftHeight, 2);
        
        // 현재 y축 회전은 유지하면서 새로운 기울기 적용
        const currentYRotation = this.body.rotation.y;
        this.body.rotation.set(pitch, currentYRotation, roll);
    }
    
    getPosition() {
        return this.body ? this.body.position : new THREE.Vector3();
    }
    
    takeDamage(damage) {
        this.health -= damage;
        return this.health <= 0;
    }
    
    startReload() {
        this.isReloading = true;
        const reloadingText = document.getElementById('reloadingText');
        reloadingText.style.display = 'block';
        setTimeout(() => {
            this.ammo = this.maxAmmo;
            this.isReloading = false;
            reloadingText.style.display = 'none';
            this.updateAmmoDisplay();
        }, this.reloadTime);
    }
    
    updateAmmoDisplay() {
        document.getElementById('ammoDisplay').textContent = `APFSDS: ${this.ammo}/${this.maxAmmo}`;
    }
}

// Enemy 클래스
class Enemy {
    constructor(scene, position, type = 'tank') {
        this.scene = scene;
        this.position = position;
        this.mesh = null;
        this.type = type;
        this.health = type === 'tank' ? 100 : 200;
        this.lastAttackTime = 0;
        this.bullets = [];
        this.isLoaded = false;
        this.moveSpeed = type === 'tank' ? ENEMY_MOVE_SPEED : ENEMY_MOVE_SPEED * 0.7;
    }

    async initialize(loader) {
        try {
            const modelPath = this.type === 'tank' ? '/models/enemy1.glb' : '/models/enemy4.glb';
            const result = await loader.loadAsync(modelPath);
            this.mesh = result.scene;
            this.mesh.position.copy(this.position);
            this.mesh.scale.set(ENEMY_SCALE, ENEMY_SCALE, ENEMY_SCALE);
            
            this.mesh.traverse((child) => {
                if (child.isMesh) {
                    child.castShadow = true;
                    child.receiveShadow = true;
                }
            });
            
            this.scene.add(this.mesh);
            this.isLoaded = true;
        } catch (error) {
            console.error('Error loading enemy model:', error);
            this.isLoaded = false;
        }
    }

    update(playerPosition) {
    if (!this.mesh || !this.isLoaded) return;

    const direction = new THREE.Vector3()
        .subVectors(playerPosition, this.mesh.position)
        .normalize();
    
    const distanceToPlayer = this.mesh.position.distanceTo(playerPosition);
    const minDistance = 50;
    
    this.mesh.lookAt(playerPosition);
    
    if (distanceToPlayer > minDistance) {
        const moveVector = direction.multiplyScalar(this.moveSpeed);
        const newPosition = this.mesh.position.clone().add(moveVector);
        
        // 새로운 위치의 지형 높이 가져오기
        const heightAtNewPos = window.gameInstance.getHeightAtPosition(newPosition.x, newPosition.z);
        newPosition.y = heightAtNewPos + TANK_HEIGHT;
        
        // 경사 체크
        const heightDifference = Math.abs(newPosition.y - this.mesh.position.y);
        const maxClimbAngle = 0.5;
        
        if (heightDifference / this.moveSpeed < maxClimbAngle) {
            this.mesh.position.copy(newPosition);
            
            // 적 탱크 기울기 조정
            const forwardVector = new THREE.Vector3(0, 0, 1).applyQuaternion(this.mesh.quaternion);
            const rightVector = new THREE.Vector3(1, 0, 0).applyQuaternion(this.mesh.quaternion);
            
            const frontHeight = window.gameInstance.getHeightAtPosition(
                newPosition.x + forwardVector.x,
                newPosition.z + forwardVector.z
            );
            const backHeight = window.gameInstance.getHeightAtPosition(
                newPosition.x - forwardVector.x,
                newPosition.z - forwardVector.z
            );
            const rightHeight = window.gameInstance.getHeightAtPosition(
                newPosition.x + rightVector.x,
                newPosition.z + rightVector.z
            );
            const leftHeight = window.gameInstance.getHeightAtPosition(
                newPosition.x - rightVector.x,
                newPosition.z - rightVector.z
            );
            
            const pitch = Math.atan2(frontHeight - backHeight, 2);
            const roll = Math.atan2(rightHeight - leftHeight, 2);
            
            this.mesh.rotation.x = pitch;
            this.mesh.rotation.z = roll;
        }
    }


    // 총알 업데이트 부분
    for (let i = this.bullets.length - 1; i >= 0; i--) {
        const bullet = this.bullets[i];
        bullet.position.add(bullet.velocity);

        if (Math.abs(bullet.position.x) > MAP_SIZE || 
            Math.abs(bullet.position.z) > MAP_SIZE) {
            this.scene.remove(bullet);
            this.bullets.splice(i, 1);
        }
    }
}


    shoot(playerPosition) {
        const currentTime = Date.now();
        const attackInterval = this.type === 'tank' ? 
            ENEMY_CONFIG.ATTACK_INTERVAL : 
            ENEMY_CONFIG.ATTACK_INTERVAL * 1.5;

        if (currentTime - this.lastAttackTime < attackInterval) return;

        const bulletGeometry = new THREE.SphereGeometry(this.type === 'tank' ? 0.2 : 0.3);
        const bulletMaterial = new THREE.MeshBasicMaterial({ 
            color: this.type === 'tank' ? 0xff0000 : 0xff6600 
        });
        const bullet = new THREE.Mesh(bulletGeometry, bulletMaterial);

        bullet.position.copy(this.mesh.position);
        
        const direction = new THREE.Vector3()
            .subVectors(playerPosition, this.mesh.position)
            .normalize();
        
        const bulletSpeed = this.type === 'tank' ? 
            ENEMY_CONFIG.BULLET_SPEED : 
            ENEMY_CONFIG.BULLET_SPEED * 0.8;
        
        bullet.velocity = direction.multiplyScalar(bulletSpeed);
        
        this.scene.add(bullet);
        this.bullets.push(bullet);
        this.lastAttackTime = currentTime;
    }

    takeDamage(damage) {
        this.health -= damage;
        return this.health <= 0;
    }

    destroy() {
        if (this.mesh) {
            this.scene.remove(this.mesh);
            this.bullets.forEach(bullet => this.scene.remove(bullet));
            this.bullets = [];
            this.isLoaded = false;
        }
    }
}

// Particle 클래스
class Particle {
    constructor(scene, position) {
        const geometry = new THREE.SphereGeometry(0.1);
        const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
        this.mesh = new THREE.Mesh(geometry, material);
        this.mesh.position.copy(position);
        
        this.velocity = new THREE.Vector3(
            (Math.random() - 0.5) * 0.3,
            Math.random() * 0.2,
            (Math.random() - 0.5) * 0.3
        );
        
        this.gravity = -0.01;
        this.lifetime = 60;
        this.age = 0;
        
        scene.add(this.mesh);
    }

    update() {
        this.velocity.y += this.gravity;
        this.mesh.position.add(this.velocity);
        this.age++;
        return this.age < this.lifetime;
    }

    destroy(scene) {
        scene.remove(this.mesh);
    }
}

// Game 클래스
class Game {
    constructor() {
        this.scene = new THREE.Scene();
        this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        this.renderer = new THREE.WebGLRenderer({ antialias: true });
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.renderer.shadowMap.enabled = true;
        document.getElementById('gameContainer').appendChild(this.renderer.domElement);

        // 레이더 관련 속성 추가
        this.radarUpdateInterval = 100; // 100ms마다 레이더 업데이트
        this.lastRadarUpdate = 0;
        this.radarRange = 200; // 레이더 감지 범위

        this.tank = new TankPlayer();
        this.enemies = [];
        this.particles = [];
        this.buildings = [];
        this.loader = new GLTFLoader();
        this.controls = null;
        this.gameTime = GAME_DURATION;
        this.score = 0;
        this.isGameOver = false;
        this.isLoading = true;
        this.previousTankPosition = new THREE.Vector3();
        this.lastTime = performance.now();
        this.gameTimer = null;
        this.animationFrameId = null;

        this.mouse = { x: 0, y: 0 };
        this.keys = {
            forward: false,
            backward: false,
            left: false,
            right: false
        };

        this.setupEventListeners();
        this.initialize();
    }

    async initialize() {
        try {
            // 안개 효과 제거
            this.scene.fog = null;
            this.scene.background = new THREE.Color(0x87CEEB);

            // 주변광 설정 - 더 밝게
            const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
            this.scene.add(ambientLight);

            // 태양광 설정
            const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
            directionalLight.position.set(100, 100, 50);
            directionalLight.castShadow = true;
            directionalLight.shadow.mapSize.width = 1024;
            directionalLight.shadow.mapSize.height = 1024;
            this.scene.add(directionalLight);

            // 사막 지형 생성
            const groundGeometry = new THREE.PlaneGeometry(MAP_SIZE, MAP_SIZE, 100, 100);
            const groundMaterial = new THREE.MeshStandardMaterial({
                color: 0xD2B48C,
                roughness: 0.8,
                metalness: 0.2
            });

            const ground = new THREE.Mesh(groundGeometry, groundMaterial);
            ground.rotation.x = -Math.PI / 2;
            ground.receiveShadow = true;

            // 지형의 기복 추가
            const vertices = ground.geometry.attributes.position.array;
            let seed = Math.random() * 100;
            for (let i = 0; i < vertices.length; i += 3) {
                vertices[i + 2] = Math.sin(vertices[i] * 0.01) * Math.cos(vertices[i + 1] * 0.01) * 20;
            }

            ground.geometry.attributes.position.needsUpdate = true;
            ground.geometry.computeVertexNormals();
            
            this.scene.add(ground);

            await this.addDesertDecorations();
            await this.tank.initialize(this.scene, this.loader);
          if (!this.tank.isLoaded) {
                throw new Error('Tank loading failed');
            }

            const tankPosition = this.tank.getPosition();
            this.camera.position.set(
                tankPosition.x,
                tankPosition.y + 15,
                tankPosition.z - 30
            );
            this.camera.lookAt(tankPosition);
            
            this.isLoading = false;
            document.getElementById('loading').style.display = 'none';
            
            this.animate();
            this.spawnEnemies();
            this.startGameTimer();

        } catch (error) {
            console.error('Game initialization error:', error);
            this.handleLoadingError();
        }
    }

    // 레이더 업데이트 메서드 추가
    updateRadar() {
        const currentTime = Date.now();
        if (currentTime - this.lastRadarUpdate < this.radarUpdateInterval) return;
        
        const radar = document.getElementById('radar');
        const radarRect = radar.getBoundingClientRect();
        const radarCenter = {
            x: radarRect.width / 2,
            y: radarRect.height / 2
        };

        // 기존 적 도트 제거
        const oldDots = radar.getElementsByClassName('enemy-dot');
        while (oldDots[0]) {
            oldDots[0].remove();
        }

        // 탱크 위치 가져오기
        const tankPos = this.tank.getPosition();

        // 모든 적에 대해 레이더에 표시
        this.enemies.forEach(enemy => {
            if (!enemy.mesh || !enemy.isLoaded) return;

            const enemyPos = enemy.mesh.position;
            const distance = tankPos.distanceTo(enemyPos);

            // 레이더 범위 내에 있는 경우만 표시
            if (distance <= this.radarRange) {
                // 탱크 기준 상대 각도 계산
                const angle = Math.atan2(
                    enemyPos.x - tankPos.x,
                    enemyPos.z - tankPos.z
                );

                // 상대 거리를 레이더 크기에 맞게 스케일링
                const relativeDistance = distance / this.radarRange;
                const dotX = radarCenter.x + Math.sin(angle) * (radarCenter.x * relativeDistance);
                const dotY = radarCenter.y + Math.cos(angle) * (radarCenter.y * relativeDistance);

                // 적 도트 생성 및 추가
                const dot = document.createElement('div');
                dot.className = 'enemy-dot';
                dot.style.left = `${dotX}px`;
                dot.style.top = `${dotY}px`;
                radar.appendChild(dot);
            }
        });

        this.lastRadarUpdate = currentTime;
    }

    async addDesertDecorations() {
        // 바위 생성
        const rockGeometries = [
            new THREE.DodecahedronGeometry(3),
            new THREE.DodecahedronGeometry(2),
            new THREE.DodecahedronGeometry(4)
        ];

        const rockMaterial = new THREE.MeshStandardMaterial({
            color: 0x8B4513,
            roughness: 0.9,
            metalness: 0.1
        });

        for (let i = 0; i < 100; i++) {
            const rockGeometry = rockGeometries[Math.floor(Math.random() * rockGeometries.length)];
            const rock = new THREE.Mesh(rockGeometry, rockMaterial);
          rock.position.set(
               (Math.random() - 0.5) * MAP_SIZE * 0.9,
               Math.random() * 2,
               (Math.random() - 0.5) * MAP_SIZE * 0.9
           );
           
           rock.rotation.set(
               Math.random() * Math.PI,
               Math.random() * Math.PI,
               Math.random() * Math.PI
           );
           
           rock.scale.set(
               1 + Math.random() * 0.5,
               1 + Math.random() * 0.5,
               1 + Math.random() * 0.5
           );
           
           rock.castShadow = true;
           rock.receiveShadow = true;
           this.scene.add(rock);
       }

       // 선인장 추가 (간단한 geometry로 표현)
       const cactusGeometry = new THREE.CylinderGeometry(0.5, 0.7, 4, 8);
       const cactusMaterial = new THREE.MeshStandardMaterial({
           color: 0x2F4F2F,
           roughness: 0.8
       });

       for (let i = 0; i < 50; i++) {
           const cactus = new THREE.Mesh(cactusGeometry, cactusMaterial);
           cactus.position.set(
               (Math.random() - 0.5) * MAP_SIZE * 0.8,
               2,
               (Math.random() - 0.5) * MAP_SIZE * 0.8
           );
           cactus.castShadow = true;
           cactus.receiveShadow = true;
           this.scene.add(cactus);
       }
   }

   setupEventListeners() {
       document.addEventListener('keydown', (event) => {
           if (this.isLoading || this.isGameOver) return;
           switch(event.code) {
               case 'KeyW': this.keys.forward = true; break;
               case 'KeyS': this.keys.backward = true; break;
               case 'KeyA': this.keys.left = true; break;
               case 'KeyD': this.keys.right = true; break;
           }
       });

       document.addEventListener('keyup', (event) => {
           if (this.isLoading || this.isGameOver) return;
           switch(event.code) {
               case 'KeyW': this.keys.forward = false; break;
               case 'KeyS': this.keys.backward = false; break;
               case 'KeyA': this.keys.left = false; break;
               case 'KeyD': this.keys.right = false; break;
           }
       });

       document.addEventListener('mousemove', (event) => {
           if (this.isLoading || this.isGameOver || !document.pointerLockElement) return;

           const movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
           this.mouse.x += movementX * 0.002;
           this.mouse.y = 0;

           while (this.mouse.x > Math.PI) this.mouse.x -= Math.PI * 2;
           while (this.mouse.x < -Math.PI) this.mouse.x += Math.PI * 2;
       });

       document.addEventListener('click', () => {
           if (!document.pointerLockElement) {
               document.body.requestPointerLock();
           } else if (!this.isGameOver) {
               const bullet = this.tank.shoot(this.scene);
               if (bullet) {
                   // Shooting effects could be added here
               }
           }
       });

       document.addEventListener('pointerlockchange', () => {
           if (!document.pointerLockElement) {
               this.mouse.x = 0;
               this.mouse.y = 0;
           }
       });

       window.addEventListener('resize', () => {
           this.camera.aspect = window.innerWidth / window.innerHeight;
           this.camera.updateProjectionMatrix();
           this.renderer.setSize(window.innerWidth, window.innerHeight);
       });
   }
  handleMovement() {
       if (!this.tank.isLoaded || this.isGameOver) return;

       const direction = new THREE.Vector3();

       // 차체 이동과 회전은 유지
       if (this.keys.forward) direction.z += 1;
       if (this.keys.backward) direction.z -= 1;
       if (this.keys.left) this.tank.rotate(-1);
       if (this.keys.right) this.tank.rotate(1);

       if (direction.length() > 0) {
           direction.normalize();
           direction.applyEuler(this.tank.body.rotation);
           this.tank.move(direction);
       }

       // 탱크 위치 가져오기
       const tankPos = this.tank.getPosition();
       
       // 카메라는 마우스 X 회전에만 따라감
       const cameraDistance = 30;
       const cameraHeight = 15;
       const cameraAngle = this.mouse.x + Math.PI; // 항상 포탑의 뒤쪽에 위치
       
       const cameraX = tankPos.x + Math.sin(cameraAngle) * cameraDistance;
       const cameraZ = tankPos.z + Math.cos(cameraAngle) * cameraDistance;

       this.camera.position.set(
           cameraX,
           tankPos.y + cameraHeight,
           cameraZ
       );

       // 카메라가 탱크를 바라보도록 설정
       const lookAtPoint = new THREE.Vector3(
           tankPos.x,
           tankPos.y + 2,
           tankPos.z
       );
       this.camera.lookAt(lookAtPoint);
   }

   createBuildings() {
       const buildingTypes = [
           { width: 10, height: 30, depth: 10, color: 0x808080 },
           { width: 15, height: 40, depth: 15, color: 0x606060 },
           { width: 20, height: 50, depth: 20, color: 0x404040 }
       ];

       for (let i = 0; i < BUILDING_COUNT; i++) {
           const type = buildingTypes[Math.floor(Math.random() * buildingTypes.length)];
           const building = this.createBuilding(type);
           
           let position;
           let attempts = 0;
           do {
               position = new THREE.Vector3(
                   (Math.random() - 0.5) * (MAP_SIZE - type.width),
                   type.height / 2,
                   (Math.random() - 0.5) * (MAP_SIZE - type.depth)
               );
               attempts++;
           } while (this.checkBuildingCollision(position, type) && attempts < 50);

           if (attempts < 50) {
               building.position.copy(position);
               this.buildings.push(building);
               this.scene.add(building);
           }
       }
       return Promise.resolve();
   }

   createBuilding(type) {
       const geometry = new THREE.BoxGeometry(type.width, type.height, type.depth);
       const material = new THREE.MeshPhongMaterial({ 
           color: type.color,
           emissive: 0x222222,
           specular: 0x111111,
           shininess: 30
       });
       const building = new THREE.Mesh(geometry, material);
       building.castShadow = true;
       building.receiveShadow = true;
       return building;
   }
  checkBuildingCollision(position, type) {
       const margin = 5;
       const bbox = new THREE.Box3(
           new THREE.Vector3(
               position.x - (type.width / 2 + margin),
               0,
               position.z - (type.depth / 2 + margin)
           ),
           new THREE.Vector3(
               position.x + (type.width / 2 + margin),
               type.height,
               position.z + (type.depth / 2 + margin)
           )
       );

       return this.buildings.some(building => {
           const buildingBox = new THREE.Box3().setFromObject(building);
           return bbox.intersectsBox(buildingBox);
       });
   }

   handleLoadingError() {
       this.isLoading = false;
       const loadingElement = document.getElementById('loading');
       if (loadingElement) {
           loadingElement.innerHTML = `
               <div class="loading-text" style="color: red;">
                   Loading failed. Please refresh the page.
               </div>
           `;
       }
   }

   startGameTimer() {
       if (this.gameTimer) {
           clearInterval(this.gameTimer);
       }
       
       this.gameTimer = setInterval(() => {
           if (this.isLoading || this.isGameOver) {
               clearInterval(this.gameTimer);
               return;
           }
           
           this.gameTime--;
           document.getElementById('time').textContent = `Time: ${this.gameTime}s`;
           
           if (this.gameTime <= 0) {
               clearInterval(this.gameTimer);
               this.endGame();
           }
       }, 1000);
   }

   spawnEnemies() {
       const spawnEnemy = () => {
           if (this.enemies.length < 3 && !this.isGameOver) {  // 최대 3대로 제한
               const position = this.getValidEnemySpawnPosition();
               if (position) {
                   const type = Math.random() < 0.7 ? 'tank' : 'heavy';
                   const enemy = new Enemy(this.scene, position, type);
                   enemy.initialize(this.loader);
                   this.enemies.push(enemy);
               }
           }
           if (!this.isGameOver) {
               setTimeout(spawnEnemy, 10000);  // 10초마다 스폰
           }
       };
       
       spawnEnemy();
   }

   getValidEnemySpawnPosition() {
       const margin = 20;
       let position;
       let attempts = 0;
       const maxAttempts = 50;

       do {
           position = new THREE.Vector3(
               (Math.random() - 0.5) * (MAP_SIZE - margin * 2),
               ENEMY_GROUND_HEIGHT,
               (Math.random() - 0.5) * (MAP_SIZE - margin * 2)
           );

           const distanceToPlayer = position.distanceTo(this.tank.getPosition());
           if (distanceToPlayer < 100) continue;

           let collisionFound = false;
           for (const building of this.buildings) {
               const buildingBox = new THREE.Box3().setFromObject(building);
               if (buildingBox.containsPoint(position)) {
                   collisionFound = true;
                   break;
               }
           }

           if (!collisionFound) return position;

           attempts++;
       } while (attempts < maxAttempts);

       return null;
   }
  updateParticles() {
       for (let i = this.particles.length - 1; i >= 0; i--) {
           const particle = this.particles[i];
           if (!particle.update()) {
               particle.destroy(this.scene);
               this.particles.splice(i, 1);
           }
       }
   }

   createExplosion(position) {
       for (let i = 0; i < PARTICLE_COUNT; i++) {
           this.particles.push(new Particle(this.scene, position));
       }
   }

   checkCollisions() {
    if (this.isLoading || !this.tank.isLoaded) return;

    const tankPosition = this.tank.getPosition();
    // 적 총알과 플레이어 탱크 충돌 체크
    this.enemies.forEach(enemy => {
        if (!enemy.mesh || !enemy.isLoaded) return;

        enemy.bullets.forEach(bullet => {
            const distance = bullet.position.distanceTo(tankPosition);
            if (distance < 1) {
                if (this.tank.takeDamage(250)) { // 데미지를 250으로 수정
                    this.endGame();
                }
                this.scene.remove(bullet);
                enemy.bullets = enemy.bullets.filter(b => b !== bullet);
                
                this.createExplosion(bullet.position);
                document.getElementById('health').style.width = 
                    `${(this.tank.health / MAX_HEALTH) * 100}%`;
            }
        });
    });

    // 플레이어 총알과 적 충돌 체크
    this.tank.bullets.forEach((bullet, bulletIndex) => {
        this.enemies.forEach((enemy, enemyIndex) => {
            if (!enemy.mesh || !enemy.isLoaded) return;

            const distance = bullet.position.distanceTo(enemy.mesh.position);
            if (distance < 2) {
                if (enemy.takeDamage(50)) {
                    enemy.destroy();
                    this.enemies.splice(enemyIndex, 1);
                    this.score += 100;
                    document.getElementById('score').textContent = `Score: ${this.score}`;
                }
                this.scene.remove(bullet);
                this.tank.bullets.splice(bulletIndex, 1);
                this.createExplosion(bullet.position);
            }
        });
    });

    // 플레이어 탱크와 적 전차 충돌 체크
    const tankBoundingBox = new THREE.Box3().setFromObject(this.tank.body);
    this.enemies.forEach(enemy => {
        if (!enemy.mesh || !enemy.isLoaded) return;
        
        const enemyBoundingBox = new THREE.Box3().setFromObject(enemy.mesh);
        if (tankBoundingBox.intersectsBox(enemyBoundingBox)) {
            this.tank.body.position.copy(this.previousTankPosition);
        }
    });

    // 이전 위치 저장
    this.previousTankPosition.copy(this.tank.body.position);
}
  endGame() {
       if (this.isGameOver) return;
       
       this.isGameOver = true;
       
       if (this.gameTimer) {
           clearInterval(this.gameTimer);
       }

       if (this.animationFrameId) {
           cancelAnimationFrame(this.animationFrameId);
       }

       document.exitPointerLock();

       const gameOverDiv = document.createElement('div');
       gameOverDiv.style.position = 'absolute';
       gameOverDiv.style.top = '50%';
       gameOverDiv.style.left = '50%';
       gameOverDiv.style.transform = 'translate(-50%, -50%)';
       gameOverDiv.style.color = '#0f0';
       gameOverDiv.style.fontSize = '48px';
       gameOverDiv.style.backgroundColor = 'rgba(0, 20, 0, 0.7)';
       gameOverDiv.style.padding = '20px';
       gameOverDiv.style.borderRadius = '10px';
       gameOverDiv.style.textAlign = 'center';
       gameOverDiv.innerHTML = `
           Game Over<br>
           Score: ${this.score}<br>
           Time Survived: ${GAME_DURATION - this.gameTime}s<br>
           <button onclick="location.reload()" 
                   style="font-size: 24px; padding: 10px; margin-top: 20px; 
                          cursor: pointer; background: #0f0; border: none; 
                          color: black; border-radius: 5px;">
               Play Again
           </button>
       `;
       document.body.appendChild(gameOverDiv);
   }

   updateUI() {
       if (!this.isGameOver) {
           const healthBar = document.getElementById('health');
           if (healthBar) {
               healthBar.style.width = `${(this.tank.health / MAX_HEALTH) * 100}%`;
           }

           const timeElement = document.getElementById('time');
           if (timeElement) {
               timeElement.textContent = `Time: ${this.gameTime}s`;
           }

           const scoreElement = document.getElementById('score');
           if (scoreElement) {
               scoreElement.textContent = `Score: ${this.score}`;
           }
       }
   }

   animate() {
       if (this.isGameOver) {
           if (this.animationFrameId) {
               cancelAnimationFrame(this.animationFrameId);
           }
           return;
       }

       this.animationFrameId = requestAnimationFrame(() => this.animate());

       const currentTime = performance.now();
       const deltaTime = (currentTime - this.lastTime) / 1000;
       this.lastTime = currentTime;

       if (!this.isLoading) {
           this.handleMovement();
           this.tank.update(this.mouse.x, this.mouse.y, this.scene);
           
           const tankPosition = this.tank.getPosition();
           this.enemies.forEach(enemy => {
               enemy.update(tankPosition);
               
               if (enemy.isLoaded && enemy.mesh.position.distanceTo(tankPosition) < ENEMY_CONFIG.ATTACK_RANGE) {
                   enemy.shoot(tankPosition);
               }
           });

           this.updateParticles();
           this.checkCollisions();
           this.updateUI();
           this.updateRadar(); // 레이더 업데이트 추가
       }
       
       this.renderer.render(this.scene, this.camera);
   }
}

// Start game
window.startGame = function() {
   document.getElementById('startScreen').style.display = 'none';
   document.body.requestPointerLock();
   
   // Create new game instance or restart existing one
   if (!window.gameInstance) {
       window.gameInstance = new Game();
   }
};

// Initialize game
document.addEventListener('DOMContentLoaded', () => {
   const game = new Game();
});