<template>
  <div ref="container" class="w-full h-full min-h-100"></div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as THREE from 'three'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

const container = ref(null)
let renderer, scene, camera, controls, animationId

onMounted(() => {
  initScene()
  loadModel()
  animate()
  window.addEventListener('resize', onResize)
})

onUnmounted(() => {
  cancelAnimationFrame(animationId)
  renderer?.dispose()
  window.removeEventListener('resize', onResize)
})

function initScene() {
  scene = new THREE.Scene()
  scene.background = null

  camera = new THREE.PerspectiveCamera(
    45,
    container.value.clientWidth / container.value.clientHeight,
    0.01,
    1000
  )
  camera.position.set(0, 0, 5)

  renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true })
  renderer.setSize(container.value.clientWidth, container.value.clientHeight)
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
  container.value.appendChild(renderer.domElement)

  // Освещение
  scene.add(new THREE.AmbientLight(0x404060, 1.8))
  const sun = new THREE.DirectionalLight(0xffffff, 2.2)
  sun.position.set(5, 3, 5)
  scene.add(sun)
  const back = new THREE.DirectionalLight(0x3366aa, 0.5)
  back.position.set(-3, -1, -3)
  scene.add(back)

  // OrbitControls (только вращение)
  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.dampingFactor = 0.08
  controls.autoRotate = true
  controls.autoRotateSpeed = 0.4
  controls.enableZoom = false
  controls.enablePan = false
  controls.target.set(0, 0, 0)
}

function loadModel() {
  const basePath = '/models/earth/'

  new MTLLoader()
    .setPath(basePath)
    .load('Earth 2K.mtl', (materials) => {
      materials.preload()

      new OBJLoader()
        .setMaterials(materials)
        .setPath(basePath)
        .load('Earth 2K.obj', (object) => {
          // Применяем текстуры (с DoubleSide и needsUpdate)
          applyTextures(object)

          // Группа только для непрозрачной Земли (без облаков и атмосферы)
          const earthGroup = new THREE.Group()
          object.traverse((child) => {
            if (!child.isMesh) return
            const matName = child.material?.name?.toLowerCase() || ''
            if (!matName.includes('atmosphere') && !matName.includes('cloud')) {
              earthGroup.add(child.clone())
            }
          })

          // Вычисляем bounding sphere только для Земли
          const earthSphere = new THREE.Sphere()
          if (earthGroup.children.length > 0) {
            new THREE.Box3().setFromObject(earthGroup).getBoundingSphere(earthSphere)
          } else {
            // fallback
            new THREE.Box3().setFromObject(object).getBoundingSphere(earthSphere)
          }

          // Центрируем ВСЮ модель (с облаками) по центру Земли
          object.position.sub(earthSphere.center)
          object.position.y += 0.1

          // Расстояние камеры, чтобы земная сфера заняла экран с отступом 2%
          const radius = earthSphere.radius * 0.6
          const aspect = container.value.clientWidth / container.value.clientHeight
          const fovRad = camera.fov * Math.PI / 180
          const distanceH = radius / Math.sin(fovRad / 2) / aspect
          const distanceV = radius / Math.sin(fovRad / 2)
          const finalDistance = Math.max(distanceH, distanceV)

          camera.position.set(0, radius * 0.1, finalDistance)
          camera.lookAt(0, 0, 0)
          controls.target.set(0, 0, 0)
          controls.update()

          scene.add(object)
          console.log('🌍 Земля вписана, радиус Земли:', earthSphere.radius.toFixed(2))
        })
    })
}

function applyTextures(object) {
  const loader = new THREE.TextureLoader()
  const texPath = '/models/earth/Textures/'

  const textures = {
    diffuse: loader.load(texPath + 'Diffuse_2K.png'),
    bump: loader.load(texPath + 'Bump_2K.png'),
    clouds: loader.load(texPath + 'Clouds_2K.png'),
    night: loader.load(texPath + 'Night_lights_2K.png'),
    oceanMask: loader.load(texPath + 'Ocean_Mask_2K.png')
  }

  object.traverse((child) => {
    if (!child.isMesh) return
    const matName = child.material?.name?.toLowerCase() || ''

    if (matName.includes('atmosphere')) {
    child.material = new THREE.MeshStandardMaterial({
      color: 0x4488ff,
      transparent: true,
      opacity: 0.1,               // уменьшена плотность
      roughness: 1,
      metalness: 0,
      side: THREE.DoubleSide,
      depthWrite: false           // не перекрывает то, что сзади
  })
  } else if (matName.includes('cloud')) {
    child.material = new THREE.MeshStandardMaterial({
      map: textures.clouds,
      transparent: true,
      opacity: 0.5,               // облака стали прозрачнее
      roughness: 0.8,
      metalness: 0,
      side: THREE.DoubleSide,
      depthWrite: false           // ключевая строка
    })
    } else {
      child.material = new THREE.MeshStandardMaterial({
        map: textures.diffuse,
        bumpMap: textures.bump,
        bumpScale: 0.04,
        roughnessMap: textures.oceanMask,
        roughness: 0.6,
        metalnessMap: textures.oceanMask,
        metalness: 0.2,
        emissiveMap: textures.night,
        emissive: new THREE.Color(0xffaa33),
        emissiveIntensity: 0.5,
        side: THREE.DoubleSide
      })
    }
    child.material.needsUpdate = true
  })
}

function onResize() {
  if (!container.value) return
  camera.aspect = container.value.clientWidth / container.value.clientHeight
  camera.updateProjectionMatrix()
  renderer.setSize(container.value.clientWidth, container.value.clientHeight)
}

function animate() {
  animationId = requestAnimationFrame(animate)
  controls.update()
  renderer.render(scene, camera)
}
</script>