import { ref } from 'vue'
import { getMubiaoHisTraj } from '@/api/mubiao'
import { point, bearing } from '@turf/turf'
import { cartesian32LonLat } from '@/utils/pos'

type TPoints = { time: number; position: Cesium.Cartesian3 }[]

const showHisTrajCom = ref(false)
const mbData = ref({})

export const useMBTrajectory = () => {
  let entities: Cesium.Entity[] = []

  let mbTarget: Cesium.Entity | null = null

  const isFollow = ref(false)
  watch(isFollow, follow => {
    !follow && setDefaultView()
  })
  const times = ref<number[]>([])
  // const posArray = ref([])
  // const points = ref([])

  const customElapsedTime = ref<number>(0)
  const animationSpeed = ref<number>(1)
  const lastFrameTime = ref<number>(performance.now())
  const isAnimationRunning = ref<boolean>(false)
  const isPaused = ref<boolean>(false)

  async function loadHisTraj(id: string, timeRange: string[]) {
    const { points, posArray, timeArray } = await getHisTraj({
      id,
      timeRange,
    })
    times.value = timeArray
    if (timeArray.length <= 1) return

    // const pathLine = createPathLine(posArray as number[])
    createTarget(points, posArray as number[])
  }

  function showOrHideHisTraj(data) {
    // console.log(data, '<======>')
    mbData.value = data
    showHisTrajCom.value = !showHisTrajCom.value

    removeEntities()
  }

  function createTarget(points: TPoints, posArray: number[]) {
    const totalAnimationTime = points[points.length - 1].time
    // console.log('totalAnimationTime', totalAnimationTime)

    const positionProperty = new Cesium.SampledPositionProperty()
    const startTime = Cesium.JulianDate.now()
    // 添加路径点到位置属性
    points.forEach(point => {
      const pointEntity = createPoint(point.position)
      entities.push(pointEntity)
      const time = Cesium.JulianDate.addSeconds(
        Cesium.JulianDate.now(),
        point.time,
        new Cesium.JulianDate()
      )
      positionProperty.addSample(time, point.position)
    })
    // positionProperty.setInterpolationOptions({
    //   //二次多项式进行插值。二次多项式插值相较于线性插值会更光滑，但不如高阶多项式平滑
    //   interpolationDegree: 2,
    //   //赫尔米特多项式插值算法。使得插值曲线能够平滑过渡，并且可以更好地控制运动的速度和方向变化
    //   interpolationAlgorithm: Cesium.HermitePolynomialApproximation,
    // })
    // positionProperty._time.map(time => {
    //   console.log(positionProperty.getValue(time), 'getValue')
    // })
    // 获取 line 插值后的值
    // const linePositions = []
    // const endTime = Cesium.JulianDate.addSeconds(
    //   startTime,
    //   totalAnimationTime,
    //   new Cesium.JulianDate()
    // )
    // for (let now = startTime; now < endTime; ) {
    //   const posi = positionProperty.getValue(now)
    //   const pos = new Cesium.Cartesian3(posi.x, posi.y, posi.z)
    //   linePositions.push(pos) // 把所有的坐标放到newPosition数组中
    //   now = Cesium.JulianDate.addSeconds(now, 30, new Cesium.JulianDate())
    // }
    // console.log(linePositions)
    // 创建实体
    mbTarget = viewer.entities.add({
      position: new Cesium.CallbackProperty(() => {
        if (!isAnimationRunning.value) {
          return points[0].position
        }
        console.log(positionProperty.getValue(customElapsedTime.value), '---')
        return positionProperty.getValue(customElapsedTime.value)
      }, false),
      // point: { pixelSize: 10, color: Cesium.Color.RED },
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArrayHeights(posArray),
        // positions: linePositions,
        width: 5,
        // material: new Cesium.PolylineTrailLinkMaterialProperty({
        //   color: Cesium.Color.YELLOW,
        //   duration: 3000,
        // }),
        material: new Cesium.PolylineGlowMaterialProperty({
          glowPower: 0.1,
          color: Cesium.Color.ORANGE,
        }),
        clampToGround: true,
      },
      // path: {
      //   resolution: 1,
      //   width: 5,
      //   material: new Cesium.PolylineGlowMaterialProperty({
      //     glowPower: 0.1,
      //     color: Cesium.Color.ORANGE,
      //   }),
      // },
      model: {
        uri: '/models/驱逐舰2.glb',
        minimumPixelSize: 200,
        maximumScale: 10000,
      },
      // orientation: ,
    })
    // entities.push(entity)
    // entity
    viewer.scene.preRender.addEventListener(() => {
      if (!isAnimationRunning.value || isPaused.value) {
        return
      }

      const currentFrameTime = performance.now() // 当前帧的时间戳
      const deltaTime = (currentFrameTime - lastFrameTime.value) / 1000 // 计算渲染帧之间的时间差（秒）
      lastFrameTime.value = currentFrameTime // 更新上一次帧的时间戳

      // 根据倍速调整动画时间
      customElapsedTime.value += deltaTime * animationSpeed.value

      // 判断是否达到动画结束时间
      if (customElapsedTime.value >= totalAnimationTime) {
        customElapsedTime.value = totalAnimationTime // 限制时间为总时长
        isAnimationRunning.value = false // 停止动画
      }

      // 计算自定义时间下的位置
      const customTime = Cesium.JulianDate.addSeconds(
        startTime,
        customElapsedTime.value,
        new Cesium.JulianDate()
      )
      const position = positionProperty.getValue(customTime)

      if (position) {
        mbTarget.position = position // 更新实体的位置
      }

      // const nextPosition = points
      //   ? points.find(item => item.time >= customElapsedTime.value).position
      //   : null
      const nextPosition = points
        ? positionProperty.getValue(
            Cesium.JulianDate.addSeconds(
              startTime,
              customElapsedTime.value + 1,
              new Cesium.JulianDate()
            )
          )
        : null

      const orientation = getOrientation(position, nextPosition)
      mbTarget.orientation = orientation
      if (isFollow.value) {
        trackTarget(position, getOrientation(position, nextPosition, 75))
      }
    })
  }

  function getOrientation(
    curPos: Cesium.Cartesian3,
    nextPos: Cesium.Cartesian3,
    p: number = 0
  ) {
    // console.log(curPos, nextPos, 'curPos, nextPos')
    if (!curPos || !nextPos || Cesium.Cartesian3.equals(curPos, nextPos)) {
      return Cesium.Quaternion.IDENTITY // 默认方向
    }

    const curPoint = cartesian32LonLat(curPos)
    const nextPoint = cartesian32LonLat(nextPos)
    const angle = getAngle(curPoint, nextPoint)
    const heading = Cesium.Math.toRadians(angle + 90)

    const pitch = Cesium.Math.toRadians(p)
    const roll = 0

    // 生成 HeadingPitchRoll 对象
    const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll)
    // console.log(hpr, '====')
    // 转换为四元数
    const orientation = Cesium.Transforms.headingPitchRollQuaternion(
      curPos,
      hpr
    )
    return orientation
  }

  function getAngle(p1: number[], p2: number[]) {
    const point1 = point(p1)
    const point2 = point(p2)

    const angle = bearing(point2, point1)
    return angle
  }

  function createPoint(position: Cesium.Cartesian3) {
    return viewer.entities.add({
      position: position,
      point: {
        color: Cesium.Color.TRANSPARENT,
        pixelSize: 6,
        outlineColor: Cesium.Color.ORANGE,
        outlineWidth: 2,
      },
    })
  }

  function play() {
    // console.log('play')
    if (!isAnimationRunning.value) {
      isAnimationRunning.value = true
      isPaused.value = false
      lastFrameTime.value = performance.now()
    } else if (isPaused.value) {
      isPaused.value = false
      lastFrameTime.value = performance.now()
    }

    // viewer.trackedEntity = mbTarget // 设置追踪的实体
  }

  function trackTarget(center, orientation) {
    if (mbTarget) {
      // 监听场景渲染

      // 第三人称视角跟随
      let transform = Cesium.Transforms.eastNorthUpToFixedFrame(center)
      transform = Cesium.Matrix4.fromRotationTranslation(
        Cesium.Matrix3.fromQuaternion(orientation),
        center
      )
      viewer.camera.lookAtTransform(
        transform,
        new Cesium.Cartesian3(-100, 0, 150000)
      )
    }
  }

  function setDefaultView() {
    viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
  }

  function pause() {
    console.log('pause')

    if (isAnimationRunning.value) {
      isPaused.value = !isPaused.value
      if (!isPaused.value) {
        lastFrameTime.value = performance.now()
      }
    }
  }

  function setSpeed(speed: number) {
    animationSpeed.value = speed
  }

  function reset() {
    customElapsedTime.value = 0
    isAnimationRunning.value = false
    isPaused.value = false
    animationSpeed.value = 1
  }

  function changeTime(time: number) {
    customElapsedTime.value = time
    // timeLabel.textContent = `时间: ${customElapsedTime.toFixed(1)}s`;
    // isPaused.value = true
  }

  function removeEntities() {
    entities.forEach(element => {
      viewer.entities.remove(element)
    })
    entities = []
    mbTarget && viewer.entities.remove(mbTarget), (mbTarget = null)
  }
  return {
    mbData,
    customElapsedTime,
    showHisTrajCom,
    showOrHideHisTraj,
    times,
    loadHisTraj,
    isAnimationRunning,
    isPaused,
    play,
    pause,
    reset,
    animationSpeed,
    setSpeed,
    changeTime,
    isFollow,
  }
}

async function getHisTraj({
  id,
  timeRange,
}: {
  id: string
  timeRange: string[]
}) {
  const [timeBegin, timeEnd] = timeRange
  const { code, data: result } = await getMubiaoHisTraj({
    target_id: id,
    timeBegin,
    timeEnd,
  })
  if (code !== '200') {
    return
  }

  const timeArray = result.map(item => {
    return new Date(item.time).getTime()
  })
  const posArray = result.map(item => item.position).flat(Infinity)
  const points = result.reduce<TPoints>((acc, point, index, array) => {
    const { time, position } = point
    const cartesian3 = Cesium.Cartesian3.fromDegrees(...position)
    if (index === 0) {
      acc.push({ time: 0, position: cartesian3 })
    } else {
      acc.push({
        time:
          (new Date(time).getTime() - new Date(array[0].time).getTime()) / 1000,
        position: cartesian3,
      })
    }
    return acc
  }, [])

  return { points, posArray, timeArray }
}
