import * as Cesium from 'cesium'
import * as turf from '@turf/turf'
import { useDrawTool } from './useDrawTool'

// 存储测量内容的辅助图层
let measureLayer = null

/**
 * 计算折线长度
 * @param {Cesium.Cartesian3[]} positions 位置列表
 * @returns 折线长度，单位米
 */
const getDistance = (positions) => { 
  const line = turf.lineString(positions.map((pos) => {
    const cartographic = Cesium.Cartographic.fromCartesian(pos)
    return [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]
  }))
  return turf.length(line, { units: 'kilometers' }) * 1000 // 返回米
}

/**
 * 计算多边形面积
 * @param {Cesium.Cartesian3[]} positions 位置列表
 * @returns 多边形面积，单位平方米
 */
const getArea = (positions) => {
  const pts = [...positions, positions[0]] // 闭合多边形
  const polygon = turf.polygon([pts.map((pos) => {
    const cartographic = Cesium.Cartographic.fromCartesian(pos)
    return [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]
  })])
  return turf.area(polygon) // 返回平方米
}

/**
 * 获取多个点的中心位置，根据边界范围确定
 * @param {Cesium.Cartesian3[]} positions 位置列表
 * @param {number} height 返回位置的高度，默认为0
 * @returns 根据边界范围确定的中心点位置
 */
const getBoundingCenter = (positions, height = 0) => {
  const coord = getBoundingCenterCoordinate(positions)
  return Cesium.Cartesian3.fromDegrees(coord[0], coord[1], height)
}

/**
 * 获取多个点的中心位置坐标，根据边界范围确定
 * @param {Cesium.Cartesian3[]} positions 位置列表
 * @returns 根据边界范围确定的中心点位置坐标，格式为 [经度, 纬度]
 */
const getBoundingCenterCoordinate = (positions) => {
  const polygon = turf.lineString(positions.map((pos) => {
    const cartographic = Cesium.Cartographic.fromCartesian(pos)
    return [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]
  }))
  const centerFeature = turf.center(polygon)
  return centerFeature.geometry.coordinates
}

export const useMeasureTool = (viewer) => {
  if (!viewer) {
    throw new Error('获取 Viewer 实例失败，请确保在 Viewer 初始化后调用 useMeasureTool 方法！')
  }

  const editTool = useDrawTool(viewer)
  if (!measureLayer) {
    measureLayer = new Cesium.CustomDataSource('__assist_measure')
    viewer.dataSources.add(measureLayer)
  }

  // 距离测量
  const measureDistance = () => {
    return editTool.drawPolyline().then((positions) => {
      const style = {
        width: 5,
        material: Cesium.Color.fromCssColorString('#57e0e0'),
      }
      let arr = []
      for (let i = 0; i < positions.length; i++) {
        if (i + 1 < positions.length) {
          if (!positions[i] || !positions[i + 1]) continue
          arr.push([positions[i], positions[i + 1]])
        }
      }
      console.log(arr)
      let result = 0
      arr.forEach((item) => {
        let start = Cesium.Cartographic.fromCartesian(item[0])
        let end = Cesium.Cartographic.fromCartesian(item[1])
        let startObj = { longitude: '', latitude: '' }
        let endObj = { longitude: '', latitude: '' }
        startObj.longitude = Cesium.Math.toDegrees(start.longitude)
        startObj.latitude = Cesium.Math.toDegrees(start.latitude)
        endObj.longitude = Cesium.Math.toDegrees(end.longitude)
        endObj.latitude = Cesium.Math.toDegrees(end.latitude)

        console.log(startObj)
        console.log(endObj)

        let from = turf.point([startObj.longitude, startObj.latitude])
        let to = turf.point([endObj.longitude, endObj.latitude])

        let distance = turf.distance(from, to, { units: 'kilometers' }) * 1000

        result += distance

        const tempPolyline = new Cesium.Entity({
          name: '__measure_distance',
          // position: [ {x: (item[0].x + item[1].x) / 2,  y: (item[0].y + item[1].y) / 2, z: (item[0].z + item[1].z) / 2} ],
          position: new Cesium.Cartesian3(
            (item[0].x + item[1].x) / 2,
            (item[0].y + item[1].y) / 2,
            (item[0].z + item[1].z) / 2,
          ),
          polyline: {
            positions: [...item],
            width: style.width,
            material: style.material,
            clampToGround: true,
          },
          label: new Cesium.LabelGraphics({
            text: distance.toFixed(2) + '米',
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
            pixelOffset: new Cesium.Cartesian2(10, 10),
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
          }),
        })

        measureLayer.entities.add(tempPolyline)
        return positions
      })

      let len = positions.length - 1
      if (len > 1) {
        let resultLabel = new Cesium.Entity({
          name: 'measure_distance_length',
          position: new Cesium.Cartesian3(
            (positions[0].x + positions[len].x) / 2,
            (positions[0].y + positions[len].y) / 2,
            (positions[0].z + positions[len].z) / 2,
          ),
          label: new Cesium.LabelGraphics({
            text: '总距离：' + result.toFixed(2) + '米',
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
            fillColor: Cesium.Color.AQUAMARINE,
          }),
        })
        measureLayer.entities.add(resultLabel)
      }
      return positions
    })
  }

  // 面积测量
  const measureArea = () => {
    return editTool.drawPolygon().then((positions) => {
      let polygon = []
      positions.forEach((item) => {
        let obj = Cesium.Cartographic.fromCartesian(item)
        polygon.push([Cesium.Math.toDegrees(obj.longitude), Cesium.Math.toDegrees(obj.latitude)])
      })

      let features = turf.points(polygon)
      let center = turf.center(features)

      console.log(center)

      let points0 = Cesium.Cartographic.fromCartesian(positions[0])
      polygon.push([
        Cesium.Math.toDegrees(points0.longitude),
        Cesium.Math.toDegrees(points0.latitude),
      ])
      let areaPolygon = turf.polygon([polygon])
      let area = turf.area(areaPolygon)

      const tempPolygon = new Cesium.Entity({
        name: '__measure_area',
        position: Cesium.Cartesian3.fromDegrees(
          center.geometry.coordinates[0],
          center.geometry.coordinates[1],
        ),
        polygon: {
          hierarchy: new Cesium.PolygonHierarchy(positions),
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          material: Cesium.Color.fromCssColorString('#ffff00').withAlpha(0.3),
        },
        polyline: {
          positions: [...positions, positions[0]],
          clampToGround: true,
          width: 2,
          material: Cesium.Color.fromCssColorString('#ffff00'),
        },
        label: new Cesium.LabelGraphics({
          text: area.toFixed(2) + '平方米',
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
        }),
      })
      measureLayer.entities.add(tempPolygon)
      return positions
    })
  }

  // 取消当前测量
  const abort = () => {
    editTool.abort() // 调用编辑工具的取消方法
  }

  // 清除所有测量结果
  const clear = () => {
    measureLayer.entities.removeAll()
  }

  return {
    distance: measureDistance,
    area: measureArea,
    abort,
    clear,
  }
}

export { getDistance, getArea, getBoundingCenter, getBoundingCenterCoordinate }
