// 单次点击 - 返回的经纬度
let _position = "";

// 经度
let _longitude = "";

// 维度
let _latitude = "";

// 高程
let _height = "";

// ========================================== 临时定位坐标点的变量 | S
// 121.70825443975761 Latitude: 36.86250187104627 Height: 66.3921270241871

//  121.70570667390288 Latitude: 36.86383149414161

// Longitude: 121.70824700245234 Latitude: 36.862220128264575

// \Longitude: 121.70785014768873 Latitude: 36.86265554205143 Height: 67.08689583983765
let _iptX = "121.70785014768873";
let _iptY = "36.86265554205143";

let __iptX = "121.70785014768873";
let __iptY = "36.86265554205143";

// =================================================================

//  [x y z]
let _positionArr = [];

// [{ zx, yz }]
let pList = [];

const isViewer = (height) => {
  return height > 15;
};

let _type = "";

// 格式化 [1 1 1 2 2 2 3 3 3 ] => [{ x y z }]
const formatPos = (arr) => {
  /**
   *
   *  [1 1 1 2 2 2 3 3 3 4 4 4]
   */
  if (!Array.isArray(arr)) return;

  let _arr = [],
    x = 0,
    y = 0,
    z = 0;

  for (let i = 0; i < arr.length; i++) {
    /**(
     *  
     * 
     * 界
     *  - 清
     *  - 存
     * 
    ) */

    if (!x) x = arr[i];
    if (x && !y) y = arr[i];
    if (y && !z) z = arr[i];

    if (!(i % 3)) {
      _arr.push({
        x,
        y,
        z,
      });

      x = 0;
      y = 0;
      z = 0;
    }
  }

  return _arr;
};

// ================================================================== [源文件粘贴过来] 返回 - 计算高差、平面、角 | S
function calcelatepoduCopy(podupoints) {
  console.log(
    "elevationDifference ===============================================:",
    podupoints
  );

  // ============================================== 粘过来 校验 turf | S

  if (!turf) {
    turf = window.turf || self.turf || globalThis.turf;
  }

  if (!turf) {
    return new ReferenceError(
      "///init.js ||||||||||||| ____________turf is undefined"
    );
  }
  // ============================================== 粘过来 校验 turf | E

  // 循环遍历 podupoints 数组中的每对相邻点
  for (let i = 0; i < podupoints.length - 1; i++) {
    // ========================= 临时处理 |　S

    // 获取两个相邻的点
    let point1 = podupoints[i];
    let point2 = podupoints[i + 1];

    /**
     *              let point1 = podupoints[i];
                    let point2 = podupoints[i + 1];
     * 
     * 
     *              
     *              var point1 = turf.point([109.104262, 37.831315]);
                    var point2 = turf.point([109.104261, 37.831315]);
                    var bearing = turf.bearing(point1, point2);
                    if(bearing<0){
                        bearing=bearing+360
                    }
                    console.log("bearing",bearing);
     */

    /**
     *
     *  podupoints = [ {x: 0, y: 0}, {x: 1, y: 1},{x: 2, y: 2, z: 2} ]
     *
     *
     * */

    // 获取经纬度和高程
    let longitude1 = point1.x;
    let latitude1 = point1.y;
    let elevation1 = point1.z;

    let longitude2 = point2.x;
    let latitude2 = point2.y;
    let elevation2 = point2.z;

    // 使用 Turf.js 计算两个点之间的水平距离
    const point1Turf = turf.point([longitude1, latitude1]);
    const point2Turf = turf.point([longitude2, latitude2]);

    // 计算两个点之间的水平距离
    const options = { units: "meters" }; // 单位可以根据需求选择 'meters', 'kilometers', 'miles', etc.
    const distance = turf.distance(point1Turf, point2Turf, options); // 距离单位为公里，若需要单位为米则改为 'meters'

    // 计算高程差
    const elevationDifference = Math.abs(elevation2 - elevation1); // 高程差（单位：米）
    console.log(
      "elevationDifference ===============================================:",
      elevationDifference
    );
    debugger;

    // 计算坡度（单位：弧度）
    const slopeRadians = Math.atan(elevationDifference / distance); // distance 转为米

    // 将坡度转换为度（可选）
    const slopeDegrees = slopeRadians * (180 / Math.PI); // 转为度

    // =========================================================

    var point11 = turf.point([point1.x, point1.y]);
    var point22 = turf.point([point2.x, point2.y]);
    var bearing = turf.bearing(point11, point22);
    if (bearing < 0) {
      bearing = bearing + 360;
    }
    console.log("bearing", bearing);

    // =========================================================

    // 输出坡度
    console.log(`Slope between point ${i + 1} and point ${i + 2}:`);
    console.log("Slope in radians:", slopeRadians);
    console.log("Slope in degrees:", slopeDegrees);

    return {
      distance: {
        name: "距离",
        value: distance,
      },
      elevationDifference: {
        name: "高差",
        value: elevationDifference,
      },
      slopeDegrees: {
        name: "坡度角",
        value: slopeDegrees,
      },
      opts: {
        name: "当前轮 - 参数",
        value: podupoints,
      },
      bearing: {
        name: "方位角",
        value: bearing,
      },
    };
  }

}
// ================================================================== [源文件粘贴过来] 返回 - 计算高差、平面、角 | E

