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

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

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

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

    /**
     * 线颜色
     * @type {String}
     */
    this._lineColor = DataUtils.default(options.color, '#E67D32');

    /**
     * 线宽
     * @type {Number}
     */
    this._lineWidth = DataUtils.default(options.width, 9.5);

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

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

    /**
     * 是否显示流向
     * @type {Boolean}
     */
    this._showDirection = DataUtils.default(options.showDirection, false);

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

    /**
     * 默认图层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._oriLayerId = this._layerId + '-ori';
    this._lvl2_oriLayerId = this._lvl2_layerId + '-ori';
    this._lvl3_oriLayerId = this._lvl3_layerId + '-ori';

    /* 图层对象 */
    this._lineLayer = null;      // 一级管线
    this._lvl2_lineLayer = null; // 二级管线
    this._lvl3_lineLayer = null; // 三级管线

    this._oriLayer = null; // 方向
    this._lvl2_oriLayer = null;
    this._lvl3_oriLayer = null;

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

    if (this._showDirection) {
      // 初始化方向图层
      this._initDirectionLayer();
    }
  }

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

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

      if (this._showDirection) {
        this._oriLayer.setData(data);
      }
    }
  }

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

    if (filter && VerifyUtils.isArray(filter)) {
      // 设置筛选器
      this._lineLayer.setFilter(filter);
      if (this._showDirection) {
        this._oriLayer.setFilter(filter);
      }

      if (this._showByLevel) {
        this._lvl2_lineLayer.setFilter(filter);
        this._lvl3_lineLayer.setFilter(filter);

        if (this._showDirection) {
          this._lvl2_oriLayer.setFilter(filter);
          this._lvl3_oriLayer.setFilter(filter);
        }
      }
    }
  }

  /**
   * 设置绘制属性
   * @param {String} name -属性名称
   * @param {String|Object} value -属性值
   */
  setPaintProperty(name, value) {
    this._lineLayer.setPaintProperty(name, value);

    if (this._showByLevel) {
      this._lvl2_lineLayer.setPaintProperty(name, value);
      this._lvl3_lineLayer.setPaintProperty(name, value);
    }
  }

  /**
   * 设置布局属性
   * @param {String} name -属性名称
   * @param {String|Object} value -属性值
   */
  setLayoutProperty(name, value) {
    this._lineLayer.setLayoutProperty(name, value);

    if (this._showByLevel) {
      this._lvl2_lineLayer.setLayoutProperty(name, value);
      this._lvl3_lineLayer.setLayoutProperty(name, value);
    }
  }

  /**
   * 重置线宽
   */
  resetLineWidth() {
    const map = this._map;
    const minZoom = this._minzoom;
    const maxZoom = map.getMaxZoom();

    this.setPaintProperty('line-width', {
      base: 1.5,
      stops: [
        [minZoom, 0.75],
        [maxZoom, this._lineLayer._lineWidth],
      ]
    })
  }

  /**
   * 加载图层
   */
  loadLayer() {
    if (!this.hasLayer()) {
      // 一级管线
      this._lineLayer.loadLayer();
      if (this._showDirection) {
        this._oriLayer.loadLayer();
      }

      if (this._showByLevel) {
        this._lvl2_lineLayer.loadLayer();
        this._lvl3_lineLayer.loadLayer();

        if (this._showDirection) {
          this._lvl2_oriLayer.loadLayer();
          this._lvl3_oriLayer.loadLayer();
        }
      }
    }

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

  /**
   * 显示/隐藏图层
   * @param {Boolean} isShow -是否显示图层
   */
  showLayer(isShow) {
    // 一级管线
    this._lineLayer.showLayer(isShow);
    if (this._showDirection) {
      this._oriLayer.showLayer(isShow);
    }

    if (this._showByLevel) {
      this._lvl2_lineLayer.showLayer(isShow);
      this._lvl3_lineLayer.showLayer(isShow);

      if (this._showDirection) {
        this._lvl2_oriLayer.showLayer(isShow);
        this._lvl3_oriLayer.showLayer(isShow);
      }
    }
  }

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

    if (this._showByLevel) {
      has = (
        this._lineLayer.hasLayer() &&
        this._lvl2_lineLayer.hasLayer() &&
        this._lvl3_lineLayer.hasLayer()
      );
    }

    return has;
  }

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

    if (this._showByLevel) {
      if (this._showDirection) {
        // 管线流向
        this._lvl3_oriLayer.removeLayer();
        this._lvl2_oriLayer.removeLayer();
      }

      this._lvl3_lineLayer.removeLayer();
      this._lvl2_lineLayer.removeLayer();
    }

    // 一级管线
    if (this._showDirection) {
      this._oriLayer.removeLayer();
    }

    this._lineLayer.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);
    }
  }

  /**
   * 绑定单击事件
   * @param {Function} event -事件函数
   */
  onClick(event) {
    // 一级管线
    this._lineLayer.onClick(event);

    if (this._showByLevel) {
      // 二级管线
      this._lvl2_lineLayer.onClick(event);
      // 三级管线
      this._lvl3_lineLayer.onClick(event);
    }
  }

  /**
   * 绑定事件
   * @param {String} name -事件名称
   * @param {Function} event -事件函数
   */
  onEvent(name, event) {
    // 一级管线
    this._lineLayer.onEvent(name, event);

    if (this._showByLevel) {
      // 二级管线
      this._lvl2_lineLayer.onEvent(name, event);
      // 三级管线
      this._lvl3_lineLayer.onEvent(name, event);
    }
  }

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

    const filter = this._filter;

    if (!this._showByLevel) {
      // 管线
      this._lineLayer = new SimpleLineLayer({
        map: map,
        minzoom: minZoom,
        color: this._lineColor,
        width: this._lineWidth,
        filter: filter,
        sourceId: this._sourceId,
        layerId: this._layerId
      });
    } else {
      // 一级管线
      this._lineLayer = new SimpleLineLayer({
        map: map,
        minzoom: minZoom,
        color: this._lineColor,
        width: this._lineWidth,
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '1']] : filter,
        sourceId: this._sourceId,
        layerId: this._layerId
      });

      // 二级管线
      this._lvl2_lineLayer = new SimpleLineLayer({
        map: map,
        minzoom: minZoom + 2.5,
        color: this._lineColor,
        width: this._lineWidth,
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '2']] : filter,
        sourceId: this._lvl2_sourceId,
        layerId: this._lvl2_layerId
      });

      // 三级管线
      this._lvl3_lineLayer = new SimpleLineLayer({
        map: map,
        minzoom: minZoom + 4.5,
        color: this._lineColor,
        width: this._lineWidth,
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '3']] : filter,
        sourceId: this._lvl3_sourceId,
        layerId: this._lvl3_layerId
      });
    }

    // 管线瓦片，需初始化默认鼠标事件
    if (cached) {
      this._lineLayer._onEvent();

      if (this._showByLevel) {
        this._lvl2_lineLayer._onEvent();
        this._lvl3_lineLayer._onEvent();
      }
    }
  }

  /**
   * 初始化方向图层
   */
  _initDirectionLayer() {
    const map = this._map;
    const minZoom = this._minzoom + 6;
    const cached = this._cached;

    const filter = this._filter;

    if (!this._showByLevel) {
      // 管线方向
      this._oriLayer = new SimpleMarkerLayer({
        map: map,
        minzoom: minZoom,
        icon: 'faci_flow',
        filter: filter,
        sourceId: this._sourceId,
        layerId: this._oriLayerId
      });
      this._oriLayer.setLayoutProperty('symbol-placement', 'line');
      this._oriLayer.setLayoutProperty('symbol-spacing', 1500);
    } else {
      // 一级管线方向
      this._oriLayer = new SimpleMarkerLayer({
        map: map,
        minzoom: minZoom,
        icon: 'faci_flow',
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '1']] : filter,
        sourceId: this._sourceId,
        layerId: this._oriLayerId
      });
      this._oriLayer.setLayoutProperty('symbol-placement', 'line');
      this._oriLayer.setLayoutProperty('symbol-spacing', 1500);

      // 二级管线方向
      this._lvl2_oriLayer = new SimpleMarkerLayer({
        map: map,
        minzoom: minZoom,
        icon: 'faci_flow',
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '2']] : filter,
        sourceId: this._lvl2_sourceId,
        layerId: this._lvl2_layerId
      });
      this._lvl2_oriLayer.setLayoutProperty('symbol-placement', 'line');
      this._lvl2_oriLayer.setLayoutProperty('symbol-spacing', 1500);

      // 三级管线方向
      this._lvl3_oriLayer = new SimpleMarkerLayer({
        map: map,
        minzoom: minZoom,
        icon: 'faci_flow',
        filter: (filter && cached) ? ['all', filter, ['==', 'show_level', '3']] : filter,
        sourceId: this._lvl3_sourceId,
        layerId: this._lvl3_oriLayerId
      });
      this._lvl3_oriLayer.setLayoutProperty('symbol-placement', 'line');
      this._lvl3_oriLayer.setLayoutProperty('symbol-spacing', 1500);
    }
  }

  /**
   * 清空数据源数据
   */
  _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 = [];
      }
    }
  }
}
