
import Highcharts from 'highcharts';
import HTreemap from 'highcharts/modules/treemap.js';
import Highcharts3D from 'highcharts/highcharts-3d.js';
//import oldie from 'highcharts/oldie.js';
//import cylinder from 'highcharts/cylinder.js';
HTreemap(Highcharts);			// treemap 类型
Highcharts3D(Highcharts);		// 3D 类型

var Highchart = function () {

	/**
		* 图表数据格式化
		* @param: {Array} list
		* @param: {Object} opts [standOut(突出最大值)]
		*	@example1: qf.UI.showFloatMenu({top:y,left:x, eventOutClose:}, html);
		* @return: 
		* @author: Kimber
		* @updatetime: 2021/12/25
		* @createtime: 2021/12/25
		*/
	var formatChartData = function (list, opts) {
		var sdata = [], sum = 0, maxVal = 0, mark = 0;
		var len = list.length;
		for (var i = 0; i < len; i++) {
			var item = list[i];
			var value = item[opts.value] * 1;
			value > maxVal && (maxVal = value, mark = i);
			sdata.push({ name: item[opts.name], y: value, 'color': item.color || void 0 });
			sum += value;
		};
		if (opts.standOut) {
			sdata[mark].sliced = true;
			sdata[mark].selected = true;
		};
		return { seriesData: sdata, sum: sum };
	};


	/**
		* series数据格式化
		* @param: {Array} list
		* @param: {Object} opts [standOut(突出最大值)]
		*	@example1: qf.UI.showFloatMenu({top:y,left:x, eventOutClose:}, html);
		* @return: 
		* @author: Kimber
		* @updatetime: 2022/12/28
		* @createtime: 2022/12/28
		*/
	var seriesDataFormat = function (data, opts) {
		var names = data.names || [], list = data.list || data.lists, series = [], categories = [],
			maxVal = 0;
		if (names[0] && list) {
			var colors = ['#7CB5EC', '#90ED7D', '#F7A35C', '#8085E9', '#F15C80', '#E4D354', '#2B908F', '#F45B5B', '#91E8E1', '#0769CB', '#00ABBD', '#ffd886', "#9F2E61", "#4D670C"];

			var len = names.length;
			for (var i = 0; i < len; i++) {
				var item = names[i];
				var serie = { name: item.name, data: [], key: item.key, type: data.chartType, color: colors[i] };
				opts && serie.type && (serie.type = opts.type);
				series.push(serie);
			};

			for (var item of list) {
				var values = item.values;
				//var datetime = item[opts.datekey || 'dateUnit'];
				//var time = datetime.indexOf(' ') > 0 ? datetime.split(' ')[1] : datetime;
				var timestamp = item['date'];

				//categories.push(timestamp);
				for (var serie of series) {
					var value = values[serie.key] * 1;
					Math.abs(value) > maxVal && (maxVal = Math.abs(value));
					serie.data.push([timestamp, value]);
				};
			};
		};
		return { series: series, categories: categories, maxVal: maxVal }
	};


	/**
		* 递归继承, 新对象在先, 原对象在后, 节省运行效率
		* @param: {Object} inherit	// 继承者
		* @param: {Object} give		// 传承者
		* @param: {Function} call		// 方法回调, 于在在特殊情况自定义
		*	@example1: var options = reversExtends(option, opts);
		* @return: 
		* @author: Kimber
		* @updatetime: 2022/1/12
		* @createtime: 2022/1/12
		*/
	var reversExtends = function (inherit, give, fn) {
		return (function run(main, assist) {
			var keys = Object.keys(assist), i = 0;
			return (function loop() {
				var key = keys[i]; i++;
				if (key) {
					fn && fn(key, main, assist);
					return typeof main[key] === 'object' ? run(main[key], assist[key]) : (main[key] = assist[key]), loop();
				} else {
					return inherit;
				};
			})();
		})(inherit, give);
	};

	/**
		* 根据报警级别识别近两条报警线
		* @param: {Number} level
		* @param: {Object} value
		*	@example1: series = discernValidAlarmValue(data.alarm, data.lists, series);
		* @return: 
		* @author: Kimber
		* @updatetime: 2022/4/18(周一)
		* @createtime: 2022/4/18(周一)
		*/
	var discernValidAlarmValue = function (alarms, list, series, direction, opts) {
		var xLength = (list || []).length, maxAlarm = 0, opts = opts || {};
		if (alarms && xLength) {
			var value = alarms.value;

			// discern
			var levelDist = [
				{ color: 'red', name: '红色报警线' },
				{ color: 'orange', name: '橙色报警线' },
				{ color: 'yellow', name: '黄色报警线' },
				{ color: 'blue', name: '蓝色报警线' }],
				alarmLine = {}, setAlarmSerie = function (value, name, color) {
					// 修改蓝色色值
					(color === 'blue') && (color = '#3BAFFB');
					var sx = list[0].date, ex = list[xLength - 1].date;
					var serie = {
						name: name, type: 'spline', data: [{ x: sx, y: value }, { x: ex, y: value }],
						color: color,
						enableMouseTracking: false,
						legend: false,
						showInLegend: false,
						dashStyle: 'ShortDot',
						lineWidth: opts.lineWidth || 1,
						states: {
							inactive: {
								opacity: opts.opacity
							},
						},
						dataLabels: {
							enabled: opts.valEnabled || false,		// 数据值, 2022/11/11(周五) 因多条报警线暂时关闭
							//backgroundColor:'red',
							verticalAlign: 'middle',
							padding: 0,
							defer: false,
							allowOverlap: true,
							color: color,
							style: {
								textOutline: 'none',
							},
						},
						tooltip: {

							//footerFormat:'',
							//pointFormat:'',
							headerFormat: '',
							//nullFormat:'',
						},
						marker: {
							enabled: false
						},
						zIndex: -10,
					};
					series.push(serie);
				};

			/* 智能报警线
			var level = (~~alarms.alarmLevel || levelDist.length+1) - 1;
			var nearLevel = level ? level - 1 : level;
			var alarm = levelDist[level];
			var nearAlarm = levelDist[nearLevel];
			nearAlarm.value = value[nearAlarm.color];
			alarmLine[nearAlarm.color] = nearAlarm;
			if(alarm){
				alarm.value = value[alarm.color];
				alarmLine[alarm.color] = alarm;
			}; */

			// 多条报警线
			for (var item of levelDist) {
				item.value = value[item.color];
				alarmLine[item.color] = item;
			};

			// add
			for (var key in alarmLine) {
				var line = alarmLine[key];
				line.value > maxAlarm && (maxAlarm = line.value);
				setAlarmSerie(line.value, line.name, line.color);
				direction && setAlarmSerie(0 - line.value, line.name, line.color);
			};
		};
		return { series, maxAlarm };
	};

	var addAlarmLine = function (alarms, list, series, direction) {
		var xLength = (list || []).length;
		if (alarms && xLength) {
			var value = alarms.value;
			// discern
			var levelDist = [
				{ color: 'red', name: '红色报警线' },
				{ color: 'orange', name: '橙色报警线' },
				{ color: 'yellow', name: '黄色报警线' },
				{ color: 'blue', name: '蓝色报警线' }],
				alarmLine = {}, setAlarmSerie = function (value, name, color) {
					var serie = {
						name: name, type: 'spline', data: [{ x: 0, y: value }, { x: xLength, y: value }], color: color,
						//enableMouseTracking:false,
						legend: false,
						showInLegend: false,
						dashStyle: 'ShortDot',
						states: {
							inactive: {
								opacity: 1
							},
						},
					};
					series.push(serie);
				};

			for (var item of levelDist) {
				var value = alarms[item.color] * 1;
				if (value) {
					setAlarmSerie(value, item.name, item.color);
					direction && setAlarmSerie(0 - value, item.name, item.color);
				};
			};
		};
		return series;
	};

	var template = {
		pie: function (el, data, opts) {
			var chartData = formatChartData(data, opts);
			var seriesData = chartData.seriesData;
			return new Highcharts.chart(el, {
				chart: {
					backgroundColor: 'transparent',
					//spacing:[0, 0 , 0, 0]
				},
				title: {
					floating: true,
					text: '总数<br/>' + chartData.sum,
					verticalAlign: 'middle',
					y: 22,
					floating: true,
					style: {
						color: '#00f6ff',
					}
				},
				tooltip: {
					shared: false, // 添加此属性关闭共享提示框
					pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
				},
				plotOptions: {
					pie: {
						allowPointSelect: true,
						borderWidth: 0,
						minSize: 130,
						//size:200,
						cursor: 'pointer',
						dataLabels: {
							enabled: true,
							distance: 10,
							format: '<b>{point.name}</b>: {point.percentage:.1f} %',
							style: {
								color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
							}
						},
					}
				},
				credits: {
					enabled: false
				},
				series: [{
					type: 'pie',
					innerSize: '70%',
					name: '设备数量',
					data: seriesData
				}]
			}, function (c) { // 图表初始化完毕后的会掉函数
				/* // 环形图圆心
				var centerY = c.series[0].center[1],
					titleHeight = parseInt(c.title.styles.fontSize);

				// 动态设置标题位置
				c.setTitle({
					y:centerY
				}); */
			});
		},

		/**
			* 浮动菜单容器
			* @param: {Dom} el 
			* @param: {Object} data
			* @param: {Object} opts	{chartConfig:{}, callback:Function}
			*	@example1:
			* @return: 
			* @author: Kimber
			* @updatetime: 2022/1/11
			* @createtime: 2022/1/11
			*/
		high: function (el, data, opts) {
			var list = data.list;
			data.chartType = data.range === 'month' ? 'line' : 'column';
			var chartConfig = opts.chartConfig || {};

			var chartData, categories = [], series = [], maxVal = null;
			if (opts.isSeriesData) {

			} else {
				chartData = seriesDataFormat(data, {});
				categories = chartData.categories;
				series = chartData.series;
			};

			// add alarm line
			var alarmData = discernValidAlarmValue(data.alarm, data.lists, series, opts.warningLine);
			//series = addAlarmLine(data.alarm, data.lists, series, opts.warningLine);

			// 识别最大值
			var maxVal = chartData && chartData.maxVal > alarmData.maxAlarm ? chartData.maxVal : alarmData.maxAlarm;
			var option = {
				chart: {
					type: data.chartType,
					backgroundColor: 'transparent',
					//marginTop:30,
					marginBottom: 22,
					marginLeft: 30,
				},
				title: {
					text: ''
				},
				subtitle: {
					text: ''
				},
				xAxis: {
					type: 'datetime' || 'category',
					labels: {
						rotation: 0,  // 设置轴标签旋转角度
						style: {
							color: '#fff'
						},
						y: 15,
					},
					categories: categories[0] && categories,
					lineWidth: 0,
					//lineColor:'#ff0000',
					gridLineColor: '#aaa',
					tickLength: 0,		// 刻度线

					dateTimeLabelFormats: {
						millisecond: '%H:%M:%S.%L',
						second: '%H:%M:%S',
						minute: '%H:%M',
						hour: '%H:%M',
						day: '%m-%d',
						week: '%m-%d',
						month: '%Y-%m',
						year: '%Y'
					}
				},
				yAxis: {
					title: {
						text: ''
					},
					labels: {
						style: {
							color: '#fff'
						},
						x: -6,
					},
					gridLineColor: '#0F5680',
					//minorGridLineWidth: 5,
					//gridLineWidth: 5,
					max: opts.maxValDev ? maxVal + maxVal * opts.maxValDev : null,
				},
				plotOptions: {
					column: {
						borderWidth: 0,
						//y:50,
						//itemMarginTop:50,
					},
					bar: {
						borderWidth: 0,
					},
				},
				legend: {
					enabled: series.length > 1 ? true : false,
					// 图例定位
					layout: 'horizontal',				// 水平布局:“horizontal”, 垂直布局:“vertical”
					floating: false,					// 图列是否浮动
					align: 'right',

					// 图例容器
					//width:'100%',		// number	|| String
					padding: 2,			// 内边距
					margin: 2,
					borderRadius: 5,
					//borderWidth:1,
					verticalAlign: 'top',

					// 图例项
					//itemWidth:120,		// 宽度
					itemDistance: 10,	// 间距	20
					y: -10,
					itemMarginTop: 2,
					itemStyle: { color: '#fff', },
					itemHoverStyle: { color: '#fff', },
				},
				credits: {
					enabled: false
				},
				tooltip: {
					/* formatter: function (e) {
						return this.series.name + "："+ this.key +'<br/>'+ this.y.toFixed(3)+' ' + data.unit;
					}, */
					shared: false,
					pointFormat: '{series.name}：{point.y} ' + data.unit,
					dateTimeLabelFormats: {
						millisecond: '%H:%M:%S.%L',
						second: '%H:%M:%S',
						minute: '%m-%d %H:%M',
						hour: '%m-%d %H:%M',
						day: '%m-%d %H:%M',
						week: '%m-%d %H:%M',
						month: '%Y-%m',
						year: '%Y'
					}
				},
				series: series
			};

			Highcharts.setOptions({
				global: {
					useUTC: false
				},
			});

			var options;
			if (opts.isSeriesData) {
				options = reversExtends(option, chartConfig, opts.callback);
				if (opts.type === "t_10") {
					delete options.legend;
					delete options.xAxis;
					delete options.yAxis;
				};
			} else {
				options = reversExtends(option, chartConfig, opts.callback);
			};

			return new Highcharts.chart(el, options);
		},

		rich: function (el, data, opts) {
			var list = data.list;
			var chartConfig = opts.chartConfig || {};
			var chartData, categories = [], series = [], maxVal = null, unit = data.danwei;
			if (opts.isSeriesData) {

			} else {
				chartData = seriesDataFormat(data, { datekey: 'date' });
				categories = chartData.categories;
				series = chartData.series;
			};

			var warningLine = this.form.config.warningLine;

			// add alarm line
			var option = {
				valEnabled: true,
				opacity: 1,
				lineWidth: 3,
			};
			var alarmData = discernValidAlarmValue(data.alarm, data.lists, series, warningLine, option);

			var option = {
				chart: {
					//type: '',
					backgroundColor: 'transparent',
					//marginTop:30,
					//marginBottom:30,
					//marginLeft:30,
					zoomType: 'x',		// xy
				},
				title: {
					text: ''
				},
				subtitle: {
					text: ''
				},
				tooltip: {
					enabled: false,
					shared: false, // 添加此属性关闭共享提示框
					borderWidth: 10,
				},
				xAxis: {
					type: 'datetime',
					categories: categories[0] && categories,
					lineWidth: 0,
					//lineColor:'#ff0000',
					gridLineColor: '#aaa',

					dateTimeLabelFormats: {
						millisecond: '%H:%M:%S.%L',
						second: '%H:%M:%S',
						minute: '%H:%M',
						hour: '%H:%M',
						day: '%m-%d',
						week: '%m-%d',
						month: '%Y-%m',
						year: '%Y'
					}
				},
				yAxis: {
					title: {
						text: ''
					},
					labels: {
						x: -6,
					},
					gridLineColor: '#aaa',
					max: null,
				},
				plotOptions: {
					column: {
						borderWidth: 0,
						//y:50,
						//itemMarginTop:50,
					},
					bar: {
						borderWidth: 0,
					},
				},
				tooltip: {
					// {point.y:.4f}	// 保留4位小数
					//headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
					pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}:</td>' +
						'<td style="padding:0"><b>{point.y}' + unit + '</b> </td></tr>',
					footerFormat: '</table>',
					shared: false,
					useHTML: true,
					dateTimeLabelFormats: {
						millisecond: '%H:%M:%S.%L',
						second: '%H:%M:%S',
						minute: '%H:%M',
						hour: '%H:%M',
						day: '%m-%d %H时',
						week: '%m-%d',
						month: '%Y-%m',
						year: '%Y'
					}
				},
				legend: {
					enabled: series.length > 1 ? true : false,
					// 图例定位
					layout: 'horizontal',				// 水平布局:“horizontal”, 垂直布局:“vertical”
					floating: false,					// 图列是否浮动
					align: 'right',

					// 图例容器
					//width:'100%',		// number	|| String
					padding: 2,			// 内边距
					margin: 2,
					borderRadius: 5,
					//borderWidth:1,
					verticalAlign: 'top',

					// 图例项
					//itemWidth:120,		// 宽度
					itemDistance: 10,	// 间距	20
					y: -10,
					itemMarginTop: 2,
					itemStyle: {},
					itemHoverStyle: {},
				},
				credits: {
					enabled: false
				},
				series: series
			};

			Highcharts.setOptions({
				global: {
					useUTC: false
				},
				lang: {
					resetZoom: '重置缩放比例',
				},
			});

			var options;
			if (opts.isSeriesData) {
				options = reversExtends(option, chartConfig, opts.callback);
				if (opts.type === "t_10") {
					delete options.legend;
					delete options.xAxis;
					delete options.yAxis;
				};
			} else {
				options = reversExtends(option, chartConfig, opts.callback);
			};
			return new Highcharts.chart(el, options);
		},
	};

	var getRandomColor = function (random) {
		if (random === true) {
			return 'rgb(' + [Math.round(Math.random() * 160), Math.round(Math.random() * 160), Math.round(Math.random() * 160)].join(',') + ')';
		} else {
			var colors = ['#7CB5EC', '#434348', '#90ED7D', '#F7A35C', '#8085E9', '#F15C80', '#E4D354', '#2B908F', '#F45B5B', '#91E8E1', '#0769CB', '#00ABBD', '#ffd886', "#9F2E61", "#4D670C"];
			if (typeof random === 'number') {
				return colors[~~random];
			} else {
				return colors[~~(Math.random() * colors.length)];
			};
		};
	};

	return {
		template: template, getRandomColor: getRandomColor
	}
};

export var Highchart = Highchart();
