import { getIconName } from "../../public-function";
/**
 * @description 图例组件 相关 sdk
 * @author      朱琦
 * @date        2022/6/6
 */

/**
 * 图例组件 路况 sdk
 */
class LkSdk {
  constructor(config, sdk) {
    this.sdk = sdk;
    this.config = config;
  }
  /**
   * 设置数据
   * @param {Array} data 图例数据
   */
  setData(data) {
    this.data = data;
    return data;
  }
  /**
   * 加载图层
   * @returns 图层
   */
  async loadLayer() {
    this.layer = await this.sdk.createMvMapTrafficLayer(this.config);
    return this.layer;
  }

  /**
   * 隐藏图层
   */
  hideLayer() {
    this.layer && this.layer.hide();
  }

  /**
   * 显示图层
   */
  showLayer() {
    this.layer && this.layer.show();
  }
}

/**
 * 图例组件 海量点 sdk
 */
class PointSdk {
  constructor(config, sdk) {
    this.sdk = sdk;
    this.config = config;
  }
  /**
   * 设置数据
   * @param {Array} data 图例数据
   */
  setData(data) {
    // 海量点数据处理
    // let zoom = 8
    let list = [];
    data.forEach((item, index) => {
      // if ((/(^[1-9]\d*$)/.test((index / 100).toString()))) {
      //     zoom = zoom + 1
      // }
      const path = [parseFloat(item.path[0]), parseFloat(item.path[1])];
      // 过滤点位
      if (!path[0] || !path[1]) return;

      const itemData = {
        // zooms: [zoom, zoom + 2],
        zIndex: index,
        ...item,
        id: item.id,
        name: item.name,
        path,
        icon: getIconName(item, this.config.iconFilter),
        angle: item.angle || 0
      };
      list.push(itemData);
    });
    this.data = list;
    return list;
  }
  /**
   * 加载图层
   * @param {Function} callback 回调函数
   * @returns 图层
   */
  async loadLayer(callback) {
    this.layer = await this.sdk.createMvMapMassPoint(
      this.data,
      this.config,
      callback
    );
    return this.layer;
  }

  /**
   * 隐藏图层
   */
  hideLayer() {
    if (!this.layer) return;
    this.layer.setData(null);
    // this.layer.hide() 用hide2.0会有问题
  }

  /**
   * 显示图层
   */
  showLayer() {
    if (!this.layer) return;
    this.layer.setData(this.data);
    // this.layer.show()
  }
}

/**
 * 图例组件 海量线 sdk
 */
class LineSdk {
  constructor(config, sdk) {
    this.sdk = sdk;
    this.config = config;
  }
  /**
   * 设置数据
   * @param {Array} data 图例数据
   */
  setData(data) {
    this.data = data;
    return data;
  }
  /**
   * 加载图层
   * @param {Function} callback 回调函数
   * @returns 图层
   */
  async loadLayer(callback) {
    this.layer = await this.sdk.createMvMapMassLine(
      this.data,
      this.config,
      callback
    );
    return this.layer;
  }

  /**
   * 隐藏图层
   */
  hideLayer() {
    if (!this.layer) return;
    this.layer.setData(null);
    // this.layer.hide() 用hide2.0会有问题
  }

  /**
   * 显示图层
   */
  showLayer() {
    if (!this.layer) return;
    this.layer.setData(this.data);
    // this.layer.show()
  }
}
/**
 * 图例组件 图片 sdk
 */
class ImgSdk {
  constructor(config, sdk) {
    this.sdk = sdk;
    this.config = config;

    this.interval = Number(config.interval) || 0.5;
    this.data = null;
    this.layer = null;
    this.timer = null;
  }
  /**
   * 设置数据
   * @param {Array} data 图例数据
   */
  setData(data) {
    this.data = data;

    return data;
  }
  /**
   * 加载图层
   * @param {Function} callback 回调函数
   * @returns 图层
   */
  async loadLayer() {
    this.layer = await this.sdk.createMvMapImgLayer(this.data[0], this.config);

    if (this.data.length > 1 && this.config.loop) {
      // 多个图片 且开启循环时
      this.setImgTimer(true);
    }

    return this.layer;
  }
  /**
   * 清除图层
   */
  clearLayer() {
    this.setImgTimer(false);
    if (!this.layer) return;
    this.layer.setMap(null);
    this.layer = null;
  }

