import DataUtils from '../utils/DataUtils';
import GeogUtils from '../utils/GeogUtils';
import MapProvider from './MapProvider';
import GeoJsonProvider from './GeoJsonProvider';
import LocationLayer from '../common/LocationLayer';

/**
 * 定位(+聚焦)图层对象类
 * @alias LocationProvider
 *
 * @summary <用于定位/聚焦的点/线加载>
 */
export default class LocationProvider {
  /**
   * 构造函数
   * @param {Object} options -图层选项
   */
  constructor(options) {
    /**
     * 地图对象
     * @type {Object}
     */
    this._map = options.map;

    /**
     * 最小缩放层级
     * @type {Number}
     */
    this._minzoom = DataUtils.default(options.minzoom, 10);

    /**
     * 图标偏移
     * @type {Array}
     */
    this._offset = DataUtils.default(options.offset, [0, -22]);

    /**
     * 线宽
     */
    this._lineWidth = DataUtils.default(options.lineWidth, 7.5);

    /**
     * 字段名
     * @type {String}
     */
    this._fieldName = DataUtils.default(options.field, undefined);

    /**
     * 文本偏移
     * @type {Array}
     */
    this._textOffset = DataUtils.default(options.textOffset, [0, -2.0]);

    // 创建图层对象
    this._locationLayer = new LocationLayer({
      map: this._map,
      minzoom: this._minzoom,
      lineWidth: this._lineWidth,
      offset: this._offset,
      field: this._fieldName,
      textOffset: this._textOffset
    });
  }

  /**
   * 缩放至要素集合
   * @param {Object} map -地图对象
   * @param {Array} features -GeoJson要素集合
   * @param {Number} zoom - 缩放层级
   */
  static fitToFeatures(map, features, zoom = 15.75) {
    if (!features || features.length === 0) return;

    const pointFC = GeoJsonProvider.getEmptyFC();
    pointFC.features = features.filter((fea) => {
      return fea.geometry.type.toLowerCase() === 'point';
    });

    const lineFC = GeoJsonProvider.getEmptyFC();
    lineFC.features = features.filter((fea) => {
      return fea.geometry.type.toLowerCase() === 'linestring' ||
             fea.geometry.type.toLowerCase() === 'multilinestring';
    });

    // 计算包围盒
    let bboxP = [], bboxL = [];
    if (pointFC.features.length > 0) {
      let pntFea = pointFC.features[0]
      bboxP = pointFC.features.length === 1
              ? [pntFea.geometry.coordinates, pntFea.geometry.coordinates]
              : GeogUtils.calcBBox(pointFC);
    }
    if (lineFC.features.length > 0) {
      bboxL = GeogUtils.calcBBox(lineFC);
    }

    // 缩放至要素范围
    if (bboxP.length > 0 || bboxL.length > 0) {
      let bbox = [];
      let isJumpTo = false;
      if (bboxP.length === 1 && bboxL.length === 0) {
        isJumpTo = true;
      } else if (bboxP.length > 0 && bboxL.length === 0) {
        bbox = bboxP;
      } else if (bboxP.length === 0 && bboxL.length > 0) {
        bbox = bboxL;
      } else {
        bbox = [
          [Math.min(bboxP[0][0], bboxL[0][0]), Math.min(bboxP[0][1], bboxL[0][1])],
          [Math.max(bboxP[1][0], bboxL[1][0]), Math.max(bboxP[1][1], bboxL[1][1])]
        ];
      }

      if (isJumpTo) {
        MapProvider.jumpTo(map, bboxP[0], zoom);
      } else {
        MapProvider.fitBounds(map, bbox, zoom, true);
      }
    }
  }

  /**
   * 定位
   * @param {Array} center -经纬度
   * @param {Number} zoom -缩放层级
   */
  locate(center, zoom = null, jump = false) {
    this._locationLayer.locate(center, zoom, jump);
  }

  /**
   * 添加定位
   * @param {Array|Object} data -数据
   * @param {Number} zoom -缩放层级
   */
  addLocate(data, zoom = null, jump = false) {
    this._locationLayer.addData(data, zoom, jump);
  }

  /**
   * 定位数据
   * @param {Array|Object} data -数据
   * @param {Number} zoom -缩放层级
   * @param {Boolean} jump -是否直接定位
   */
  setLocate(data, zoom = null, jump = false) {
    this._locationLayer.setData(data, zoom, jump);
  }

  /**
   * 聚焦数据
   * @param {Array|Object} data -数据
   * @param {Number} zoom -缩放层级
   * @param {Boolean} jump -是否直接定位
   */
  setFocus(data, zoom = null, jump = false) {
    this._locationLayer.setFocus(data, zoom, jump);
  }

  /**
   * 设置选中
   * @param {Object} data -GeoJSON要素集
   */
  setSelection(data) {
    this._locationLayer.setSelection(data);
  }

  /**
   * 开始拖拽
   */
  startDragging() {
    this._locationLayer.startDragging();
  }

  /**
   * 停止拖拽
   */
  stopDragging() {
    this._locationLayer.stopDragging();
  }

  /**
   * 获取拖拽要素
   *
   * @returns {Object}
   */
  getDraggingFeature() {
    return this._locationLayer._draggingFeature;
  }

  /**
   * 获取数据
   *
   * @returns {Object}
   */
  getData() {
    // 判断返回折线要素集 or 点要素集
    const lineFC = this._locationLayer._lineFC;
    if (lineFC && lineFC.features && lineFC.features.length > 0) {
      return lineFC;
    }

    return this._locationLayer._fc;
  }

  /**
   * 清除数据
   */
  clearData() {
    this._locationLayer.clearData();
  }

  /**
   * 显示/隐藏图层
   * @param {Boolean} isShow -是否显示图层
   */
  showLayer(isShow = true) {
    this._locationLayer.showLayer(isShow);
  }

  /**
   * 移除图层
   */
  removeLayer() {
    this._locationLayer.removeLayer();
  }
}
