// 3D 지형 시각화 모듈
var Terrain3D = (function() {
    var scene, camera, renderer, terrain, water;
    var isInitialized = false;
    var animationId = null;

    // 지형 초기화
    function init(containerId) {
        var container = document.getElementById(containerId);
        if (!container) return;

        // 이미 초기화된 경우 리사이즈만 처리
        if (isInitialized && renderer) {
            onWindowResize(container);
            return;
        }

        // Scene 생성
        scene = new THREE.Scene();
        scene.background = new THREE.Color(0x1a1a2e);

        // 카메라 설정
        var width = container.clientWidth;
        var height = container.clientHeight;
        camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 1000);
        camera.position.set(0, 40, 60);
        camera.lookAt(0, 0, 0);

        // 렌더러 설정
        renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(width, height);
        renderer.setPixelRatio(window.devicePixelRatio);
        container.appendChild(renderer.domElement);

        // 조명 추가
        var ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
        scene.add(ambientLight);

        var directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(50, 100, 50);
        scene.add(directionalLight);

        // 지형 생성
        createTerrain();

        // 물 표면 생성
        createWater();

        // 마우스 컨트롤
        setupControls(container);

        // 리사이즈 이벤트
        window.addEventListener('resize', function() {
            onWindowResize(container);
        });

        isInitialized = true;

        // 애니메이션 시작
        animate();
    }

    // 지형 생성
    function createTerrain() {
        var geometry = new THREE.PlaneGeometry(80, 80, 64, 64);
        geometry.rotateX(-Math.PI / 2);

        // 높이 데이터 생성 (Perlin noise 시뮬레이션)
        var vertices = geometry.attributes.position.array;
        for (var i = 0; i < vertices.length; i += 3) {
            var x = vertices[i];
            var z = vertices[i + 2];

            // 여러 주파수의 노이즈 조합
            var height = 0;
            height += Math.sin(x * 0.1) * Math.cos(z * 0.1) * 8;
            height += Math.sin(x * 0.2 + 1) * Math.cos(z * 0.15) * 4;
            height += Math.sin(x * 0.05) * Math.cos(z * 0.08) * 6;

            // 중앙에 분지(물이 고일 곳) 생성
            var distFromCenter = Math.sqrt(x * x + z * z);
            if (distFromCenter < 15) {
                height = Math.min(height, -3 + distFromCenter * 0.2);
            }

            vertices[i + 1] = height;
        }

        geometry.computeVertexNormals();

        // 높이에 따른 색상 적용
        var colors = [];
        for (var i = 0; i < vertices.length; i += 3) {
            var height = vertices[i + 1];
            var color = getColorForHeight(height);
            colors.push(color.r, color.g, color.b);
        }

        geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

        var material = new THREE.MeshLambertMaterial({
            vertexColors: true,
            side: THREE.DoubleSide
        });

        terrain = new THREE.Mesh(geometry, material);
        scene.add(terrain);
    }

    // 높이에 따른 색상 반환
    function getColorForHeight(height) {
        var color = new THREE.Color();

        if (height < -2) {
            // 낮은 지역 - 심각 (빨강)
            color.setRGB(0.91, 0.30, 0.24);
        } else if (height < 2) {
            // 중간 낮음 - 높음 (주황)
            color.setRGB(0.90, 0.49, 0.13);
        } else if (height < 6) {
            // 중간 - 보통 (노랑)
            color.setRGB(0.95, 0.77, 0.06);
        } else {
            // 높은 지역 - 낮음 (초록)
            color.setRGB(0.15, 0.68, 0.38);
        }

        return color;
    }

    // 물 표면 생성
    function createWater() {
        var waterGeometry = new THREE.CircleGeometry(12, 32);
        waterGeometry.rotateX(-Math.PI / 2);

        var waterMaterial = new THREE.MeshLambertMaterial({
            color: 0x3498db,
            transparent: true,
            opacity: 0.7
        });

        water = new THREE.Mesh(waterGeometry, waterMaterial);
        water.position.y = -2;
        scene.add(water);
    }

    // 마우스 컨트롤 설정
    function setupControls(container) {
        var isDragging = false;
        var previousMousePosition = { x: 0, y: 0 };
        var rotationSpeed = 0.005;
        var targetRotationY = 0;

        container.addEventListener('mousedown', function(e) {
            isDragging = true;
            previousMousePosition = { x: e.clientX, y: e.clientY };
        });

        container.addEventListener('mousemove', function(e) {
            if (!isDragging) return;

            var deltaX = e.clientX - previousMousePosition.x;
            targetRotationY += deltaX * rotationSpeed;

            previousMousePosition = { x: e.clientX, y: e.clientY };
        });

        container.addEventListener('mouseup', function() {
            isDragging = false;
        });

        container.addEventListener('mouseleave', function() {
            isDragging = false;
        });

        // 마우스 휠 줌
        container.addEventListener('wheel', function(e) {
            e.preventDefault();
            var zoomSpeed = 0.1;
            camera.position.z += e.deltaY * zoomSpeed;
            camera.position.z = Math.max(30, Math.min(100, camera.position.z));
            camera.position.y = camera.position.z * 0.67;
        });

        // 애니메이션에서 회전 적용
        setInterval(function() {
            if (terrain) {
                terrain.rotation.y += (targetRotationY - terrain.rotation.y) * 0.1;
                if (water) water.rotation.y = terrain.rotation.y;
            }
        }, 16);
    }

    // 윈도우 리사이즈 처리
    function onWindowResize(container) {
        if (!camera || !renderer) return;

        var width = container.clientWidth;
        var height = container.clientHeight;

        camera.aspect = width / height;
        camera.updateProjectionMatrix();
        renderer.setSize(width, height);
    }

    // 애니메이션 루프
    function animate() {
        animationId = requestAnimationFrame(animate);

        // 물 애니메이션
        if (water) {
            water.position.y = -2 + Math.sin(Date.now() * 0.001) * 0.1;
        }

        if (renderer && scene && camera) {
            renderer.render(scene, camera);
        }
    }

    // 정리
    function dispose() {
        if (animationId) {
            cancelAnimationFrame(animationId);
        }
        if (renderer) {
            renderer.dispose();
        }
        isInitialized = false;
    }

    return {
        init: init,
        dispose: dispose
    };
})();