const initCesiumPoint = (
  viewer,
  Cesium,
  { _longitude, _latitude, _height },
  { text, fillColor } = { text: "", fillColor: "" }
) => {
  
  debugger;

  if (_height < 15) return;
  const pointConf = {
    text: ` 经度 : ${String(_longitude).slice(0, 10)}\n 纬度 : ${String(
      _latitude
    ).slice(0, 10)}\n 高程 : ${String(_height).slice(0, 10)}(米)`,
  };

  const _id = viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
      _longitude,
      _latitude,
      _height + 0.02
    ),
    point: {
      pixelSize: 10,
      color: fillColor || Cesium.Color.RED,
      heightReference: Cesium.HeightReference.NONE,
    },
    label: {
      disableDepthTestDistance: Number.POSITIVE_INFINITY, // 去掉地形遮挡
      fillColor: Cesium.Color.WHITE,
      outlineColor: Cesium.Color.WHITE,
      text: text || pointConf.text,
      backgroundColor: Cesium.Color.BLACK, // 背景颜色
      font: "10pt monospace",
      showBackground: true, // 是否显示背景颜色
      horizontalOrigin: Cesium.HorizontalOrigin.LEFT, // 水平位置，左对齐
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      outlineWidth: 0.3,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      pixelOffset: new Cesium.Cartesian2(0, -30),
    },
  });

  initCesiumPoint.__ids = initCesiumPoint.__ids
    ? [...initCesiumPoint.__ids, _id]
    : [_id];

  initCesiumPoint._remove = () => {
    if (!Array.isArray(initCesiumPoint.__ids)) return;
    for (let _vId of initCesiumPoint.__ids) {
      viewer.entities.remove(_vId);
    }
  };
};

// 上一次的坐标点 | 临时
let oldP = {
  x: 0,
  y: 0,
  z: 0,
};

const calcD = (height, distance) => {
  /**
   *
   *  1. 坡度角
   *  2. 方位角
   *
   *  -  height
   *
   */
};

