import DataUtils from '../utils/DataUtils';
import IconProvider from '../geog/IconProvider';
import GeoJsonProvider from '../geog/GeoJsonProvider';
import LayerProvider from '../geog/LayerProvider';
import FlowingLayer from '../common/FlowingLayer';
import SimpleFillLayer from '../common/SimpleFillLayer';
import SimpleMarkerLayer from '../common/SimpleMarkerLayer';
import PipelineErrorLayer from '../pipeline/PipelineErrorLayer';
import EquipmentLayer from '../equipment/EquipmentLayer';
import PipenetFlowingLayer from './PipenetFlowingLayer';

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

/**
 * 定义管网上下游分析提供类
 *
 * @alias PipenetUpdownstreamProvider
 *
 * @summary <用于加载管网上下游分析图层>
 */
export default class PipenetUpdownstreamProvider {
  /**
   * 构造函数
   * @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, 3.0);

    /**
     * 是否查询管网问题
     * @type {Boolean}
     */
    this._withError = DataUtils.default(options.error, false);
    /**
     * 是否查询结果
     * @type {Boolean}
     */
    this._withResult = DataUtils.default(options.result, false);
    /**
     * 是否查询设备
     * @type {Boolean}
     */
    this._withDevice = DataUtils.default(options.device, false);

    this._category = 'grade'; // 排水户等级
    this.sourceId = 0; // 起始点ID
    this.targetId = 0; // 终止点ID

    /* 要素集 */
    this._fc = GeoJsonProvider.getEmptyFC();       // 分析结果管线
    this._mergedFC = GeoJsonProvider.getEmptyFC(); // 合并的管线
    this._errorFC = GeoJsonProvider.getEmptyFC();  // 管网问题

    this._drainUnitFC = GeoJsonProvider.getEmptyFC();   // 排水单元
    this._drainEntityFC = GeoJsonProvider.getEmptyFC(); // 排水户

    this._plantPumpFC = GeoJsonProvider.getEmptyFC(); // 厂站

    this._deviceFC = GeoJsonProvider.getEmptyFC(); // 设备

    /* 图层 */
    this._flowingLayer = null; // 管网流向
    this._errorLayer = null;   // 管网问题

    this._drainUnitLayer = null;   // 排水单元
    this._drainEntityLayer = null; // 排水户

    this._deviceLayer = 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.targetId = 0;

    this._fc.features = [];
    this._mergedFC.features = [];
    this._errorFC.features = [];
    this._drainUnitFC.features = [];
    this._drainEntityFC.features = [];
    this._plantPumpFC.features = [];
    this._deviceFC.features = [];
    // 结果要素集
    let resultFC = GeoJsonProvider.getEmptyFC();