  /**
   * 隐藏图层
   */
  hideLayer() {
    this.setImgTimer(false);
    if (!this.layer) return;
    this.layer.hide();
  }

  /**
   * 显示图层
   */
  showLayer() {
    if (!this.layer) return;
    this.layer.show();
    this.config.loop && this.setImgTimer(true);
  }

  /**
   * 设置图片图层定时器
   * @param {Boolean} isOpen 是否开启定时器
   */
  setImgTimer(isOpen) {
    this.currentIndex = 0;
    if (!isOpen) {
      // 关闭定时器
      clearInterval(this.timer);
      this.timer = null;
    } else {
      // 开启定时器
      this.timer = setInterval(() => this.setImgLoop(), this.interval * 1000);
    }
  }

  /**
   * 图片图层循环
   */
  setImgLoop() {
    if (this.currentIndex >= this.data.length - 1) {
      this.currentIndex = 0;
    }
    if (this.timer) {
      this.currentIndex++;
      this.layer.setImageUrl(this.data[this.currentIndex].url);
    }
  }
  /**
   * 销毁
   */
  destroy() {
    this.setImgTimer(false);
  }
}

/**
 * 图例组件 点标记 marker sdk
 */
class MarkerSdk {
  constructor(config, sdk) {
    this.sdk = sdk;
    this.config = config;
  }
  /**
   * 设置数据
   * @param {Array} data 图例数据
   */
  setData(data) {
    let list = [];
    data.forEach((item) => {
      const path = [parseFloat(item.path[0]), parseFloat(item.path[1])];
      // 过滤点位
      if (!path[0] || !path[1]) return;

      const itemData = {
        ...item,
        id: item.id,
        name: item.name,
        path,
        icon: getIconName(item, this.config.iconFilter),
        angle: item.angle || 0
      };
      list.push(itemData);
    });
    this.data = list;
    return list;
  }
  /**
   * 加载图层
   * @param {Function} callback 回调函数
   * @returns 图层
   */
  async loadLayer(callback) {
    this.layer = await this.sdk.createMvMapMarkerLayer(
      this.data,
      this.config,
      callback
    );
    return this.layer;
  }
  /**
   * 清除图层
   */
  clearLayer() {
    if (!this.layer) return;
    this.sdk.removeMvMapMarkerLayer(this.layer);
    this.layer = null;
  }

  /**
   * 隐藏图层
   */
  hideLayer() {
    this.layer && this.sdk.hideMvMapMarkerLayer(this.layer);
  }

  /**
   * 显示图层
   */
  showLayer() {
    this.layer && this.sdk.showMvMapMarkerLayer(this.layer);
  }
}
/**
 * 图例组件 海量标记点 mass-marks sdk
 */
class MassMarksSdk {
  constructor(config, sdk) {
    this.sdk = sdk;
    this.config = config;
  }
  /**
   * 设置数据
   * @param {Array} data 图例数据
   */
  setData(data) {
    this.data = data;
    return data;
  }
  /**
   * 加载图层
   * @param {Function} callback 回调函数
   * @returns 图层
   */
  async loadLayer(callback) {
    this.layer = await this.sdk.createMvMapMassMarksLayer(
      this.data,
      this.config,
      callback
    );
    return this.layer;
  }
  /**
   * 清除图层
   */
  clearLayer() {
    if (!this.layer) return;
    this.sdk.hideMvMapMassMarksLayer(this.layer);
    this.layer.setMap(null);
    this.layer = null;
  }