const initCesiumpolyline = (
  viewer,
  Cesium,
  { _longitude, _latitude, _height, beforeCallback, afterCallback }
) => {
  if (!Cesium) {
    Cesium = window.Cesium;
  }

  if (_height < 15) return;
  // viewer.entities.removeAll();
  // if(switchModule.)

  const pointConf = {
    text: `  
                经度 : ${String(_longitude).slice(0, 8)}
                纬度 : ${String(_latitude).slice(0, 8)}
                高程 : ${String(_height).slice(0, 6)}(米)`,
    // ...
  };

  let _curPosition = [_longitude, _latitude, _height];
  _positionArr = [..._positionArr, ..._curPosition];

  pList = [...pList, { x: _longitude, y: _latitude, z: _height }];
  //   - _height + 5 解决图层重叠问题。
  //   -  label - font 字体大小 9t。

  const _isDeg = initCesiumpolyline.___d;

  const _isLine = !initCesiumpolyline.___d;
  debugger;
  let _id;
  const CesiumLine = () => {
    _id = viewer.entities.add({
      name: "polyline",
      polyline: {
        show: true, // 显示折线
        positions: Cesium.Cartesian3.fromDegreesArrayHeights(_positionArr), // 折线顶点的位置数组
        material: Cesium.Color.RED, // 折线颜色
        width: 5, // 折线宽度
        clampToGround: true, // 将折线贴地
        zIndex: 92, // 折线层级索引
        classificationType: Cesium.ClassificationType.BOTH, // 折线分类类型
        heightReference: Cesium.HeightReference.NONE,
      },
    });
  };

  const CesiumLabel = (opt) => {
    if (!opt) return;

    let { distance, elevationDifference, slopeDegrees, bearing } = opt;
    /**
     * 
     *  
     *  distance: {
        name: "距离",
        value: distance,
      },
      elevationDifference: {
        name: "高差",
        value: elevationDifference,
      },
      slopeDegrees: {
        name: "坡度",
        value: slopeDegrees,
      },
      opts: {
        name: "当前轮 - 参数",
        value: podupoints,
      },
     * 
     * 
     */

    /**
       * 
       *  text: `  
                经度 : ${String(_longitude).slice(0, 8)}
                纬度 : ${String(_latitude).slice(0, 8)}
                高程 : ${String(_height).slice(0, 6)}(米)`,
       */

    const styleOpt = {
      text: ` 平距 : ${distance.value}\n 空间距离 : ${Math.sqrt(
        distance.value * distance.value +
          elevationDifference.value * elevationDifference.value
      )}\n 高差 : ${elevationDifference.value}(米)\n 坡度 : ${
        slopeDegrees.value
      }`,
      fillColor: Cesium.Color.GREEN,
    };

    if (_isDeg) {
      styleOpt.text = `  方位角 : ${bearing.value}\n  坡度角 : ${slopeDegrees.value}`;
    }

    debugger;
    // initCesiumPoint.__setLabel(styleOpt);
    initCesiumPoint(
      viewer,
      Cesium,
      {
        _longitude,
        _latitude,
        _height,
      },
      styleOpt
    );
  };

  let _labelOpt;

  if (pList.length > 1) {
    const start = pList[pList.length - 2];
    const end = pList[pList.length - 1];
    _labelOpt = calcelatepoduCopy([start, end]);
  }
  debugger;
  CesiumLine();
  CesiumLabel(_labelOpt);
  initCesiumpolyline.___d = false;

  initCesiumpolyline.__ids = initCesiumpolyline.__ids
    ? [...initCesiumpolyline.__ids, _id]
    : [_id];

  initCesiumpolyline.__remove = () => {
    if (!Array.isArray(initCesiumpolyline.__ids)) return;
    for (let _vId of initCesiumpolyline.__ids) {
      viewer.entities.remove(_vId);
    }
  };
};

const xD = (old, cur) => {
  /**
   *  [ x, y]
   *
   */
  if (!Array.isArray(old)) return;
  let point1 = turf.point(old);
  let point2 = turf.point(cur);
  let bearing = turf.bearing(point1, point2);
  if (bearing < 0) {
    bearing = bearing + 360;
  }
  console.log("bearing", bearing);
};

// ================================================================ 模板函数 | S
/**
 * 
            // 面
            var polyEntity = viewer.entities.add({
                name: 'Area Measurement',
                polygon: {
                    hierarchy: new Cesium.PolygonHierarchy(positions),
                    material: Cesium.Color.YELLOW.withAlpha(0.5),
                    outline: true,
                    outlineColor: Cesium.Color.BLACK
                }
            });

            // 线
            var polyEntity2 = viewer.entities.add({
                name: 'Area Measurement2',
                polyline: {
                    positions: positions, // 使用 positions 而非 hierarchy
                    width: 5,             // 设置线宽
                    material: Cesium.Color.RED, // 设置线的材质
                }
            });

            // 点
            viewer.entities.add({
                position: Cesium.Cartesian3.fromDegrees(-75.617, 40.038),
                point: {
                    pixelSize: 10,
                    color: Cesium.Color.RED
                }
            });

 * 
 */
// ================================================================ 模板函数 | E

// ================================= 点击切换

// 全部状态

