// import Cesium from "./core"
import wkt from 'terraformer-wkt-parser'

export function transformWGS842Cartesian(position, alt) {
    return position
        ? Cesium.Cartesian3.fromDegrees(
            position.lng,
            position.lat,
            (position.alt = alt || position.alt),
            Cesium.Ellipsoid.WGS84
        )
        : Cesium.Cartesian3.ZERO;
}

export function transformCartesian2WGS84(cartesian) {
    let ellipsoid = Cesium.Ellipsoid.WGS84;
    let cartographic = ellipsoid.cartesianToCartographic(cartesian);
    return {
        lng: Cesium.Math.toDegrees(cartographic.longitude),
        lat: Cesium.Math.toDegrees(cartographic.latitude),
        alt: cartographic.height,
    };
}


export function getCartesian3FromPX(viewer, px) {

    let picks = viewer.scene.drillPick(px);
    let isOn3dtiles = false,
        isOnTerrain = false,
        cartesian = null;

    for (let i in picks) {
        let pick = picks[i];

        if (
            pick &&
            (pick.primitive instanceof Cesium.Cesium3DTileFeature ||
                pick.primitive instanceof Cesium.Cesium3DTileset ||
                pick.primitive instanceof Cesium.Model)
        ) {
            isOn3dtiles = true;
        }

        //is on 3dtiles
        if (isOn3dtiles) {
            viewer.scene.pick(px);
            cartesian = viewer.scene.pickPosition(px);
            if (cartesian) {
                let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
                if (cartographic.height < 0) cartographic.height = 0;
                let lng = Cesium.Math.toDegrees(cartographic.longitude);
                let lat = Cesium.Math.toDegrees(cartographic.latitude);
                let alt = cartographic.height;
                cartesian = transformWGS842Cartesian({ lng, lat, alt });
            }
        }
    }

    // is ellipsoid terrain
    let boolTerrain =
        viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider;

    // is other terrain
    if (!isOn3dtiles && !boolTerrain) {
        let ray = viewer.scene.camera.getPickRay(px);
        if (!ray) return null;
        cartesian = viewer.scene.globe.pick(ray, viewer.scene);
        isOnTerrain = true;
    }

    if (!isOn3dtiles && !isOnTerrain && boolTerrain) {
        cartesian = viewer.scene.camera.pickEllipsoid(
            px,
            viewer.scene.globe.ellipsoid
        );
    }

    // 避免位置陷入地下
    if (cartesian) {
        let position = transformCartesian2WGS84(cartesian);
        if (position.alt < 0) {
            cartesian = transformWGS842Cartesian(position, 0.1);
        }
    }

    return cartesian;
}

//geom转position
export function geomToCartesian3(geom) {
    let positions = []
    let geojson = wkt.parse(geom)
    let { type, coordinates } = geojson
    if (type === 'Point') {
      let [x, y, z] = coordinates
      positions.push(Cesium.Cartesian3.fromDegrees(x, y, z))
    } else if (type === 'LineString') {
      coordinates.forEach((element) => {
        let [x, y, z] = element
        positions.push(Cesium.Cartesian3.fromDegrees(x, y, z))
      })
    } else if (type === 'Polygon') {
      coordinates.forEach((element) => {
        element.forEach((item) => {
          let [x, y, z] = item
          positions.push(Cesium.Cartesian3.fromDegrees(x, y, z))
        })
      })
    }
    return {
      type,
      positions,
    }
}

/**
 * 将单个 Cartesian3 坐标转换为 WGS84 坐标
 *
 * @export
 * @param {*} position
 * @returns
 */
export function simpleCartesian3ToWGS84(position, viewer) {
    let ellipsoid = viewer.scene.globe.ellipsoid
    let cartographic = ellipsoid.cartesianToCartographic(position)
    //弧度转经度
    let wgs84 = {}
    wgs84.longitude = Cesium.Math.toDegrees(cartographic.longitude)
    wgs84.latitude = Cesium.Math.toDegrees(cartographic.latitude)
    wgs84.altitude = cartographic.height
    return wgs84
}

// 点位转WKTString
export function positionToGeom(wgs84Obj) {
    const { type, positions } = wgs84Obj
    let geom = ''
    if (type === 'Point') {
      geom = wkt.convert({
        type: 'Point',
        coordinates: positions[0],
      })
    } else if (type === 'LineString') {
      geom = wkt.convert({
        type: 'LineString',
        coordinates: positions,
      })
    } else if (type === 'Polygon') {
      geom = wkt.convert({
        type: 'Polygon',
        coordinates: [positions],
      })
    }
    return geom
}

// Cartesian3ToWGS84
export function cartesian3ToWGS84(viewer, cartesian3Obj) {
    const { type, positions } = cartesian3Obj
    let wgs84Positions
    if (type === 'Point') {
      wgs84Positions = Array.prototype.map.call(positions, (item) => {
        let wgs84 = simpleCartesian3ToWGS84(item, viewer)
        return [wgs84.longitude, wgs84.latitude, wgs84.altitude]
      })
    } else if (type === 'LineString') {
      wgs84Positions = Array.prototype.map.call(positions, (item) => {
        let wgs84 = simpleCartesian3ToWGS84(item, viewer)
        return [wgs84.longitude, wgs84.latitude, wgs84.altitude]
      })
    } else if (type === 'Polygon') {
      wgs84Positions = Array.prototype.map.call(positions, (item) => {
        let wgs84 = simpleCartesian3ToWGS84(item, viewer)
        return [wgs84.longitude, wgs84.latitude, wgs84.altitude]
      })
      wgs84Positions.push(wgs84Positions[0])
    }
    return {
      type,
      positions: wgs84Positions,
    }
}

export function addZero(num) {
    if (parseInt(num) < 10) {
      num = '0' + num
    }
    return num
}

export default {
    transformWGS842Cartesian,
    transformCartesian2WGS84,
    getCartesian3FromPX,
}