
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 = [];
		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;
				categories.push(item[opts.datekey || 'dateUnit']);
				for(var serie of series){
					serie.data.push(values[serie.key] * 1);
				};
			};
		};
		return {series:series, categories:categories}
	};

	
	/**
	  * 递归继承, 新对象在先, 原对象在后, 节省运行效率
	  * @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){
		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:'dash',
					};
					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;
			};

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

	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);
				};
			/* 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){
				var value = alarms[item.color] * 1;
				if(value){
					setAlarmSerie(value, item.name, item.color);
					direction && setAlarmSerie(0-value, item.name, item.color);
				};
			};


			// add
			/* for(var key in alarms){
				var val = alarms[key]*1;
				console.log('line ________________ ', line);
				setAlarmSerie(val, line.name, key);
				direction && setAlarmSerie(0-val, line.name, key);
			}; */
		};
		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: {
					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, {datekey:'date'});
				categories = chartData.categories;
				series = chartData.series;
			};

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

			

			/* 渐变色
			Highcharts.getOptions().colors = Highcharts.map(Highcharts.getOptions().colors, function(color) {
				let startColor = ''
				let endColor = ''
				// 第二次的时候color变为了对象，所以取色值要从对象里取
				if (color instanceof Object) {
				  startColor = color.stops[0][1]
				  endColor = color.stops[1][1]
				} else {
				  startColor = color
				  endColor = Highcharts.Color(color)
					.brighten(0.15)
					.get('rgb')
				}
				return {
				  radialGradient: { cx: 0.5, cy: 0.3, r: 0.7 },
				  stops: [[0, startColor], [1, endColor]]
				}
			}); */

			var option = {
				chart: {
					type: data.chartType,
					backgroundColor:'transparent',
					//marginTop:30,
					marginBottom:30,
					marginLeft:30,
				},
				title: {
					text: ''
				},
				subtitle: {
					text: ''
				},
				xAxis: {
					type: 'category',
					labels: {
						rotation: -45,  // 设置轴标签旋转角度
						style:{
							color:'#fff'
						},
						y:10,
					},
					categories: categories[0] && categories,
					lineWidth:0,
					//lineColor:'#ff0000',
					gridLineColor:'#aaa',
				},
				yAxis: {
					title: {
						text: ''
					},
					labels:{
						style:{
							color:'#fff'
						},
						x:-6,
					},
					gridLineColor:'#aaa',
					max: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)+' 毫米';
					}
				}, */
				series: series
			};

			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 option = {
				chart: {
					//type: '',
					backgroundColor:'transparent',
					//marginTop:30,
					//marginBottom:30,
					//marginLeft:30,
					zoomType: 'x',		// xy
				},
				title: {
					text: ''
				},
				subtitle: {
					text: ''
				},
				tooltip:{
					enabled:false,
					borderWidth:10,
				},
				xAxis: {
					type: 'category',
					categories: categories[0] && categories,
					lineWidth:0,
					//lineColor:'#ff0000',
					gridLineColor:'#aaa',
				},
				yAxis: {
					title: {
						text: ''
					},
					labels:{
						x:-6,
					},
					gridLineColor:'#aaa',
					max:null,
				},
				plotOptions: {
					column: {
						borderWidth: 0,
						//y:50,
						//itemMarginTop:50,
					},
					bar:{
						borderWidth: 0,
					},
				},
				tooltip: {
					// head + 每个 point + footer 拼接成完整的 table
					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:.1f} '+unit+'</b></td></tr>',
					footerFormat: '</table>',
					shared: true,
					useHTML: true
				},
				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: true
				},
				series: series
			};

			Highcharts.setOptions({
				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();