// const switchModule = (type) => {
//   switchModule.allType = {
//     point: false,
//     line: false,
//   };
//   // 当前是什么标识 约束只能是那些
//   // 没有全关
//   if (!Reflect.ownKeys(switchModule.allType).includes(type)) {
//     return new Error("切换模块的唯一标识传递错误！ 例： 绘点[pointType] ");
//   }

//   _conf[type] = true;

//   for (let _t in _conf) {
//     if (type !== _t) _conf[_t] = false;
//   }
//   switchModule._curType = type;
//   return {
//     ...switchModule.allType,
//     _curType: type,
//   }
// };

// ==================================================== 粘贴过来 (体积) | S

async function calculateTotalVolume(polygon) {
  debugger;

  const gridStep = 0.000001; // 网格的步长
  let totalVolume = 0;
  const [minLon, minLat, maxLon, maxLat] = turf.bbox(polygon);
  for (let lat = minLat; lat < maxLat; lat += gridStep) {
    for (let lon = minLon; lon < maxLon; lon += gridStep) {
      const point = turf.point([lon, lat]);
      if (turf.booleanPointInPolygon(point, polygon)) {
        const cartographic = Cesium.Cartographic.fromDegrees(lon, lat);
        const elevation = await getElevationFromRay(cartographic);
        let volume = calculateVolume(elevation, gridStep, lat);
        totalVolume += volume;
      }
    }
  }
  console.log(
    `Total =============================== Volume: ${totalVolume} 立方米`
  );
}

/**
 * @param {*} cartographic
 * @returns
 * @name getElevationFromRay
 */

function getElevationFromRay(cartographic) {
  debugger;
  return new Promise((resolve, reject) => {
    const ellipsoid = viewer.scene.globe.ellipsoid;
    const startPoint = Cesium.Cartesian3.fromRadians(
      cartographic.longitude,
      cartographic.latitude,
      100
    );
    console.log("getElevationFromRay");
    const surfaceNormal =
      viewer.scene.globe.ellipsoid.geodeticSurfaceNormal(startPoint);
    const direction = Cesium.Cartesian3.negate(
      surfaceNormal,
      new Cesium.Cartesian3()
    );
    const ray = new Cesium.Ray(startPoint, direction);
    const intersection = viewer.scene.pickFromRay(ray);
    if (intersection) {
      const cartographicPosition = Cesium.Cartographic.fromCartesian(
        intersection.position
      );
      console.log(`高程: ${cartographicPosition.height} 米`);
      resolve(cartographicPosition.height); // 返回高程
    } else {
      reject("未检测到交点");
    }
  });
}

/**
 *
 * @param {*} height
 * @param {*} gridStep
 * @param {*} latitude
 * @returns
 *
 * @name calculateVolume
 */

function calculateVolume(height, gridStep, latitude) {
  // 1度纬度大约为111320米
  const latDistance = 111320 * gridStep;
  console.log("latDistance", latDistance);
  const lonDistance =
    111320 * Math.cos(Cesium.Math.toRadians(latitude)) * gridStep;
  const area = latDistance * lonDistance;
  return area * height;
}

// 调用方法
// const polygonCoordinates = [
//   [121.707742, 36.862901],
//   [121.7078519, 36.86264528],
//   [121.70805941, 36.86271579],
//   [121.7080125, 36.8629544],
//   [121.707742, 36.862901], // 闭合多边形
// ];
// const polygon = turf.polygon([[...polygonCoordinates]]);

// calculateTotalVolume(polygon);
// ==================================================== 粘贴过来 (体积) | E

const entry = () => {
  const polygonCoordinates = [
    [121.707742, 36.862901],
    [121.7078519, 36.86264528],
    [121.70805941, 36.86271579],
    [121.7080125, 36.8629544],
    [121.707742, 36.862901], // 闭合多边形
  ];
  const polygon = turf.polygon([[...polygonCoordinates]]);

  calculateTotalVolume(polygon);
};

const removeCreateViewer = (callback) => {
  if (typeof callback !== "function") return;
  console.dir(initCesiumpolyline, initCesiumPoint);
  initCesiumpolyline.__remove && initCesiumpolyline.__remove();
  initCesiumPoint._remove && initCesiumPoint._remove();
  callback && callback();
};

// ================================================== 体积计算 | S