  /**
   * 隐藏图层
   */
  hideLayer() {
    this.layer && this.sdk.hideMvMapMassMarksLayer(this.layer);
  }

  /**
   * 显示图层
   */
  showLayer() {
    this.layer && this.sdk.showMvMapMassMarksLayer(this.layer);
  }
}
/**
 * 图例组件 标记类 label-marker sdk
 */
class LabelMarkerSdk {
  constructor(config, sdk) {
    this.sdk = sdk;
    this.config = config;
  }
  /**
   * 设置数据
   * @param {Array} data 图例数据
   */
  setData(data) {
    this.data = data;
    return data;
  }
  /**
   * 加载图层
   * @param {Function} callback 回调函数
   * @returns 图层
   */
  async loadLayer(callback) {
    this.layer = await this.sdk.createMvMapLabelMarkerLayer(
      this.data,
      this.config,
      callback
    );
    return this.layer;
  }

  /**
   * 清除图层
   */
  clearLayer() {
    if (!this.layer) return;
    this.sdk.hideMvMapLabelMarkerLayer(this.layer);
    this.layer.clear();
    this.layer = null;
  }

  /**
   * 隐藏图层
   */
  hideLayer() {
    this.layer && this.sdk.hideMvMapLabelMarkerLayer(this.layer);
  }

  /**
   * 显示图层
   */
  showLayer() {
    this.layer && this.sdk.showMvMapLabelMarkerLayer(this.layer);
  }
}
/**
 * 图例组件 点聚合 cluster sdk
 */
class ClusterSdk {
  constructor(config, sdk) {
    this.sdk = sdk;
    this.config = config;
  }
  /**
   * 设置数据
   * @param {Array} data 图例数据
   */
  setData(data) {
    let list = [];
    data.forEach((item) => {
      const path = [parseFloat(item.path[0]), parseFloat(item.path[1])];
      // 过滤点位
      if (!path[0] || !path[1]) return;

      const itemData = {
        ...item,
        id: item.id,
        name: item.name,
        path,
        icon: getIconName(item, this.config.iconFilter),
        angle: item.angle || 0
      };
      list.push(itemData);
    });
    this.data = list;
    return list;
  }
  /**
   * 加载图层
   * @param {Function} callback 回调函数
   * @returns 图层
   */
  async loadLayer(callback) {
    this.layer = await this.sdk.createMvMapMarkerCluster(
      this.data,
      this.config,
      callback
    );
    return this.layer;
  }
  /**
   * 清除图层
   */
  clearLayer() {
    if (!this.layer) return;
    this.layer.setMap(null);
    this.layer = null;
  }

  /**
   * 隐藏图层
   */
  hideLayer() {
    this.layer && this.layer.setMap(null);
  }

  /**
   * 显示图层
   */
  showLayer() {
    this.layer && this.layer.setMap(this.sdk.getMvMap());
  }
}

/**
 * 图例组件 折线 polyline sdk
 */
class PolylineSdk {
  constructor(config, sdk) {
    this.sdk = sdk;
    this.config = config;
  }
  /**
   * 设置数据
   * @param {Array} data 图例数据
   */
  setData(data) {
    this.data = data;
    return data;
  }
  /**
   * 加载图层
   * @param {Function} callback 回调函数
   * @returns 图层
   */
  async loadLayer(callback) {
    this.layer = await this.sdk.createMvMapLineLayer(
      this.data,
      this.config,
      callback
    );
    return this.layer;
  }
  /**
   * 清除图层
   */
  clearLayer() {
    if (!this.layer) return;
    this.sdk.removeMvMapLineLayer(this.layer);
    this.layer = null;
  }

  /**
   * 隐藏图层
   */
  hideLayer() {
    // this.layer && this.sdk.getMvMap().remove(this.layer)
    this.sdk.hideMvMapLineLayer(this.layer);
  }