    const map = this._map;
    const category = layerType === 'pipeline' ? 'pipenet' : 'pipenet-up';
    // 获取管线网络查询url
    const queryUrl = LayerProvider.getBaseLayerQueryUrl(map, category, code);
    if (!queryUrl) {
      if (callback) { // 回调
        callback('updownstream', 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;
      this.targetId = fc.features[0].properties.target;
    }
    if (this.sourceId < 1 || this.targetId < 1) {
      if (callback) { // 回调
        callback('updownstream', resultFC);
      }
      return false;
    }

    // 查询下游管网流向
    await this._query('pipenet-downstream', this.sourceId);
    // 查询上游管线流向
    await this._query('pipenet-upstream', this.targetId);

    if (this._withError) {
      // 查询管网错误
      await this._query('pipenet-errordown', this.sourceId);
      await this._query('pipenet-errorup', this.targetId);
    }

    if (this._withResult) {
      // 查询排水单元
      await this._query('pipenet-drainunit', this.targetId);
      // 查询排水户
      await this._query('pipenet-drainentity', this.targetId);

      // 查询厂站
      await this._query('pipenet-plantpump', this.sourceId);
    }

    if (this._withDevice) {
      // 查询液位计
      await this._query('pipenet-devicedown', this.sourceId);
      await this._query('pipenet-deviceup', this.targetId);

      // 查询厂站
      await this._query('pipenet-plantpump', this.sourceId);
      await this._query('pipenet-plantpump', this.targetId);
    }

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

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

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

    if (this._withError) {
      // 管网问题
      this._errorLayer.setData(this._errorFC);

      // 合并管网问题
      if (this._errorFC.features.length > 0) {
        resultFC.features = resultFC.features.concat(this._errorFC.features);
      }
    }

    if (this._withResult) {
      // 获取唯一排水单元要素集合
      this._drainUnitFC.features = GeoJsonProvider.getUniqueFeatures(this._drainUnitFC.features, 'unit_name');
      // 设置排水单元数据
      this._drainUnitLayer.setData(this._drainUnitFC);
      // 合并排水单元
      if (this._drainUnitFC.features.length > 0) {
        resultFC.features = resultFC.features.concat(this._drainUnitFC.features);
      }

      // 获取唯一排水户要素集合
      this._drainEntityFC.features = GeoJsonProvider.getUniqueFeatures(this._drainEntityFC.features, 'drain_code');
      // 设置排水户数据
      this._drainEntityLayer.setData(this._drainEntityFC);
      // 合并排水户
      if (this._drainEntityFC.features.length > 0) {
        resultFC.features = resultFC.features.concat(this._drainEntityFC.features);
      }

      // 获取唯一厂站要素集合
      this._plantPumpFC.features = GeoJsonProvider.getUniqueFeatures(this._plantPumpFC.features, 'object_id');
      // 合并厂站
      if (this._plantPumpFC.features.length > 0) {
        resultFC.features = resultFC.features.concat(this._plantPumpFC.features);
      }
    }

    if (this._withDevice) {
      // 设置设备数据
      this._deviceLayer.setData(this._deviceFC);

      // 获取唯一设备要素集合
      this._deviceFC.features = GeoJsonProvider.getUniqueFeatures(this._deviceFC.features, 'device_id');
      // 合并设备
      if (this._deviceFC.features.length > 0) {
        resultFC.features = resultFC.features.concat(this._deviceFC.features);
      }

      // 获取唯一厂站要素集合
      this._plantPumpFC.features = GeoJsonProvider.getUniqueFeatures(this._plantPumpFC.features, 'object_id');
      // 合并厂站
      if (this._plantPumpFC.features.length > 0) {
        resultFC.features = resultFC.features.concat(this._plantPumpFC.features);
      }
    }

    // 更新管网总数、问题总数
    if (resultFC.features.length > 0) {
      resultFC.features[0].properties.pipe_num = this._fc.features.length;
      let pipeLen = 0;
      this._fc.features.forEach((fea) => {
        pipeLen += fea.properties.pipe_length || 0;
      });
      resultFC.features[0].properties.pipe_len = pipeLen;

      resultFC.features[0].properties.error_num = this._errorFC.features.length;
      let errorLen = 0;
      this._errorFC.features.forEach((fea) => {
        errorLen += fea.properties.pipe_length || 0;
      });
      resultFC.features[0].properties.error_len = errorLen;
    }

    // 回调
    if (callback) {
      callback('updownstream', resultFC);
    }
  }

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

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

    // 管网问题
    if (this._errorLayer) {
      this._errorLayer.removeLayer();
    }

    // 排水户点
    if (this._drainEntityLayer) {
      this._drainEntityLayer.removeLayer();
    }
    // 排水单元
    if (this._drainUnitLayer) {
      this._drainUnitLayer.removeLayer();
    }

    // 设备
    if (this._deviceLayer) {
      this._deviceLayer.removeLayer();
    }
  }

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

    // 管网问题
    if (this._errorLayer) {
      this._errorLayer.showLayer(isShow);
    }

    // 排水户点
    if (this._drainEntityLayer) {
      this._drainEntityLayer.showLayer(isShow);
    }
    // 排水单元
    if (this._drainUnitLayer) {
      this._drainUnitLayer.showLayer(isShow);
    }