/**
 *
 * @param {
 *
 * } polygon
 */

async function calculateTotalVolume(polygon) {
  /**
   *  1.
   *
   */
  const gridStep = 0.0001; // 网格的步长
  let totalVolume = 0;
  const [minLon, minLat, maxLon, maxLat] = turf.bbox(polygon);
  for (let lat = minLat; lat < maxLat; lat += gridStep) {
    for (let lon = minLon; lon < maxLon; lon += gridStep) {
      const point = turf.point([lon, lat]);
      if (turf.booleanPointInPolygon(point, polygon)) {
        const cartographic = Cesium.Cartographic.fromDegrees(lon, lat);
        const elevation = await getElevationFromRay(cartographic);
        let volume = calculateVolume(elevation, gridStep, lat);
        totalVolume += volume;
      }
    }
  }
  console.log(`======================= Total Volume: ${totalVolume} 立方米`);
}

function getElevationFromRay(cartographic) {
  return new Promise((resolve, reject) => {
    const ellipsoid = viewer.scene.globe.ellipsoid;
    const startPoint = Cesium.Cartesian3.fromRadians(
      cartographic.longitude,
      cartographic.latitude,
      100
    );
    console.log("getElevationFromRay");
    const surfaceNormal =
      viewer.scene.globe.ellipsoid.geodeticSurfaceNormal(startPoint);
    const direction = Cesium.Cartesian3.negate(
      surfaceNormal,
      new Cesium.Cartesian3()
    );
    const ray = new Cesium.Ray(startPoint, direction);
    const intersection = viewer.scene.pickFromRay(ray);
    if (intersection) {
      const cartographicPosition = Cesium.Cartographic.fromCartesian(
        intersection.position
      );
      console.log(`高程: ${cartographicPosition.height} 米`);
      resolve(cartographicPosition.height); // 返回高程
    } else {
      reject("未检测到交点");
    }
  });
}

function calculateVolume(height, gridStep, latitude) {
  // 1度纬度大约为111320米
  const latDistance = 111320 * gridStep;
  console.log("latDistance", latDistance);
  const lonDistance =
    111320 * Math.cos(Cesium.Math.toRadians(latitude)) * gridStep;
  const area = latDistance * lonDistance;
  return area * height;
}
// ================================================== 体积计算 | E

// =================================================================================== SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
async function calculateTotalVolume(polygon) {
  const gridStep = 0.000001; // 网格的步长
  let totalVolume = 0;
  const [minLon, minLat, maxLon, maxLat] = turf.bbox(polygon);
  for (let lat = minLat; lat < maxLat; lat += gridStep) {
    for (let lon = minLon; lon < maxLon; lon += gridStep) {
      const point = turf.point([lon, lat]);
      if (turf.booleanPointInPolygon(point, polygon)) {
        const cartographic = Cesium.Cartographic.fromDegrees(lon, lat);
        const elevation = await getElevationFromRay(cartographic);
        let volume = calculateVolume(elevation, gridStep, lat);
        totalVolume += volume;
      }
    }
  }
  console.log(`Total Volume: ${totalVolume} 立方米`);
}


function getElevationFromRay(cartographic) {
  return new Promise((resolve, reject) => {
    const ellipsoid = viewer.scene.globe.ellipsoid;
    const startPoint = Cesium.Cartesian3.fromRadians(
      cartographic.longitude,
      cartographic.latitude,
      100
    );
    console.log("getElevationFromRay");
    const surfaceNormal =
      viewer.scene.globe.ellipsoid.geodeticSurfaceNormal(startPoint);
    const direction = Cesium.Cartesian3.negate(
      surfaceNormal,
      new Cesium.Cartesian3()
    );
    const ray = new Cesium.Ray(startPoint, direction);
    const intersection = viewer.scene.pickFromRay(ray);
    if (intersection) {
      const cartographicPosition = Cesium.Cartographic.fromCartesian(
        intersection.position
      );
      console.log(`高程: ${cartographicPosition.height} 米`);
      resolve(cartographicPosition.height); // 返回高程
    } else {
      reject("未检测到交点");
    }
  });
}


