import sunImg from "../assets/textures/corona.png"
import starsImg from "../assets/textures/stars.png"
import moonImg from "../assets/textures/moon.png"

const {
  TextureLoader,
  SphereGeometry,
  ShaderMaterial,
  MeshBasicMaterial,
  Color,
  RepeatWrapping,
  BackSide,
  Mesh,
  DirectionalLight,
  AmbientLight,
  AdditiveBlending,
  Group,
} = window.VgoMap.THREE

export function useSkyLight(map) {
  let skyDome = null
  let sun = null
  let moon = null
  let stars = null
  let sunLight = null
  let moonLight = null
  let ambientLight = null
  const skyGroup = new Group()
  const loader = new TextureLoader()
  document.querySelector("#sky-mask").remove()
  
  
  // 加载贴图
  const sunTexture = loader.load(sunImg)
  const starsTexture = loader.load(starsImg)
  const moonTexture = loader.load(moonImg)
  
  const skyColorKeyframes = [
    {
      time: 0,
      top: new Color(0x090b12),
      bottom: new Color(0x0f131d)
    },
    {
      time: 240,
      top: new Color(0x090b12),
      bottom: new Color(0x0f131d)
    },
    {
      time: 360,
      top: new Color(0x87ceeb),
      bottom: new Color(0xd8f2ff)
    },
    {
      time: 720,
      top: new Color(0x87ceeb),
      bottom: new Color(0xd8f2ff)
    },
    {
      time: 1020,
      top: new Color(0x87ceeb),
      bottom: new Color(0xd8f2ff)
    },
    {
      time: 1080,
      top: new Color(0x090b12),
      bottom: new Color(0x0f131d)
    },
    {
      time: 1440,
      top: new Color(0x090b12),
      bottom: new Color(0x0f131d)
    }
  ]

  // 初始化天空
  const init = () => {
    createSkyDome()
    createSun()
    createMoon()
    createStars()
    createLights()
    setupScene()
  }
  
  // 创建天空穹顶
  const createSkyDome = () => {
    const geometry = new SphereGeometry(8000, 64, 64)
    const material = new ShaderMaterial({
      uniforms: {
        topColor: { value: new Color(0x87ceeb) },
        bottomColor: { value: new Color(0xd8f2ff) },
        sunsetColor: { value: new Color(0xff6b35) },
        twilightColor: { value: new Color(0xffa07a) },
        offset: { value: 0 },
        exponent: { value: 0.6 },
        sunPosition: { value: { x: 0, y: 0, z: -7900 } },
        isSunset: { value: 0.0 }
      },
      vertexShader: `
        varying vec3 vWorldPosition;
        void main() {
          vec4 worldPosition = modelMatrix * vec4(position, 1.0);
          vWorldPosition = worldPosition.xyz;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        uniform vec3 topColor;
        uniform vec3 bottomColor;
        uniform vec3 sunsetColor;
        uniform vec3 twilightColor;
        uniform float offset;
        uniform float exponent;
        uniform vec3 sunPosition;
        uniform float isSunset;
        varying vec3 vWorldPosition;
        
        // 简单的云层噪声函数
        float hash(vec2 p) {
          return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
        }
        
        float noise(vec2 p) {
          vec2 i = floor(p);
          vec2 f = fract(p);
          f = f * f * (3.0 - 2.0 * f);
          float a = hash(i);
          float b = hash(i + vec2(1.0, 0.0));
          float c = hash(i + vec2(0.0, 1.0));
          float d = hash(i + vec2(1.0, 1.0));
          return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
        }
        
        void main() {
          vec3 normalized = normalize(vWorldPosition);
          float h = normalized.z;
          
          // 基础天空颜色渐变
          vec3 skyColor = mix(bottomColor, topColor, max(pow(max(h, 0.0), exponent), 0.0));
          
          // 黄昏效果：仅在太阳临近地平线时显示
          if (isSunset > 0.0) {
            // 计算与太阳方向的角度
            vec3 sunDir = normalize(sunPosition);
            float sunDot = dot(normalized, sunDir);
            
            // 检查太阳是否临近地平线（z值接近0）
            float sunHorizonDist = abs(sunDir.z);
            float sunNearHorizon = smoothstep(0.25, 0.0, sunHorizonDist); // 进一步收紧太阳接近地平线的范围
            
            // 地平线因子：极度接近地平线时值更大（进一步缩小范围）
            float horizonFactor = 1.0 - abs(h);
            horizonFactor = pow(horizonFactor, 6.0); // 提高幂次至6，大幅缩小范围
            
            // 太阳方向因子：极度接近太阳方向才显示（进一步收紧范围）
            float sunFactor = smoothstep(0.5, 0.9, sunDot); // 从0.3-0.85收紧到0.5-0.9
            
            // 云层仅在太阳附近显示的因子
            float cloudSunProximity = smoothstep(0.4, 0.8, sunDot); // 云层只在接近太阳方向显示
            
            // 添加多层云层效果，增加密度
            vec2 cloudUV = vec2(atan(normalized.x, normalized.y) * 3.0, asin(normalized.z) * 6.0);
            
            // 第一层云：较大的云团
            float cloudNoise1 = noise(cloudUV * 3.5);
            cloudNoise1 = pow(cloudNoise1, 1.8);
            
            // 第二层云：中等云团
            float cloudNoise2 = noise(cloudUV * 6.0);
            cloudNoise2 = pow(cloudNoise2, 2.0);
            
            // 第三层云：细小云丝
            float cloudNoise3 = noise(cloudUV * 10.0);
            cloudNoise3 = pow(cloudNoise3, 2.5);
            
            // 组合多层云，增加密度
            float cloudNoise = cloudNoise1 * 0.5 + cloudNoise2 * 0.3 + cloudNoise3 * 0.2;
            
            // 云层遮罩：仅在地平线和太阳附近显示
            float cloudLayer = smoothstep(0.35, 0.65, cloudNoise) * horizonFactor * cloudSunProximity * 0.8;
            
            // 综合因子（添加太阳位置检测）
            float sunsetFactor = horizonFactor * sunFactor * sunNearHorizon * isSunset;
            
            // 黄昏颜色渐变（柔和的橙色调）
            vec3 deepOrange = vec3(0.9, 0.5, 0.3);
            vec3 brightOrange = vec3(1.0, 0.65, 0.4);
            vec3 duskColor = mix(deepOrange, brightOrange, sunFactor * 0.6);
            
            // 云层受黄昏颜色影响（降低对比度）
            vec3 cloudColor = mix(duskColor * 0.85, duskColor * 1.15, cloudNoise);
            
            // 混合黄昏颜色和云层（降低混合强度）
            skyColor = mix(skyColor, duskColor, sunsetFactor * 0.35);
            skyColor = mix(skyColor, cloudColor, cloudLayer * sunsetFactor * isSunset * 0.6);
          }
          
          gl_FragColor = vec4(skyColor, 1.0);
        }
      `,
      side: BackSide
    })
    
    skyDome = new Mesh(geometry, material)
    skyDome.name = 'sky'
  }
  
  // 创建太阳
  const createSun = () => {
    // 创建太阳核心
    const coreGeometry = new SphereGeometry(180, 32, 32)
    const coreMaterial = new MeshBasicMaterial({
      color: new Color(0xFFA500), // 调整为稍冷的橙色
      transparent: true,
      blending: AdditiveBlending
    })
    
    const core = new Mesh(coreGeometry, coreMaterial)
    
    // 创建日冕效果
    const coronaGeometry = new SphereGeometry(3200, 32, 32)
    const coronaMaterial = new MeshBasicMaterial({
      map: sunTexture,
      transparent: true,
      blending: AdditiveBlending,
      opacity: 0.05,
      color: new Color(0xFF8C00) // 调整为稍冷的橙色日冕
    })
    
    const corona = new Mesh(coronaGeometry, coronaMaterial)
    
    // 组合太阳
    sun = new Group()
    sun.add(core)
    sun.add(corona)
    sun.name = 'sun'
    sun.position.set(0, 0, -7900) // 初始位置调整为垂直地平线方向
  }
  
  // 创建月亮
  const createMoon = () => {
    const geometry = new SphereGeometry(200, 32, 32) // 增大月亮尺寸
    const material = new MeshBasicMaterial({
      map: moonTexture,
      transparent: true,
      blending: AdditiveBlending
    })
    
    moon = new Mesh(geometry, material)
    moon.name = 'moon'
    moon.position.set(0, 0, 7900) // 初始位置调整为垂直地平线方向
  }
  
  // 创建星空
  const createStars = () => {
    starsTexture.wrapS = RepeatWrapping
    starsTexture.wrapT = RepeatWrapping
    starsTexture.repeat.set(10, 10)
    
    const geometry = new SphereGeometry(10000, 32, 32)
    const material = new MeshBasicMaterial({
      map: starsTexture,
      transparent: true,
      blending: AdditiveBlending,
      side: BackSide,
      opacity: 0.8
    })
    
    stars = new Mesh(geometry, material)
    stars.name = 'stars'
  }
  
  // 创建光源
  const createLights = () => {
    // 太阳光
    sunLight = new DirectionalLight(0xffffff, 1)
    sunLight.position.set(0, 0, -1000)
    sunLight.castShadow = true
    
    // 月光
    moonLight = new DirectionalLight(0x333366, 0.5)
    moonLight.position.set(0, 0, 1000)
    
    // 环境光
    ambientLight = new AmbientLight(0x404040, 0.1)
  }
  
  // 设置场景
  const setupScene = () => {
    skyGroup.add(skyDome)
    skyGroup.add(sun)
    skyGroup.add(moon)
    skyGroup.add(stars)
    skyGroup.add(sunLight)
    skyGroup.add(moonLight)
    skyGroup.add(ambientLight)
    map.scene.add(skyGroup)
  }
  
  // 设置时间（分钟数，0-1440代表一天）
  const setTime = (minutes) => {
    if (minutes < 0 || minutes > 1440) return
    
    // 计算太阳和月亮的位置（垂直方向圆周运动，自东向西）
    const angle = -(minutes / 1440) * Math.PI * 2 // 负号反转方向，使其自东向西
    const radius = -7900
    const sunY = Math.sin(angle) * radius
    const sunZ = Math.cos(angle) * radius
    const sunX = 0 // X轴位置保持为0，只在YZ平面旋转
    
    // 更新太阳位置
    sun.position.set(sunX, sunY, sunZ)
    sunLight.position.set(sunX, sunY, sunZ)
    if(minutes > 1080 || minutes < 360) {
      sun.visible = false
    } else {
      sun.visible = true
    }
    
    // 更新月亮位置（与太阳相对）
    moon.position.set(sunX, -sunY, -sunZ)
    moonLight.position.set(sunX, -sunY, -sunZ)

    if(minutes > 360 && minutes < 1080 ) {
      moon.visible = false
    } else {
      moon.visible = true
    }
    
    // 根据时间调整光照强度和颜色
    updateLighting(minutes)
    
    // 根据时间调整天空颜色
    updateSkyColor(minutes)
    
    // 根据时间调整星空可见度
    updateStarsVisibility(minutes)
  }
  
  // 更新光照
  const updateLighting = (minutes) => {
    // 日出日落时段
    if (minutes > 360 && minutes < 480) { // 6:00-8:00
      const progress = (minutes - 360) / 120
      sunLight.intensity = progress
      sunLight.color.setRGB(1, progress * 0.7 + 0.3, progress * 0.3 + 0.7)
      moonLight.intensity = 0.2
      // ambientLight.intensity = 0.2 + progress * 0.3
    } 
    // 正午时段
    else if (minutes >= 480 && minutes <= 960) { // 8:00-16:00
      sunLight.intensity = 1.5
      sunLight.color.setRGB(1, 1, 1)
      moonLight.intensity = 0
      // ambientLight.intensity = 0.5
    } 
    // 日落时段
    else if (minutes > 960 && minutes < 1080) { // 16:00-18:00
      const progress = 1 - (minutes - 960) / 120
      sunLight.intensity = progress + 0.2
      sunLight.color.setRGB(1, progress * 0.7 + 0.3, progress * 0.3 + 0.7)
      moonLight.intensity = 0
      // ambientLight.intensity = 0.2 + progress * 0.3
    } 
    // 夜晚时段
    else {
      sunLight.intensity = 0
      moonLight.intensity = 0.5
      // ambientLight.intensity = 0.1
    }
  }
  
  // 更新天空颜色
  const updateSkyColor = (minutes) => {
    const material = skyDome.material
    const normalizedMinutes = minutes === 1440 ? 0 : minutes
    let currentFrame = skyColorKeyframes[0]
    let nextFrame = skyColorKeyframes[skyColorKeyframes.length - 1]

    for (let i = 0; i < skyColorKeyframes.length - 1; i++) {
      const frame = skyColorKeyframes[i]
      const following = skyColorKeyframes[i + 1]
      if (normalizedMinutes >= frame.time && normalizedMinutes < following.time) {
        currentFrame = frame
        nextFrame = following
        break
      }
    }

    const segmentDuration = nextFrame.time - currentFrame.time || 1
    const progress = (normalizedMinutes - currentFrame.time) / segmentDuration

    material.uniforms.topColor.value
      .copy(currentFrame.top)
      .lerp(nextFrame.top, progress)

    material.uniforms.bottomColor.value
      .copy(currentFrame.bottom)
      .lerp(nextFrame.bottom, progress)
    
    // 更新太阳位置用于黄昏效果
    material.uniforms.sunPosition.value = {
      x: sun.position.x,
      y: sun.position.y,
      z: sun.position.z
    }
    
    // 仅在太阳临近地平线时显示黄昏效果（缩短时间范围）
    let sunsetIntensity = 0.0
    if (normalizedMinutes >= 270 && normalizedMinutes <= 330) {
      // 日出黄昏：270-300最强，300-330逐渐减弱
      if (normalizedMinutes <= 300) {
        sunsetIntensity = (normalizedMinutes - 270) / 30
      } else {
        sunsetIntensity = 1.0 - (normalizedMinutes - 300) / 30
      }
    } else if (normalizedMinutes >= 1050 && normalizedMinutes <= 1110) {
      // 日落黄昏：1050-1080最强，1080-1110逐渐减弱
      if (normalizedMinutes <= 1080) {
        sunsetIntensity = (normalizedMinutes - 1050) / 30
      } else {
        sunsetIntensity = 1.0 - (normalizedMinutes - 1080) / 30
      }
    }
    
    material.uniforms.isSunset.value = sunsetIntensity
  }
  
  // 更新星空可见度
  const updateStarsVisibility = (minutes) => {
    // 夜晚时显示星空 (18:00-6:00)
    if ((minutes >= 0 && minutes <= 360) || (minutes >= 1080 && minutes <= 1440)) {
      stars.visible = true
      // 在夜晚时段内，0:00-6:00 和 18:00-24:00 有不同的透明度变化
      let opacity = 0;
      if (minutes >= 1080) { // 18:00-24:00
        opacity = Math.min(1, (minutes - 1080) / 180); // 3小时渐显
      } else if (minutes <= 360) { // 0:00-6:00
        opacity = Math.min(1, (360 - minutes) / 180); // 3小时渐显
      }
      stars.material.opacity = opacity;
    } else {
      stars.visible = false;
    }
  }
  
  return {
    skyGroup,
    init,
    setTime,
  }
}
