import DataUtils from '../utils/DataUtils';
import VerifyUtils from '../utils/VerifyUtils';
import LayerProvider from '../geog/LayerProvider';
import GeoJsonProvider from '../geog/GeoJsonProvider';
import AnnotationLayer from '../common/AnnotationLayer';
import SimpleMarkerLayer from '../common/SimpleMarkerLayer';
import LabelLayer from './LabelLayer';

/**
 * 定义管线流向图层
 *
 * @alias PipeflowLayer
 *
 * @summary <用于加载管线流向图层>
 */
export default class PipeflowLayer {
  /**
   * 构造函数
   * @param {Object} options -图层选项
   */
  constructor(options) {
    /**
     * 地图对象
     * @type {Object}
     */
    this._map = options.map;

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

    /**
     * 是否缓存的
     * @type {Boolean}
     */
    this._cached = DataUtils.default(options.cached, false);

    /**
     * 图标ID
     * @type {String}
     */
    this._icon = DataUtils.default(options.icon, 'faci_flow');

    /**
     * 过滤条件数组
     * @type {Array}
     */
    this._filter = DataUtils.default(options.filter, undefined);

    /**
     * 是否分级显示
     * @type {Boolean}
     */
    this._showByLevel = DataUtils.default(options.showByLevel, true);

    /**
     * 是否显示标注
     * @type {Boolean}
     */
    this._showLabel = DataUtils.default(options.showLabel, false);

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

    /**
     * 文本大小
     * @type {Number}
     */
    this._textSize = DataUtils.default(options.textSize, 15);

    /**
     * 默认数据源ID
     * @type {String}
     */
    this._defaultSourceId = DataUtils.default(options.sourceId, 'pipe_pipeline_flow');

    /**
     * 默认图层ID
     * @type {String}
     */
    this._defaultLayerId = DataUtils.default(options.layerId, this._defaultSourceId);

    // 数据源ID
    this._sourceId = this._showByLevel ? (this._defaultSourceId + '-lvl1') : this._defaultSourceId;
    this._lvl2_sourceId = this._showByLevel ? (this._defaultSourceId + '-lvl2') : undefined;
    this._lvl3_sourceId = this._showByLevel ? (this._defaultSourceId + '-lvl3') : undefined;

    // 图层ID
    this._layerId = this._showByLevel ? (this._defaultLayerId + '-lvl1') : this._defaultLayerId;
    this._lvl2_layerId = this._defaultLayerId + '-lvl2';
    this._lvl3_layerId = this._defaultLayerId + '-lvl3';

    // 标注图层ID
    this._labelLayerId = this._layerId + '-label';
    this._lvl2_labelLayerId = this._lvl2_layerId + '-label';
    this._lvl3_labelLayerId = this._lvl3_layerId + '-label';

    /* 图层对象 */
    this._flowLayer = null;  // 流向
    this._lvl2_flowLayer = null;
    this._lvl3_flowLayer = null;

    this._labelLayer = null; // 标注
    this._lvl2_labelLayer = null;
    this._lvl3_labelLayer = null;

    // 初始化图层
    this._initLayer();

    if (this._showLabel) {
      // 初始化标注图层
      this._initLabelLayer();
    }
  }

  /** 公有方法 **/
  /**
   * 设置数据
   * @param {Object} data -GeoJSON要素集
   */
  setData(data) {
    // 加载图层
    this.loadLayer();

    if (data) {
      this._flowLayer.setData(data);

      if (this._showLabel) {
        this._labelLayer.setData(data);
      }
    }
  }

  /**
   * 设置筛选器
   * @param {Array} filter -筛选器
   */
  setFilter(filter) {
    if (!this.hasLayer()) return;

    if (filter && VerifyUtils.isArray(filter)) {
      // 一级流向
      this._flowLayer.setFilter(filter);
      if (this._showLabel) {
        this._labelLayer.setFilter(filter);
      }

      if (this._showByLevel) {
        this._lvl2_flowLayer.setFilter(filter);
        this._lvl3_flowLayer.setFilter(filter);

        if (this._showLabel) {
          this._lvl2_labelLayer.setFilter(filter);
          this._lvl3_labelLayer.setFilter(filter);
        }
      }
    }
  }

