import * as Cesium from "cesium";
import { getCenterPosition } from "./calcFn";

const createFeature = (style, position, text, layer) => {
  if (!style) {
    return null;
  }

  switch (style.properties?.type) {
    case "point":
    case "billboard":
    case "label":
      return createPointFeature(style, position, text, layer);
    case "polyline":
      return createPolylineFeature(style, position, text, layer);
    case "polygon":
      return createPolygonFeature(style, position, text, layer);
    default:
      return null;
  }
};

/**
 * 生成点要素
 * 目前图标、标签没有额外操作，故共享该方法
 * @param {Object} style 处理后的样式对象
 * @param {Cesium.Cartesian3} position 点位置
 * @param {String} text 标签文本，可选
 * @param {Cesium.DataSource} layer 图层
 * @returns {Cesium.Entity} 点对象
 */
const createPointFeature = (style, position, text, layer) => {
  if (!position) {
    return null;
  }

  const entity = new Cesium.Entity({
    position: position,
    ...cloneStyle(style),
  });
  // 添加标签文本
  // if(text !== null && text !== undefined) {
  //   if(Cesium.defined(entity.label)) {
  //     entity.label.text = new Cesium.ConstantProperty(text)
  //   } else {
  //     entity.label = new Cesium.LabelGraphics({
  //       text,
  //       font: '16px sans-serif',
  //     })
  //   }
  // }
  if (Cesium.defined(entity.label) && text !== null && text !== undefined) {
    entity.label.text = new Cesium.ConstantProperty(text);
  }
  // 加入图层
  if (layer) {
    layer.entities.add(entity);
  }
  return entity;
};

/**
 * 生成线要素
 * @param {Object} style 处理后的样式对象
 * @param {Array<Cesium.Cartesian3>} position 位置数组
 * @param {String} text 标签文本，可选
 * @param {Cesium.DataSource} layer 图层
 * @returns {Cesium.Entity} 线对象
 */
const createPolylineFeature = (style, position, text, layer) => {
  if (!position || position.length < 2) {
    return null;
  }

  const entity = new Cesium.Entity(cloneStyle(style));
  // 添加线坐标
  if (Cesium.defined(style.polyline)) {
    entity.polyline.positions = new Cesium.ConstantProperty(
      style.properties.closed ? [...position, position[0]] : position
    );
  } else {
    entity.polyline = new Cesium.PolylineGraphics({
      positions: position,
    });
  }
  // 添加标签文本
  if (Cesium.defined(entity.label) && text !== null && text !== undefined) {
    entity.label.text = new Cesium.ConstantProperty(text)
    // 添加label坐标
    entity.position = getCenterPosition(position)
  }
  // 加入图层
  if (layer) {
    layer.entities.add(entity);
  }
  return entity;
};

/**
 * 生成面要素
 * @param {Object} style 处理后的样式对象
 * @param {Array<Cesium.Cartesian3>} position 位置数组
 * @param {String} text 标签文本，可选
 * @param {Cesium.DataSource} layer 图层
 * @returns {Cesium.Entity} 面对象
 */
const createPolygonFeature = (style, position, text, layer) => {
  if (!position || position.length < 3) {
    return null;
  }

  const entity = new Cesium.Entity(cloneStyle(style));
  // 添加面坐标
  if (Cesium.defined(style.polygon)) {
    entity.polygon.hierarchy = new Cesium.PolygonHierarchy(position);
  } else {
    entity.polyline = new Cesium.PolygonGraphics({
      hierarchy: new Cesium.PolygonHierarchy(position),
    });
  }
  // 添加轮廓线坐标
  // 这里消极的判断，仅当存在polyline时才添加，且必定是闭合线
  if (Cesium.defined(style.polyline)) {
    entity.polyline.positions = new Cesium.ConstantProperty([
      ...position,
      position[0],
    ]);
  }
  // 添加标签文本
  if (Cesium.defined(entity.label) && text !== null && text !== undefined) {
    entity.label.text = new Cesium.ConstantProperty(text)
    // 添加label坐标
    entity.position = getCenterPosition(position)
  }
  // 加入图层
  if (layer) {
    layer.entities.add(entity)
  }
  return entity;
};

const cloneStyle = (style) => {
  const clone = {};
  for (let key in style) {
    // console.log(key);
    if (key === "id") {
      clone[key] = style[key];
    } else if (key === "properties") {
      // 浅拷贝属性
      clone[key] = {};
      for (let prop in style[key]) {
        clone[key][prop] = style[key][prop];
      }
    } else {
      // 用cesium提供方法拷贝
      clone[key] = style[key].clone();
    }
  }
  return clone;
};

export {
  createFeature,
  createPointFeature,
  createPolylineFeature,
  createPolygonFeature,
};
