import DataUtils from '../utils/DataUtils';
import GeoJsonProvider from '../geog/GeoJsonProvider';
import LayerProvider from '../geog/LayerProvider';
import SimpleFillLayer from '../common/SimpleFillLayer';
import FlowingLayer from '../common/FlowingLayer';
import PipenetFlowingLayer from './PipenetFlowingLayer';

import { pipenetMergeAnalystResult } from '../utils/PipenetUtils';
import { getApi } from '../../api/http';

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

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

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

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

    /**
     * 社区数据源ID
     * @type {String}
     */
    this._sourceId = DataUtils.default(options.sourceId, 'pipenet_village');
    /**
     * 社区图层ID
     * @type {String}
     */
    this._layerId = DataUtils.default(options.layerId, this._sourceId);

    this.sourceId = 0; // 起始点ID

    /* 要素集 */
    this._fc = GeoJsonProvider.getEmptyFC();       // 管网流向
    this._mergedFC = GeoJsonProvider.getEmptyFC(); // 合并的管线

    this._villageFC = GeoJsonProvider.getEmptyFC(); // 社区

    /** 图层 **/
    this._flowingLayer = null; // 管网流向
    this._villageLayer = null; // 覆盖范围

    // 初始化图层列表
    this._initLayers();
  }

  /** 公有方法 **/
  /**
   * 设置管线路径颜色
   * @param {String} color -16进制颜色字符串
   */
  setColor(color) {
    this._flowingLayer.setColor(color);
  }

  /**
   * 查询流向数据
   * @param {String} code -管线/检查井编码
   * @param {String} layerType - 图层类型
   * @param {Function} callback -回调函数
   */
  async queryData(code, layerType, callback=null) {
    this.sourceId = 0;

    this._fc.features = [];
    this._villageFC.features = [];
    // 结果要素集
    let resultFC = GeoJsonProvider.getEmptyFC();

    const map = this._map;
    const category = layerType === 'pipeline' ? 'pipenet' : 'pipenet-down';
    // 获取管线网络查询url
    const queryUrl = LayerProvider.getBaseLayerQueryUrl(map, category, code);
    if (!queryUrl) {
      if (callback) { // 回调
        callback('downstream', resultFC);
      }
      return false;
    }

    // 查询管网
    const result = await getApi(queryUrl);
    const fc = result.data;
    if (fc && fc.features && fc.features.length > 0) {
      this.sourceId = fc.features[0].properties.source;
    }
    if (this.sourceId < 1) {
      if (callback) { // 回调
        callback('downstream', resultFC);
      }
      return false;
    }

    // 查询下游管网流向
    await this._query('pipenet-downstream');
    // 查询管网覆盖范围
    await this._query('pipenet-coverage');

    // 删除分析结果
    await this._query('pipenet-delete');

    // 管网流向
    /*
    if (this._fc.features.length > 0) {
      // 获取唯一要素集合
      this._fc.features = GeoJsonProvider.getUniqueFeatures(this._fc.features, 'path');

      // 设置流向数据
      this._flowingLayer.setData(this._fc);
      // 开始动画
      this._flowingLayer.start();
    }
    */
    if (this._mergedFC.features.length > 0) {
      // 获取唯一要素集合
      this._mergedFC.features = GeoJsonProvider.getUniqueFeatures(this._mergedFC.features, 'path');

      // 设置流向数据
      this._flowingLayer.setData(this._mergedFC);
      // 开始动画
      this._flowingLayer.start();
    }

    // 覆盖范围
    this._villageLayer.setData(this._villageFC);

    resultFC.features = this._villageFC.features;
    // 回调
    if (callback) {
      callback('downstream', resultFC);
    }
  }

  /**
   * 停止流向
   */
  stop() {
    this._flowingLayer.stop();
    // 移除图层
    this.removeLayer();
  }

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

    // 社区图层
    if (this._villageLayer) {
      this._villageLayer.removeLayer();
    }
  }

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

    // 社区图层
    if (this._villageLayer) {
      this._villageLayer.showLayer(isShow);
    }
  }

  /** 私有方法 **/
  /**
   * 初始化图层列表
   */
  _initLayers() {
    const map = this._map;
    const minZoom = this._minzoom;

    // 管网流向图层
    //this._flowingLayer = new FlowingLayer({
    this._flowingLayer = new PipenetFlowingLayer({
      map: map,
      minzoom: minZoom,
      color: this._lineColor,
      width: this._lineWidth,
      sourceId: 'pipe_flowing-downstream'
    });

    // 覆盖范围(社区)图层
    this._villageLayer = new SimpleFillLayer({
      map: map,
      minzoom: minZoom,
      color: '#EEE8AA',
      opacity: 0.1,
      outline: true,
      lineColor: '#FFFACD',
      lineWidth: 2.0,
      lineOpacity: 0.75,
      dasharray: [2.5, 1.5],
      sourceId: this._sourceId,
      layerId: this._layerId
    });
    // 设置空数据
    this._villageLayer.setData(GeoJsonProvider.getEmptyFC());
  }

  /**
   * 查询管网分析结果
   * @param {String} type -分析类型
   */
  async _query(type) {
    const map = this._map;
    const sourceId = this.sourceId;

    // 获取管网函数查询url
    const queryUrl = LayerProvider.getBaseLayerQueryUrl(map, type, sourceId);
    if (!queryUrl) return false;

    // 查询管网分析结果
    await getApi(queryUrl).then(res => {
      const fc = res.data;
      if (fc && fc.features && fc.features.length > 0) {
        switch (type) {
          case 'pipenet-downstream': { // 流向
            // 合并管线数据
            this._mergedFC.features = pipenetMergeAnalystResult(fc.features);

            // 合并管网流向
            this._fc.features = this._fc.features.concat(fc.features);
            break;
          }
          case 'pipenet-coverage': { // 覆盖范围
            fc.features.forEach((fea) => {
              fea.properties.layer_type = 'village';
            });
            // 合并覆盖范围
            this._villageFC.features = this._villageFC.features.concat(fc.features);
            break;
          }
          default:
            break;
        }
      }

      return true;

    }).catch(err => {
      return false;
    });
  }
}