function calculateVolume(height, gridStep, latitude) {
  // 1度纬度大约为111320米
  const latDistance = 111320 * gridStep;
  console.log("latDistance", latDistance);
  const lonDistance =
    111320 * Math.cos(Cesium.Math.toRadians(latitude)) * gridStep;
  const area = latDistance * lonDistance;
  return area * height;
}
// =================================================================================== EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE

const initEchart = () => {
  console.log("initEchart", echarts);
  var chartDom = document.getElementById("main");
  var myChart = echarts.init(chartDom);
  var option;

  option = {
    // tooltip: {
    //   trigger: "axis",
    // },
    xAxis: {
      type: "category",
      axisLabel: {
        textStyle: {
          color: "#ffffff", // 设置 X 轴标签颜色为白色
        },
      },
      axisLine: {
        lineStyle: {
          color: "#ffffff", // 设置 X 轴轴线颜色为白色
        },
      },
      data: [],
    },
    yAxis: {
      type: "value",
      axisLabel: {
        textStyle: {
          color: "#ffffff", // 设置 Y 轴标签颜色为白色
        },
      },
      axisLine: {
        lineStyle: {
          color: "#ffffff", // 设置 Y 轴轴线颜色为白色
        },
      },
    },
    series: [
      {
        data: [120, 200, 150, 80, 70, 110, 130],
        type: "line",
        areaStyle: {
          opacity: 0.8,
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            {
              offset: 0,
              color: "rgb(128, 255, 165)",
            },
            {
              offset: 1,
              color: "rgb(1, 191, 236)",
            },
          ]),
        },
      },
    ],
  };

  option && myChart.setOption(option);

  initEchart.____option = option;
  initEchart.____myChart = myChart;
  initEchart.____el = chartDom;

  initEchart.____setOptions = (opt) => {
    return myChart.setOption({ ...option, series: opt });
  };

  return {
    //
  };
};

// ============================== 剖 面  | S

const aaa = () => {
  // 获取剖面高程函数
  function getpomianElevationFromRay(cartographic) {
    return new Promise((resolve, reject) => {
      const ellipsoid = viewer.scene.globe.ellipsoid;
      const startPoint = Cesium.Cartesian3.fromRadians(
        cartographic.longitude,
        cartographic.latitude,
        100
      ); // 高度初始为 100 米
      console.log("getElevationFromRay");
      const surfaceNormal =
        viewer.scene.globe.ellipsoid.geodeticSurfaceNormal(startPoint);
      const direction = Cesium.Cartesian3.negate(
        surfaceNormal,
        new Cesium.Cartesian3()
      );
      const ray = new Cesium.Ray(startPoint, direction);

      // 使用 pickFromRay 获取地面交点
      const intersection = viewer.scene.pickFromRay(ray);

      if (intersection) {
        const cartographicPosition = Cesium.Cartographic.fromCartesian(
          intersection.position
        );
        console.log(`高程: ${cartographicPosition.height} 米`);
        resolve(cartographicPosition.height); // 返回高程
      } else {
        reject("未检测到交点");
      }
    });
  }

  const poumianCoordinates = [
    [121.707742, 36.862901], // 第一个点
    [121.7078519, 36.86264528], // 第二个点
  ];

  // 将经纬度转为笛卡尔坐标
  var start = Cesium.Cartesian3.fromDegrees(
    poumianCoordinates[0][0],
    poumianCoordinates[0][1]
  );

  var end = Cesium.Cartesian3.fromDegrees(
    poumianCoordinates[1][0],
    poumianCoordinates[1][1]
  );

  const numSteps = 100;
  var linePoints = [];

  for (var i = 0; i <= numSteps; i++) {
    var t = i / numSteps;
    var interpolatedPosition = Cesium.Cartesian3.lerp(
      start,
      end,
      t,
      new Cesium.Cartesian3()
    );
    linePoints.push(interpolatedPosition);
  }

  const elevationPromises = linePoints.map(async (point) => {
    var cartographic = Cesium.Cartographic.fromCartesian(point);
    const elevation = await getpomianElevationFromRay(cartographic);
    return {
      longitude: cartographic.longitude,
      latitude: cartographic.latitude,
      elevation: elevation,
    };
  });

  return elevationPromises;
};

// ============================== 解剖 面  | S