    // 设备
    if (this._deviceLayer) {
      this._deviceLayer.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-updownstream'
    });

    // 管网问题图层
    if (this._withError) {
      this._errorLayer = new PipelineErrorLayer({
        map: map,
        minzoom: minZoom,
      });
    }

    if (this._withResult) {
      // 创建排水单元图层
      this._drainUnitLayer = new SimpleFillLayer({
        map: map,
        minzoom: minZoom,
        color: '#AFEEEE', // #FFC0CB
        opacity: 0.15,
        outline: true,
        lineColor: '#AFEEEE',
        lineWidth: 2.0,
        lineOpacity: 0.75,
        //dasharray: [2.5, 1.5],
        sourceId: 'pipenet_drainunit',
      });
      // 设置空数据
      this._drainUnitLayer.setData(GeoJsonProvider.getEmptyFC());

      // 创建排水户图层
      this._drainEntityLayer = new SimpleMarkerLayer({
        map: map,
        minzoom: minZoom,
        icon: IconProvider.getDrainerIconExpression(this._category, true),
        sourceId: 'pipenet_drainentity'
      });
    }

    if (this._withDevice) {
      // 创建设备图层
      this._deviceLayer = new EquipmentLayer({
        map: map,
        minzoom: minZoom,
        sourceId: 'pipenet_equipment'
      });
    }
  }

  /**
   * 查询管网分析结果
   * @param {String} type -分析类型
   * @param {NUmber} udId -上下游ID
   */
  async _query(type, udId) {
    const map = this._map;
    // 获取管网函数查询url
    const queryUrl = LayerProvider.getBaseLayerQueryUrl(map, type, udId);
    if (!queryUrl) return false;

    // 查询管网分析结果
    await getApi(queryUrl).then(res => {
      const fc = res.data;
      if (fc && fc.features && fc.features.length > 0) {
        // 更新上下游类型
        const udType = getUdsType(type);

        fc.features.forEach(feature => {
          feature.properties.uds_type = udType;
        });

        switch (type) {
          case 'pipenet-upstream':
          case 'pipenet-downstream': { // 上下游分析结果
            // 合并管线数据
            const mergedFeatures = pipenetMergeAnalystResult(fc.features);
            this._mergedFC.features = this._mergedFC.features.concat(mergedFeatures);

            // 合并管网流向
            this._fc.features = this._fc.features.concat(fc.features);
            break;
          }
          case 'pipenet-errorup':     // 问题管线
          case 'pipenet-errordown': {
            fc.features.forEach((fea) => {
              fea.properties.feature_type = 'error';
            });
            // 合并管网问题
            this._errorFC.features = this._errorFC.features.concat(fc.features);
            break;
          }
          case 'pipenet-deviceup':
          case 'pipenet-devicedown': { // 设备
            fc.features.forEach((fea) => {
              fea.properties.feature_type = 'device';
            });
            // 合并设备
            this._deviceFC.features = this._deviceFC.features.concat(fc.features);
            break;
          }
          case 'pipenet-drainunit': { // 排水单元
            fc.features.forEach((fea) => {
              fea.properties.feature_type = 'drainunit';
            });
            // 合并排水单元
            this._drainUnitFC.features = this._drainUnitFC.features.concat(fc.features);
            break;
          }
          case 'pipenet-drainentity': { // 排水户
            fc.features.forEach((fea) => {
              fea.properties.feature_type = 'drainentity';
            });
            // 合并排水户
            this._drainEntityFC.features = this._drainEntityFC.features.concat(fc.features);
            break;
          }
          case 'pipenet-plantpump': { // 厂站
            fc.features.forEach((fea) => {
              fea.properties.feature_type = fea.properties.object_type;
            });
            // 合并厂站
            this._plantPumpFC.features = this._plantPumpFC.features.concat(fc.features);
            break;
          }
          default:
            break;
        }
      }
    });

    function getUdsType(type) {
      switch (type) {
        case 'pipenet-upstream':
        case 'pipenet-errorup':
        case 'pipenet-deviceup':
          return 'up';
        case 'pipenet-downstream':
        case 'pipenet-errordown':
        case 'pipenet-devicedown':
          return 'down';
        default:
          return undefined;
      }
    }
  }
}
