import {
  GeometryType,
  Projection,
  Geometry,
  SpatialReference,
  defaultValue
} from '@mapgis/webclient-common'

function transformToWGS84(spatialReference, geo) {
  if (spatialReference.wkid !== '4326') {
    geo.spatialReference = spatialReference
    return Projection.project(geo, new SpatialReference('EPSG:4326'))
  }
  return geo
}

class ConvertGeometryUtil {
  /**
   * @description 转换为cesium C3 数组
   * @param {*} geometry
   * @param {*} options
   * @return {*}
   */
  static toCartesian3Array(geometry, options) {
    const c3Arr = []
    const opt = defaultValue(options, {})
    const offsetHeight = defaultValue(opt.offsetHeight, 0)
    if (!(geometry instanceof Geometry)) return c3Arr
    let spatialReference = defaultValue(
      opt.spatialReference,
      new SpatialReference('EPSG:4326')
    )
    if (geometry.spatialReference) {
      spatialReference = geometry.spatialReference
    }

    switch (geometry.type) {
      case GeometryType.point: {
        let geo = geometry.clone()
        geo = transformToWGS84(spatialReference, geo)
        let c3
        if (geo.hasZ) {
          c3 = Cesium.Cartesian3.fromDegrees(
            geo.coordinates[0],
            geo.coordinates[1],
            geo.coordinates[2] + offsetHeight
          )
        } else {
          c3 = Cesium.Cartesian3.fromDegrees(
            geo.coordinates[0],
            geo.coordinates[1],
            0 + offsetHeight
          )
        }
        c3Arr.push(c3)
        break
      }
      case GeometryType.lineString: {
        let geo = geometry.clone()
        geo = transformToWGS84(spatialReference, geo)
        const coordinates = geo.coordinates
        coordinates.forEach((coords) => {
          let c3
          if (geo.hasZ) {
            c3 = Cesium.Cartesian3.fromDegrees(
              coords[0],
              coords[1],
              coords[2] + offsetHeight
            )
          } else {
            c3 = Cesium.Cartesian3.fromDegrees(
              coords[0],
              coords[1],
              0 + offsetHeight
            )
          }
          c3Arr.push(c3)
        })
        break
      }
      case GeometryType.polygon: {
        let geo = geometry.clone()
        geo = transformToWGS84(spatialReference, geo)
        const coordinates = geo.coordinates
        // 只取第一个区
        coordinates[0].forEach((coords) => {
          let c3
          if (geo.hasZ) {
            c3 = Cesium.Cartesian3.fromDegrees(
              coords[0],
              coords[1],
              coords[2] + offsetHeight
            )
          } else {
            c3 = Cesium.Cartesian3.fromDegrees(
              coords[0],
              coords[1],
              offsetHeight
            )
          }
          c3Arr.push(c3)
        })
        break
      }
      case GeometryType.extent: {
        let geo = geometry.clone()
        geo = transformToWGS84(spatialReference, geo)
        const minX = geo.xmin
        const maxX = geo.xmax
        const minY = geo.ymin
        const maxY = geo.ymax
        const minZ = geo.zmin
        const maxZ = geo.zmax
        let c31
        let c32
        if (geo.hasZ) {
          c31 = Cesium.Cartesian3.fromDegrees(minX, minY, minZ + offsetHeight)
          c32 = Cesium.Cartesian3.fromDegrees(maxX, maxY, maxZ + offsetHeight)
        } else {
          c31 = Cesium.Cartesian3.fromDegrees(minX, minY, offsetHeight)
          c32 = Cesium.Cartesian3.fromDegrees(maxX, maxY, offsetHeight)
        }
        c3Arr.push(c31)
        c3Arr.push(c32)
        break
      }
      case GeometryType.circle: {
        let geo = geometry.clone()
        geo = transformToWGS84(spatialReference, geo)
        let c3
        const center = geo.center
        if (geo.hasZ) {
          c3 = Cesium.Cartesian3.fromDegrees(
            center[0],
            center[1],
            center[2] + offsetHeight
          )
        } else {
          c3 = Cesium.Cartesian3.fromDegrees(center[0], center[1], offsetHeight)
        }
        c3Arr.push(c3)
        break
      }
      default: {
        break
      }
    }
    return c3Arr
  }
}

export default ConvertGeometryUtil