  /**
   * 显示图层
   */
  showLayer() {
    // this.layer && this.sdk.getMvMap().add(this.layer)
    this.sdk.showMvMapLineLayer(this.layer);
  }
}

/**
 * 图例组件 热力图 heat sdk
 */
class HeatSdk {
  constructor(config, sdk) {
    this.sdk = sdk;
    this.config = config;
  }
  /**
   * 设置数据
   * @param {Array} data 图例数据
   */
  setData(data) {
    this.data = data;
    return data;
  }
  /**
   * 加载图层
   * @returns 图层
   */
  async loadLayer() {
    this.layer = await this.sdk.createMvMapHeatMap(this.data, this.config);
    return this.layer;
  }
  /**
   * 清除图层
   */
  clearLayer() {
    if (!this.layer) return;
    this.layer.setMap(null);
    this.layer = null;
  }

  /**
   * 隐藏图层
   */
  hideLayer() {
    this.layer && this.layer.hide();
  }

  /**
   * 显示图层
   */
  showLayer() {
    this.layer && this.layer.show();
  }
}

/**
 * 图例组件 自定义 custom-sdk
 */
class CustomSdk {
  constructor(config, sdk) {
    this.sdk = sdk;
    this.config = config;
  }
  /**
   * 设置数据
   * @param {Array} data 图例数据
   */
  setData(data) {
    this.data = data;
    return data;
  }
  /**
   * 加载图层
   * @returns 图层
   */
  async loadLayer() {
    this.layer = "自定义图层";
    return this.layer;
  }
}

/**
 * 图例类型
 * lk 高德路况
 * point UI 海量点
 * line UI 海量线
 * img 图片
 * marker 标记点
 * mass-marks 海量标记点
 * label-marker 标记类（点标注、文本标注）
 * marks 海量标记点 （暂无扩展)
 * cluster 点聚合
 * polyline 折线
 * heat 热力图
 */
const modelTypeArr = [
  { model: "lk", name: "高德路况" },
  { model: "point", name: "海量点", hasTheme: true },
  { model: "line", name: "海量线" },
  { model: "img", name: "图片" },
  { model: "marker", name: "标记点", hasTheme: true },
  { model: "mass-marks", name: "海量标记点", hasTheme: true },
  { model: "label-marker", name: "标记类", hasTheme: true },
  { model: "cluster", name: "点聚合", hasTheme: true },
  { model: "polyline", name: "折线" },
  { model: "heat", name: "热力图" }
];
/**
 * 获取该图例sdk
 * @param {Object} config 图例配置
 * @param {Class} mapSdk 地图sdk类
 * @returns 当前图例sdk
 */
const getMvMapIconSdk = (config, mapSdk) => {
  let sdk = null;
  const model = config.model;
  switch (model) {
    case "lk":
      sdk = new LkSdk(config, mapSdk);
      break;
    case "point":
      sdk = new PointSdk(config, mapSdk);
      break;
    case "line":
      sdk = new LineSdk(config, mapSdk);
      break;
    case "img":
      sdk = new ImgSdk(config, mapSdk);
      break;
    case "marker":
      sdk = new MarkerSdk(config, mapSdk);
      break;
    case "mass-marks":
      sdk = new MassMarksSdk(config, mapSdk);
      break;
    case "label-marker":
      sdk = new LabelMarkerSdk(config, mapSdk);
      break;
    case "cluster":
      sdk = new ClusterSdk(config, mapSdk);
      break;
    case "polyline":
      sdk = new PolylineSdk(config, mapSdk);
      break;
    case "heat":
      sdk = new HeatSdk(config, mapSdk);
      break;
    default:
      sdk = new CustomSdk(config, mapSdk);
      break;
  }
  return sdk;
};

/**
 * 是否是图例model
 * @param {String} model 图例类型
 * @returns Boolean
 */
const getModelConfig = (model) => {
  return modelTypeArr.find((i) => i.model === model);
};

export { getMvMapIconSdk, getModelConfig };