  /**
   * 设置绘制属性
   * @param {String} name -属性名称
   * @param {String|Object} value -属性值
   */
  setPaintProperty(name, value) {
    // 一级流向
    this._flowLayer.setPaintProperty(name, value);
    if (this._showLabel) {
      this._labelLayer.setPaintProperty(name, value);
    }

    if (this._showByLevel) {
      this._lvl2_flowLayer.setPaintProperty(name, value);
      this._lvl3_flowLayer.setPaintProperty(name, value);

      if (this._showLabel) {
        this._lvl2_labelLayer.setPaintProperty(name, value);
        this._lvl3_labelLayer.setPaintProperty(name, value);
      }
    }
  }

  /**
   * 设置布局属性
   * @param {String} name -属性名称
   * @param {String|Object} value -属性值
   */
  setLayoutProperty(name, value) {
    // 一级流向
    this._flowLayer.setLayoutProperty(name, value);
    if (this._showLabel) {
      this._labelLayer.setLayoutProperty(name, value);
    }

    if (this._showByLevel) {
      this._lvl2_flowLayer.setLayoutProperty(name, value);
      this._lvl3_flowLayer.setLayoutProperty(name, value);

      if (this._showLabel) {
        this._lvl2_labelLayer.setLayoutProperty(name, value);
        this._lvl3_labelLayer.setLayoutProperty(name, value);
      }
    }
  }

  /**
   * 加载图层
   */
  loadLayer() {
    if (!this.hasLayer()) {
      // 一级流向
      this._flowLayer.loadLayer();
      if (this._showLabel) {
        this._labelLayer.loadLayer();
      }

      if (this._showByLevel) {
        this._lvl2_flowLayer.loadLayer();
        this._lvl3_flowLayer.loadLayer();

        if (this._showLabel) {
          this._lvl2_labelLayer.loadLayer();
          this._lvl3_labelLayer.loadLayer();
        }
      }
    }

    // 显示图层
    this.showLayer(true);
  }

  /**
   * 显示/隐藏图层
   * @param {Boolean} isShow -是否显示图层
   */
  showLayer(isShow) {
    // 一级流向
    this._flowLayer.showLayer(isShow);
    if (this._showLabel) {
      this._labelLayer.showLayer(isShow);
    }

    if (this._showByLevel) {
      this._lvl2_flowLayer.showLayer(isShow);
      this._lvl3_flowLayer.showLayer(isShow);

      if (this._showLabel) {
        this._lvl2_labelLayer.showLayer(isShow);
        this._lvl3_labelLayer.showLayer(isShow);
      }
    }
  }

  /**
   * 判断图层是否已加载
   *
   * @returns {Boolean}
   */
  hasLayer() {
    let has = this._flowLayer.hasLayer();

    if (this._showLabel) {
      has = (
        this._flowLayer.hasLayer() &&
        this._labelLayer.hasLayer()
      );
    }

    return has;
  }

  /**
   * 移除图层
   */
  removeLayer() {
    if (this._cached) return;

    if (this._showByLevel) {
      if (this._showLabel) {
        // 标注
        this._lvl2_labelLayer.removeLayer();
        this._lvl3_labelLayer.removeLayer();
      }

      this._lvl3_flowLayer.removeLayer();
      this._lvl2_flowLayer.removeLayer();
    }

    // 一级流向
    if (this._showLabel) {
      this._labelLayer.removeLayer();
    }
    this._flowLayer.removeLayer();
  }

  /**
   * 移除数据源
   */
  removeSource() {
    if (this._cached) return;

    // 清空数据源
    this._clearSourceData();

    const map = this._map;

    // 更新数据源
    LayerProvider.updateSource(map, this._sourceId, GeoJsonProvider.getEmptyFC());
    if (this._showByLevel) {
      LayerProvider.updateSource(map, this._lvl2_sourceId, GeoJsonProvider.getEmptyFC());
      LayerProvider.updateSource(map, this._lvl3_sourceId, GeoJsonProvider.getEmptyFC());
    }
    // 移除数据源
    LayerProvider.removeSource(map, this._sourceId);
    if (this._showByLevel) {
      LayerProvider.removeSource(map, this._lvl2_sourceId);
      LayerProvider.removeSource(map, this._lvl3_sourceId);
    }
  }

