import DataUtils from "../utils/DataUtils";
import IconProvider from "../geog/IconProvider";
import GeoJsonProvider from "../geog/GeoJsonProvider";
import MapProvider from "../geog/MapProvider";
import LayerProvider from "../geog/LayerProvider";

import { getApi } from '../../api/http';

/**
 * 定义排水户搜索提供类
 *
 * @alias DrainerSearchProvider
 * @constructor
 *
 * @param options -搜索选项
 */
function DrainerSearchProvider(options) {
	'use strict';

	/**
	 * 地图对象
	 * @type {Object}
	 */
	this._map = options.map;

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

	/**
	 * 排水户点数据源Id
	 * @type {String}
	 */
	this._sourceId = options.sourceId;

	// 搜索器数据源Id
	this._searchSourceId = this._sourceId + '-searcher';
	// 搜索器图层Id
	this._searchLayerId = this._searchSourceId;

	this._prefix = '';  // 搜索前缀
	this._targets = []; // 搜索目标要素集合

	// 事件
	this._layerEnterEvent = null;
	this._layerLeaveEvent = null;
	this._layerClickEvent = null; // 外部实现单击事件
	// 初始化鼠标事件
	this._initEvent();
}

/**
 * 加载图层
 * @param {String} category -类型
 * @param {String} prefix -搜索前缀
 */
DrainerSearchProvider.prototype.filterLayer = function (category, prefix) {
	if (!this.hasLayer()) {
		this.loadLayer(category); // 加载图层
	}

	if (!prefix || prefix.length === 0) {
		this.showLayer(false);
	}

	let source = this._map.getSource(this._sourceId);
	if (!source) {
		return catchError();
	}

	// 规范化
	prefix = normalize(prefix);

	let that = this;
	let data = null;
	let map = this._map;

	// 返回空数组
  async function catchError() {
    return [];
  }

	/**
	 * 规范化
	 */
	function normalize(str) {
		return str.trim();
	}

	/**
	 * 是否需要查询数据源
	 *
	 * @returns {Boolean}
	 */
	function needQuerySource() {
		if (that._prefix.length === 0 ||
			that._targets.length === 0) {
			return true;
		}

		if (prefix.indexOf(that._prefix) < 0) {
			return true;
		}

		return false;
	}

	/**
	 * 查询排水户
	 */
	async function searchDrainers() {
		if (needQuerySource()) {
			let url = source._data + '&viewparams=keywords:' + prefix;
			// 查询排水户
			let result = await getApi(url);
			if (result.data) {
				data = result.data;
				// 更新数据源
				map.getSource(that._searchSourceId).setData(data);
			}

			that._prefix = prefix;
			that._targets = [];
			// 查询数据源要素集合
			let features = that._map.querySourceFeatures({
				layers: [that._searchSourceId]
			});
			if (features.length === 0) {
				features = data.features;
			}

			if (features && features.length > 0) {
				that._targets = GeoJsonProvider.getUniqueFeatures(features, 'drain_name');
			}
		}

		// Filter visible features that don't match the input value.
		let filtered = that._targets.filter((feature) => {
			var name = normalize(feature.properties.drain_name);
			return name.indexOf(prefix) > -1;
		});

		if (filtered.length > 0) {
			// Set the filter to populate features into the layer.
			map.setFilter(that._searchLayerId,
				['match',
					['get', 'drain_name'],
					filtered.map((feature) => {
						return feature.properties.drain_name
					}),
					true,
					false
				]
			);

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

		return filtered;
	}

	return searchDrainers();
}

/**
 * 加载图层
 * @param {String} category -类型
 */
DrainerSearchProvider.prototype.loadLayer = function (category) {
	// 移除图层
	this.removeLayer();

	const source = this._map.getSource(this._sourceId);
	if (!source) return;

	const map = this._map;
	// 添加数据源
	map.addSource(this._searchSourceId, {
		type: "geojson",
		data: {
			type: "FeatureCollection",
			features: []
		}
	});

	// 获取图标表达式
	let iconExpression = IconProvider.getDrainerIconExpression(category);
	// 添加图层
	map.addLayer({
		type: "symbol",
		id: this._searchLayerId,
		source: this._searchSourceId,
		minzoom: this._minzoom,
		layout: {
			"symbol-placement": "point",
			"symbol-avoid-edges": true,
			"icon-image": iconExpression,
			"icon-allow-overlap": true,
			"icon-ignore-placement": true,
			visibility: "visible"
		},
		paint: {
			"icon-opacity": 0.8
		}
	});

	// 绑定事件
	map.on('mouseenter', this._searchLayerId, this._layerEnterEvent);
	map.on('mouseleave', this._searchLayerId, this._layerLeaveEvent);
}

/**
 * 移除图层
 */
DrainerSearchProvider.prototype.removeLayer = function () {
	const map = this._map;

	// 解除事件绑定
	if (this.hasLayer()) {
		LayerProvider.offEvent(map, this._searchLayerId, 'mouseenter', this._layerEnterEvent);
    LayerProvider.offEvent(map, this._searchLayerId, 'mouseleave', this._layerLeaveEvent);
    if (this._layerClickEvent) {
      LayerProvider.offEvent(map, this._searchLayerId, 'click', this._layerClickEvent);
    }
	}

	// 移除图层
	LayerProvider.removeLayer(map, this._searchLayerId);
	// 移除数据源
	LayerProvider.removeSource(map, this._searchSourceId);
}

/**
 * 显示/隐藏图层
 * @param {Boolean} isShow -是否显示
 */
DrainerSearchProvider.prototype.showLayer = function (isShow = true) {
	LayerProvider.showLayer(this._map, this._searchLayerId, isShow);
}

/**
 * 图层是否已加载
 * @returns {Boolean}
 */
DrainerSearchProvider.prototype.hasLayer = function () {
	return LayerProvider.hasLayer(this._map, this._searchLayerId);
}

/**
 * 初始化默认事件
 */
DrainerSearchProvider.prototype._initEvent = function () {
	const map = this._map;
  // 鼠标事件
  function onMouseEnter() {
		MapProvider.setCursor(map, 'pointer');
  }
  function onMouseLeave() {
		MapProvider.setCursor(map);
  }

  this._layerEnterEvent = onMouseEnter;
  this._layerLeaveEvent = onMouseLeave;
}

export default DrainerSearchProvider;