  /** 私有方法 **/
  /**
   * 初始化图层
   */
  _initLayer() {
    const map = this._map;
    const minZoom = this._minzoom;
    const cached = this._cached;

    const filter = this._filter;

    if (!this._showByLevel) {
      // 流向
      this._flowLayer = new SimpleMarkerLayer({
        map: map,
        minzoom: minZoom,
        icon: this._icon,
        filter: filter,
        sourceId: this._sourceId,
        layerId: this._layerId
      });
      // 设置自定义样式
      this._flowLayer.setLayoutProperty('icon-rotation-alignment', 'map');
      this._flowLayer.setLayoutProperty('icon-rotate', ['get', 'bearing']);
    } else {
      // 一级流向
      this._flowLayer = new SimpleMarkerLayer({
        map: map,
        minzoom: minZoom,
        icon: this._icon,
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '1']] : filter,
        sourceId: this._sourceId,
        layerId: this._layerId
      });
      // 设置自定义样式
      this._flowLayer.setLayoutProperty('icon-rotation-alignment', 'map');
      this._flowLayer.setLayoutProperty('icon-rotate', ['get', 'bearing']);

      // 二级流向
      this._lvl2_flowLayer = new SimpleMarkerLayer({
        map: map,
        minzoom: minZoom,
        icon: this._icon,
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '2']] : filter,
        sourceId: this._lvl2_sourceId,
        layerId: this._lvl2_layerId
      });
      // 设置自定义样式
      this._lvl2_flowLayer.setLayoutProperty('icon-rotation-alignment', 'map');
      this._lvl2_flowLayer.setLayoutProperty('icon-rotate', ['get', 'bearing']);

      // 三级流向
      this._lvl3_flowLayer = new SimpleMarkerLayer({
        map: map,
        minzoom: minZoom,
        icon: this._icon,
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '3']] : filter,
        sourceId: this._lvl3_sourceId,
        layerId: this._lvl3_layerId
      });
      // 设置自定义样式
      this._lvl3_flowLayer.setLayoutProperty('icon-rotation-alignment', 'map');
      this._lvl3_flowLayer.setLayoutProperty('icon-rotate', ['get', 'bearing']);
    }
  }

  /**
   * 初始化标注图层
   */
  _initLabelLayer() {
    const map = this._map;
    const minZoom = map.getMaxZoom() - 1.5;
    const cached = this._cached;

    let filter = this._filter;

    if (!this._showByLevel) {
      // 标注
      this._labelLayer = new LabelLayer({
        map: map,
        minzoom: minZoom + 0.05,
        field: this._fieldName,
        textSize: this._textSize,
        textRotate: ['get', 'bearing_label'],
        radialOffset: 0.05,
        filter: filter,
        sourceId: this._sourceId,
        layerId: this._labelLayerId
      });
    } else {
      /*
      if (filter && this._cached) {
        filter = ['all', filter, ['==', 'show_level', '1']]
      }
      */

      // 一级标注
      this._labelLayer = new LabelLayer({
        map: map,
        minzoom: minZoom + 0.05,
        field: this._fieldName,
        textSize: this._textSize,
        textRotate: ['get', 'bearing_label'],
        radialOffset: 0.05,
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '1']] : filter,
        sourceId: this._sourceId,
        layerId: this._labelLayerId
      });

      // 二级标注
      this._lvl2_labelLayer = new LabelLayer({
        map: map,
        minzoom: minZoom + 0.05,
        field: this._fieldName,
        textSize: this._textSize,
        textRotate: ['get', 'bearing_label'],
        radialOffset: 0.05,
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '2']] : filter,
        sourceId: this._lvl2_sourceId,
        layerId: this._lvl2_labelLayerId
      });

      // 三级标注
      this._lvl3_labelLayer = new LabelLayer({
        map: map,
        minzoom: minZoom + 0.05,
        field: this._fieldName,
        textSize: this._textSize,
        textRotate: ['get', 'bearing_label'],
        radialOffset: 0.05,
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '3']] : filter,
        sourceId: this._lvl3_sourceId,
        layerId: this._lvl3_labelLayerId
      });
    }
  }

  /**
   * 清空数据源数据
   */
  _clearSourceData() {
    if (this._cached) return;

    const map = this._map;

    // 一级管线流向
    let source = map.getSource(this._sourceId);
    if (source && source._data && VerifyUtils.isGeoJsonFC(source._data)) {
      source._data.features = [];
    }
    if (this._showByLevel) {
      // 二级管线流向
      source = map.getSource(this._lvl2_sourceId);
      if (source && source._data && VerifyUtils.isGeoJsonFC(source._data)) {
        source._data.features = [];
      }

      // 三级管线流向
      source = map.getSource(this._lvl3_sourceId);
      if (source && source._data && VerifyUtils.isGeoJsonFC(source._data)) {
        source._data.features = [];
      }
    }
  }
}
