package data

import (
	"encoding/json"
	"errors"
	"eta/eta_api/models/data_manage"
	"eta/eta_api/services/google"
	"eta/eta_api/utils"
	"fmt"
	"sort"
	"strconv"
	"strings"
	"time"
)

func HandleExtraConfig(chartInfoId int, chartType int, extraConfigStr string) (newExtraConfigStr string, newAllExtraConfigStr string, err error, errMsg string) {
	newExtraConfigStr = extraConfigStr
	switch chartType {
	case 10: // 截面散点图
		var tmpExtraConfig data_manage.SectionScatterReq
		if extraConfigStr == `` {
			errMsg = "截面散点图未配置"
			err = errors.New(errMsg)
			return
		}
		err = json.Unmarshal([]byte(extraConfigStr), &tmpExtraConfig)
		if err != nil {
			errMsg = "截面散点配置异常"
			err = errors.New(errMsg)
			return
		}

		newExtraConfigStr, err, errMsg = handleSectionScatterChartData(tmpExtraConfig)
	case utils.CHART_TYPE_SECTION_COMBINE:
		//整理组合图的配置信息,将部分信息存入其他表
		// 预览和详情都走这个接口
		var sectionExtraConfig data_manage.ChartSectionAllExtraConf
		if extraConfigStr == `` {
			errMsg = "截面组合图未配置"
			err = errors.New(errMsg)
			return
		}
		err = json.Unmarshal([]byte(extraConfigStr), &sectionExtraConfig)
		if err != nil {
			errMsg = "截面组合图配置异常"
			err = errors.New(errMsg)
			return
		}
		newAllExtraConfig, e, msg := handleChartSectionCombineData(chartInfoId, sectionExtraConfig)
		if e != nil {
			err = e
			errMsg = msg
			return
		}
		newAllExtraConfigByte, e := json.Marshal(newAllExtraConfig)
		if e != nil {
			err = e
			return
		}
		newAllExtraConfigStr = string(newAllExtraConfigByte)

		newExtraConfig := &data_manage.ChartSectionExtraConf{
			DateConfList:        newAllExtraConfig.DateConfList,
			IsHeap:              newAllExtraConfig.IsHeap,
			XDataList:           newAllExtraConfig.XDataList,
			UnitList:            newAllExtraConfig.UnitList,
			BaseChartSeriesName: newAllExtraConfig.BaseChartSeriesName,
			SortType:            newAllExtraConfig.SortType,
		}
		extraConfigByte, e := json.Marshal(newExtraConfig)
		if e != nil {
			err = e
			return
		}
		newExtraConfigStr = string(extraConfigByte)
	}
	return
}

// handleSectionScatterChartData 截面散点图的数据处理
func handleSectionScatterChartData(extraConfig data_manage.SectionScatterReq) (extraConfigStr string, err error, errMsg string) {
	translateNameList := make([]string, 0)
	translateNameMap := make(map[string]bool, 0)

	if extraConfig.XNameEn == `` {
		if _, ok := translateNameMap[extraConfig.XName]; !ok {
			translateNameMap[extraConfig.XName] = true
			tmpName := strings.TrimSuffix(extraConfig.XName, " ")
			tmpName = strings.TrimPrefix(tmpName, " ")
			translateNameList = append(translateNameList, tmpName)
		}
	}
	if extraConfig.XUnitNameEn == `` {
		if _, ok := translateNameMap[extraConfig.XUnitName]; !ok {
			translateNameMap[extraConfig.XUnitName] = true
			tmpName := strings.TrimSuffix(extraConfig.XUnitName, " ")
			tmpName = strings.TrimPrefix(tmpName, " ")
			translateNameList = append(translateNameList, tmpName)
		}
	}
	if extraConfig.YNameEn == `` {
		if _, ok := translateNameMap[extraConfig.YName]; !ok {
			translateNameMap[extraConfig.YName] = true
			tmpName := strings.TrimSuffix(extraConfig.YName, " ")
			tmpName = strings.TrimPrefix(tmpName, " ")
			translateNameList = append(translateNameList, tmpName)
		}
	}
	if extraConfig.YUnitNameEn == `` {
		if _, ok := translateNameMap[extraConfig.YUnitName]; !ok {
			translateNameMap[extraConfig.YUnitName] = true
			tmpName := strings.TrimSuffix(extraConfig.YUnitName, " ")
			tmpName = strings.TrimPrefix(tmpName, " ")
			translateNameList = append(translateNameList, tmpName)
		}
	}
	for _, v := range extraConfig.SeriesList {
		if v.NameEn == `` {
			if _, ok := translateNameMap[v.Name]; !ok {
				translateNameMap[v.Name] = true
				tmpName := strings.TrimSuffix(v.Name, " ")
				tmpName = strings.TrimPrefix(tmpName, " ")
				translateNameList = append(translateNameList, tmpName)
			}
		}

		for _, edbInfo := range v.EdbInfoList {
			if edbInfo.NameEn == `` {
				if _, ok := translateNameMap[edbInfo.Name]; !ok {
					translateNameMap[edbInfo.Name] = true
					tmpName := strings.TrimSuffix(edbInfo.Name, " ")
					tmpName = strings.TrimPrefix(tmpName, " ")
					translateNameList = append(translateNameList, tmpName)
				}
			}
		}
	}

	// 获取英文名称map
	enNameMap, _, _ := GetEnNameMapByCnNameList(translateNameList)

	for k, seriesItem := range extraConfig.SeriesList {
		if len(seriesItem.EdbInfoList) <= 0 {
			errMsg = "指标不能为空"
			err = errors.New(errMsg)
			return
		}
		for edbIndex, edbConf := range seriesItem.EdbInfoList {
			if edbConf.NameEn == `` { //标签英文名称
				if tmpNameEn, ok := enNameMap[edbConf.Name]; ok {
					edbConf.NameEn = tmpNameEn
				}
			}
			seriesItem.EdbInfoList[edbIndex] = edbConf
		}

		if seriesItem.NameEn == `` { //系列英文名称
			if tmpNameEn, ok := enNameMap[seriesItem.Name]; ok {
				seriesItem.NameEn = tmpNameEn
			}
		}
		extraConfig.SeriesList[k] = seriesItem
	}

	if extraConfig.XNameEn == `` {
		if tmpNameEn, ok := enNameMap[extraConfig.XName]; ok {
			extraConfig.XNameEn = tmpNameEn
		}
	}
	if extraConfig.XUnitNameEn == `` {
		if tmpNameEn, ok := enNameMap[extraConfig.XUnitName]; ok {
			extraConfig.XUnitNameEn = tmpNameEn
		}
	}
	if extraConfig.YNameEn == `` {
		if tmpNameEn, ok := enNameMap[extraConfig.YName]; ok {
			extraConfig.YNameEn = tmpNameEn
		}
	}
	if extraConfig.YUnitNameEn == `` {
		if tmpNameEn, ok := enNameMap[extraConfig.YUnitName]; ok {
			extraConfig.YUnitNameEn = tmpNameEn
		}
	}

	extraConfigByte, err := json.Marshal(extraConfig)
	if err != nil {
		return
	}

	extraConfigStr = string(extraConfigByte)
	return
}

// GetEnNameMapByCnNameList 根据中文名称列表获取英文名称map
func GetEnNameMapByCnNameList(cnNameList []string) (contentEnMap map[string]string, err error, errMsg string) {
	// 返回参初始化
	contentEnMap = make(map[string]string)

	// 英文临时赋值变量
	tmpContentEnMapAll := make(map[string]string)
	count := 0
	contentMap := make(map[string]string, 0)
	for k, v := range cnNameList {
		//如果单条翻译的字符数超过1000,则直接翻译,否则批量翻译
		if count >= 50 { //待翻译的条数不能超过50; 单条翻译字符数不能超过1000字符
			tmpContentEnMap, tmpErr, tmpErrMsg := google.BatchTranslateHandlerByGoogle(contentMap)
			if tmpErr != nil {
				err = tmpErr
				errMsg = tmpErrMsg
				return
			}
			for tmpK, contentEn := range tmpContentEnMap {
				tmpContentEnMapAll[tmpK] = contentEn
			}
			contentMap = make(map[string]string, 0)
			count = 0
		}
		contentMap[strconv.Itoa(k)] = v
		count += 1
	}
	//剩余不满50条的content
	if count > 0 {
		tmpContentEnMap, tmpErr, tmpErrMsg := google.BatchTranslateHandlerByGoogle(contentMap)
		if tmpErr != nil {
			err = tmpErr
			errMsg = tmpErrMsg
			return
		}
		for tmpK, contentEn := range tmpContentEnMap {
			tmpContentEnMapAll[tmpK] = contentEn
		}
	}

	// 重新组装拼接返回
	lenCnNameList := len(cnNameList)
	for k, v := range tmpContentEnMapAll {
		tmpIndex, _ := strconv.Atoi(k)
		if tmpIndex < lenCnNameList {
			contentEnMap[cnNameList[tmpIndex]] = v
		}
	}
	return
}

// handleSectionScatterChartData 截面组合图的英文文案处理
func handleChartSectionCombineData(chartInfoId int, extraConfig data_manage.ChartSectionAllExtraConf) (newExtraConfig data_manage.ChartSectionAllExtraConf, err error, errMsg string) {
	dateConfListMapSave := make(map[string]bool)
	for k, v := range extraConfig.DateConfList {
		if v.DateConfNameEn == "" {
			extraConfig.DateConfList[k].DateConfNameEn = v.DateConfName
		}
	}

	if extraConfig.UnitList.LeftNameEn == "" {
		extraConfig.UnitList.LeftNameEn = extraConfig.UnitList.LeftName
	}
	if extraConfig.UnitList.RightNameEn == "" {
		extraConfig.UnitList.RightNameEn = extraConfig.UnitList.RightName
	}
	if extraConfig.UnitList.RightTwoNameEn == "" {
		extraConfig.UnitList.RightTwoNameEn = extraConfig.UnitList.RightTwoName
	}

	for k, v := range extraConfig.XDataList {
		if v.NameEn == "" {
			extraConfig.XDataList[k].NameEn = v.Name
		}
	}
	for k, v := range extraConfig.SeriesList {
		if v.SeriesNameEn == `` {
			extraConfig.SeriesList[k].SeriesNameEn = v.SeriesName
		}
		for _, info := range v.EdbInfoList {
			if info.DateConfType == 1 && info.DateConfName != "" {
				dateConfListMapSave[info.DateConfName] = true
			}
		}
	}

	if chartInfoId > 0 {
		// 查询表里的系列信息
		chartSectionCombineEdbList, e := data_manage.GetChartSeriesEdbByChartInfoId(chartInfoId)
		if e != nil {
			err = e
			errMsg = "查询图表系列信息失败"
			return
		}
		for _, info := range chartSectionCombineEdbList {
			if info.DateConfType == 1 && info.DateConfName != "" {
				dateConfListMapSave[info.DateConfName] = true
			}
		}
	}
	newExtraConfig = extraConfig
	// 去掉没有被引用的配置
	newExtraConfig.DateConfList = make([]*data_manage.ChartSectionDateConfItem, 0)
	for _, v := range extraConfig.DateConfList {
		if _, ok := dateConfListMapSave[v.DateConfName]; ok {
			newExtraConfig.DateConfList = append(newExtraConfig.DateConfList, v)
		}
	}
	return
}

// GetChartSectionCombineData 截面组合图的数据处理
func GetChartSectionCombineData(chartInfo *data_manage.ChartInfo, mappingList []*data_manage.ChartEdbInfoMapping, edbDataListMap map[int][]*data_manage.EdbDataList, extraConfig data_manage.ChartSectionAllExtraConf) (edbIdList []int, dataListResp data_manage.ChartSectionCombineDataResp, err error) {
	// 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
	edbDataMap := make(map[int]map[string]float64)
	for edbInfoId, edbDataList := range edbDataListMap {
		edbDateData := make(map[string]float64)
		for _, edbData := range edbDataList {
			edbDateData[edbData.DataTime] = edbData.Value
		}
		edbDataMap[edbInfoId] = edbDateData
	}

	// edbIdList 指标展示顺序;x轴的指标顺序
	edbIdList = make([]int, 0)
	edbMappingMap := make(map[int]*data_manage.ChartEdbInfoMapping)
	for _, v := range mappingList {
		edbIdList = append(edbIdList, v.EdbInfoId)
		edbMappingMap[v.EdbInfoId] = v
	}
	// 确定好截面散点图返回的数据格式
	// 获取所有的引用日期设置
	dateConfListMap := make(map[string]*data_manage.ChartSectionDateConfItem)
	dateConfEdbIds := make([]int, 0)
	for _, v := range extraConfig.DateConfList {
		if v.EdbInfoId > 0 {
			dateConfEdbIds = append(dateConfEdbIds, v.EdbInfoId)
		}
		dateConfListMap[v.DateConfName] = v
	}
	// 遍历每个系列
	// 遍历每个指标,根据选中的日期,进行日期变换得到最终的日期,根据最终的日期获取对应的值
	// 组装数据
	baseSeries := new(data_manage.ChartSectionSeriesItem) //y轴的系列
	var firstUnit, leftUnit, rightUnit, right2Unit *data_manage.XData
	var (
		LeftMin   float64
		LeftMax   float64
		RightMin  float64
		RightMax  float64
		Right2Min float64
		Right2Max float64
	)
	seriesDataListMap := make(map[string][]float64)
	seriesNoDataIndexMap := make(map[string][]int)
	for _, seriesItem := range extraConfig.SeriesList {
		var maxDate time.Time
		var minVal, maxVal float64
		noDataEdbIndex := make([]int, 0)
		dataList := make([]float64, len(seriesItem.EdbInfoList))
		for index, edbConf := range seriesItem.EdbInfoList {
			edbInfoId := edbConf.EdbInfoId //X轴的指标
			edbMappingInfo, ok := edbMappingMap[edbInfoId]
			if !ok {
				continue
			}
			seriesItem.EdbInfoList[index].EdbName = edbMappingInfo.EdbName
			seriesItem.EdbInfoList[index].EdbNameEn = edbMappingInfo.EdbNameEn
			seriesItem.EdbInfoList[index].EdbInfoType = edbMappingInfo.EdbInfoCategoryType
			seriesItem.EdbInfoList[index].Unit = edbMappingInfo.Unit
			seriesItem.EdbInfoList[index].UnitEn = edbMappingInfo.UnitEn
			if index == 0 {
				firstUnit = &data_manage.XData{
					Name:   edbMappingInfo.Unit,
					NameEn: edbMappingInfo.UnitEn,
				}
			}
			edbDataList, ok3 := edbDataListMap[edbInfoId]
			if !ok3 {
				err = fmt.Errorf("指标%d的日期数据不存在", edbInfoId)
				return
			}
			//日期变换处理,判断用指标的最新日期还是,直接获取引用日期
			var findDate string
			if edbConf.DateConfType == 0 {
				if edbInfoId == 0 {
					err = fmt.Errorf("请选择指标")
					return
				}
				findDate, err = GetChartSectionSeriesDateByDateChange(edbInfoId, edbDataList, edbConf.DateConf.DateChange, edbConf.DateConf.MoveForward)
				if err != nil {
					err = fmt.Errorf("指标%d的日期变换处理失败", edbInfoId)
					return
				}
			} else {
				// 获取日期配置
				dateConfItem, ok1 := dateConfListMap[edbConf.DateConfName]
				if !ok1 {
					err = fmt.Errorf("引用日期配置不存在")
					return
				}
				// todo 根据日期变换得到最终日期
				edbDataListTmp := make([]*data_manage.EdbDataList, 0)
				if dateConfItem.EdbInfoId > 0 {
					edbDataListTmp, ok1 = edbDataListMap[dateConfItem.EdbInfoId]
					if !ok1 {
						err = fmt.Errorf("指标%d的日期数据不存在", dateConfItem.EdbInfoId)
						return
					}
				}

				findDate, err = GetChartSectionSeriesDateByDateChange(dateConfItem.EdbInfoId, edbDataListTmp, dateConfItem.DateChange, dateConfItem.MoveForward)
				if err != nil {
					err = fmt.Errorf("指标%d的日期变换处理失败", dateConfItem.EdbInfoId)
					return
				}
			}
			findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
			if maxDate.IsZero() {
				maxDate = findDateTime
			} else {
				if findDateTime.After(maxDate) {
					maxDate = findDateTime
				}
			}
			if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
				dataList[index] = tmpValue
				if index == 0 {
					minVal = tmpValue
					maxVal = tmpValue
				} else {
					if tmpValue < minVal {
						minVal = tmpValue
					}
					if tmpValue > maxVal {
						maxVal = tmpValue
					}
				}
			} else {
				dataList[index] = 0
				noDataEdbIndex = append(noDataEdbIndex, index)
				continue
			}
		}
		seriesDataListMap[seriesItem.SeriesName] = dataList
		seriesNoDataIndexMap[seriesItem.SeriesName] = noDataEdbIndex
		seriesItem.DataList = dataList
		seriesItem.MinData = minVal
		seriesItem.MaxData = maxVal
		seriesItem.NoDataEdbIndex = noDataEdbIndex
		if extraConfig.BaseChartSeriesName == seriesItem.SeriesName {
			baseSeries = seriesItem
		}
		if seriesItem.IsAxis == 1 && leftUnit == nil { //左轴,右轴
			leftUnit = firstUnit
		} else if seriesItem.IsAxis == 0 && rightUnit == nil {
			rightUnit = firstUnit
		} else if seriesItem.IsAxis == 2 && right2Unit == nil {
			right2Unit = firstUnit
		}

		//处理上下限
		var minData, maxData float64
		for _, d := range seriesItem.DataList {
			if minData > d {
				minData = d
			}
			if maxData < d {
				maxData = d
			}
		}
		if seriesItem.IsAxis == 1 {
			if LeftMin > minData {
				LeftMin = minData
			}
			if LeftMax < maxData {
				LeftMax = maxData
			}
		} else if seriesItem.IsAxis == 0 {
			if RightMin > minData {
				RightMin = minData
			}
			if RightMax < maxData {
				RightMax = maxData
			}
		} else {
			if Right2Min > minData {
				Right2Min = minData
			}
			if Right2Max < maxData {
				Right2Max = maxData
			}
		}
	}
	// 处理横轴
	// 遍历基准系列,判断有几个横轴名称
	if baseSeries == nil {
		err = fmt.Errorf("基准系列不存在")
		return
	}
	// 处理系列排序
	if extraConfig.SortType > 0 {
		newSeriesDataListMap, newSeriesNoDataIndexMap := SortChartSeriesDataSet(baseSeries.SeriesName, baseSeries.DataList, baseSeries.NoDataEdbIndex, seriesDataListMap, seriesNoDataIndexMap, extraConfig.SortType)
		for k, item := range extraConfig.SeriesList {
			dataList, ok := newSeriesDataListMap[item.SeriesName]
			if ok {
				extraConfig.SeriesList[k].DataList = dataList
			}
			noIndex, ok := newSeriesNoDataIndexMap[item.SeriesName]
			if ok {
				extraConfig.SeriesList[k].NoDataEdbIndex = noIndex
			}
		}
	}

	xDataList := make([]data_manage.XData, 0)
	for index, item := range baseSeries.EdbInfoList {
		if index == 0 {
			firstUnit = &data_manage.XData{
				Name:   item.Unit,
				NameEn: item.UnitEn,
			}
		}
		tmp := data_manage.XData{
			Name:   item.EdbName,
			NameEn: item.EdbNameEn,
		}
		// 如果已经设置了横轴名称,则用设置的名称替换
		if len(extraConfig.XDataList) > index {
			newItem := extraConfig.XDataList[index]
			if newItem.Name != "" {
				tmp = newItem
			}
		}
		xDataList = append(xDataList, tmp)
	}
	dataListResp.XDataList = xDataList

	unitList := new(data_manage.ChartSectionCombineUnit)
	if baseSeries.IsAxis == 1 { //左轴,右轴
		leftUnit = firstUnit
	} else if baseSeries.IsAxis == 2 {
		rightUnit = firstUnit
	} else {
		right2Unit = firstUnit
	}
	if leftUnit != nil {
		unitList.LeftName = leftUnit.Name
		unitList.LeftNameEn = leftUnit.NameEn
	}
	if rightUnit != nil {
		unitList.RightName = rightUnit.Name
		unitList.RightNameEn = rightUnit.NameEn
	}
	if right2Unit != nil {
		unitList.RightTwoName = right2Unit.Name
		unitList.RightTwoNameEn = right2Unit.NameEn
	}
	if extraConfig.UnitList.LeftName != "" {
		unitList.LeftName = extraConfig.UnitList.LeftName
		unitList.LeftNameEn = extraConfig.UnitList.LeftNameEn
	}
	if extraConfig.UnitList.RightName != "" {
		unitList.RightName = extraConfig.UnitList.RightName
		unitList.RightNameEn = extraConfig.UnitList.RightNameEn
	}

	if extraConfig.UnitList.RightTwoName != "" {
		unitList.RightTwoName = extraConfig.UnitList.RightTwoName
		unitList.RightTwoNameEn = extraConfig.UnitList.RightTwoNameEn
	}

	if chartInfo != nil && chartInfo.MinMaxSave == 1 {
		dataListResp.LeftMin = chartInfo.LeftMin
		dataListResp.LeftMax = chartInfo.LeftMax
		dataListResp.RightMin = chartInfo.RightMin
		dataListResp.RightMax = chartInfo.RightMax
		dataListResp.Right2Min = chartInfo.Right2Min
		dataListResp.Right2Max = chartInfo.Right2Max
	} else {
		dataListResp.LeftMin = strconv.FormatFloat(LeftMin, 'f', -1, 64)
		dataListResp.LeftMax = strconv.FormatFloat(LeftMax, 'f', -1, 64)
		dataListResp.RightMin = strconv.FormatFloat(RightMin, 'f', -1, 64)
		dataListResp.RightMax = strconv.FormatFloat(RightMax, 'f', -1, 64)
		dataListResp.Right2Min = strconv.FormatFloat(Right2Min, 'f', -1, 64)
		dataListResp.Right2Max = strconv.FormatFloat(Right2Max, 'f', -1, 64)
	}

	// 查询引用日期里的指标信息
	if len(dateConfEdbIds) > 0 {
		dateConfEdbList, e := data_manage.GetEdbInfoByIdList(dateConfEdbIds)
		if e != nil {
			err = fmt.Errorf("查询引用日期里的指标信息失败,错误信息:%s", e.Error())
			return
		}
		dateConfEdbMap := make(map[int]*data_manage.EdbInfo)
		for _, dateConfEdb := range dateConfEdbList {
			dateConfEdbMap[dateConfEdb.EdbInfoId] = dateConfEdb
		}
		for i, dateConf := range extraConfig.DateConfList {
			if dateConf.EdbInfoId > 0 {
				edbItem, ok := dateConfEdbMap[dateConf.EdbInfoId]
				if ok {
					extraConfig.DateConfList[i].EdbName = edbItem.EdbName
					extraConfig.DateConfList[i].EdbInfoId = edbItem.EdbInfoId
					extraConfig.DateConfList[i].EdbInfoType = edbItem.EdbInfoType
					extraConfig.DateConfList[i].Frequency = edbItem.Frequency
					extraConfig.DateConfList[i].EndDate = edbItem.EndDate
				}

			}
		}
	}

	dataListResp.SeriesList = extraConfig.SeriesList
	dataListResp.DateConfList = extraConfig.DateConfList
	dataListResp.BaseChartSeriesName = extraConfig.BaseChartSeriesName
	dataListResp.UnitList = unitList
	dataListResp.IsHeap = extraConfig.IsHeap
	dataListResp.SortType = extraConfig.SortType
	return
}

// GetChartSectionSeriesDateByDateChange 获取日期变换后的日期edbInfoId 1指标日期,2 系统日期
func GetChartSectionSeriesDateByDateChange(edbInfoId int, dataList []*data_manage.EdbDataList, dateChange []*data_manage.ChartSectionDateChange, moveForward int) (newDate string, err error) {
	if edbInfoId > 0 { //指标日期
		newDate = GetEdbDateByMoveForward(moveForward, dataList)
	} else {
		//系统日期
		newDate = time.Now().Format(utils.FormatDate)
	}
	if newDate != "" && len(dateChange) > 0 {
		newDate, err = HandleChartSectionSeriesDateChange(newDate, dateChange)
	}
	return
}

func GetEdbDateByMoveForward(moveForward int, edbDataList []*data_manage.EdbDataList) (date string) {
	dateList := make([]string, 0)
	for _, v := range edbDataList {
		dateList = append(dateList, v.DataTime)
	}

	date = GetEdbDateByMoveForwardByDateList(moveForward, dateList)
	return
}

func GetEdbDateByMoveForwardByDateList(moveForward int, dateList []string) (date string) {
	// 根据日期进行排序
	index := len(dateList) - 1 - moveForward
	for k, v := range dateList {
		if k == index {
			date = v
			return
		}
	}
	return
}

// HandleChartSectionSeriesDateChange 处理日期变换
func HandleChartSectionSeriesDateChange(date string, dateChange []*data_manage.ChartSectionDateChange) (newDate string, err error) {
	newDate = date
	if newDate != "" {
		if len(dateChange) > 0 {
			var dateTime time.Time
			dateTime, err = time.ParseInLocation(utils.FormatDate, newDate, time.Local)
			if err != nil {
				err = fmt.Errorf("日期解析失败: %s", err.Error())
				return
			}
			for _, v := range dateChange {
				if v.ChangeType == 1 {
					dateTime = dateTime.AddDate(v.Year, v.Month, v.Day)
					newDate = dateTime.Format(utils.FormatDate)
				} else if v.ChangeType == 2 {
					newDate, err, _ = handleSystemAppointDateT(dateTime, v.FrequencyDay, v.Frequency)
					if err != nil {
						return
					}
					dateTime, err = time.ParseInLocation(utils.FormatDate, newDate, time.Local)
					if err != nil {
						err = fmt.Errorf("日期解析失败: %s", err.Error())
						return
					}
				}
			}
		}
	}

	return
}

// handleSystemAppointDateT
// @Description: 处理系统日期相关的指定频率(所在周/旬/月/季/半年/年的最后/最早一天)
// @author: Roc
// @datetime2023-10-27 09:31:35
// @param Frequency string
// @param Day string
// @return date string
// @return err error
// @return errMsg string
func handleSystemAppointDateT(currDate time.Time, appointDay, frequency string) (date string, err error, errMsg string) {
	//currDate := time.Now()
	switch frequency {
	case "本周":
		day := int(currDate.Weekday())
		if day == 0 { // 周日
			day = 7
		}
		num := 0
		switch appointDay {
		case "周一":
			num = 1
		case "周二":
			num = 2
		case "周三":
			num = 3
		case "周四":
			num = 4
		case "周五":
			num = 5
		case "周六":
			num = 6
		case "周日":
			num = 7
		}
		day = num - day
		date = currDate.AddDate(0, 0, day).Format(utils.FormatDate)
	case "本旬":
		day := currDate.Day()
		var tmpDate time.Time
		switch appointDay {
		case "第一天":
			if day <= 10 {
				tmpDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, currDate.Location())
			} else if day <= 20 {
				tmpDate = time.Date(currDate.Year(), currDate.Month(), 11, 0, 0, 0, 0, currDate.Location())
			} else {
				tmpDate = time.Date(currDate.Year(), currDate.Month(), 21, 0, 0, 0, 0, currDate.Location())
			}
		case "最后一天":
			if day <= 10 {
				tmpDate = time.Date(currDate.Year(), currDate.Month(), 10, 0, 0, 0, 0, currDate.Location())
			} else if day <= 20 {
				tmpDate = time.Date(currDate.Year(), currDate.Month(), 20, 0, 0, 0, 0, currDate.Location())
			} else {
				tmpDate = time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, currDate.Location()).AddDate(0, 0, -1)
			}
		}
		date = tmpDate.Format(utils.FormatDate)
	case "本月":
		var tmpDate time.Time
		switch appointDay {
		case "第一天":
			tmpDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, currDate.Location())
		case "最后一天":
			tmpDate = time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, currDate.Location()).AddDate(0, 0, -1)
		}
		date = tmpDate.Format(utils.FormatDate)
	case "本季":
		month := currDate.Month()
		var tmpDate time.Time
		switch appointDay {
		case "第一天":
			if month <= 3 {
				tmpDate = time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, currDate.Location())
			} else if month <= 6 {
				tmpDate = time.Date(currDate.Year(), 4, 1, 0, 0, 0, 0, currDate.Location())
			} else if month <= 9 {
				tmpDate = time.Date(currDate.Year(), 7, 1, 0, 0, 0, 0, currDate.Location())
			} else {
				tmpDate = time.Date(currDate.Year(), 10, 1, 0, 0, 0, 0, currDate.Location())
			}
		case "最后一天":
			if month <= 3 {
				tmpDate = time.Date(currDate.Year(), 3, 31, 0, 0, 0, 0, currDate.Location())
			} else if month <= 6 {
				tmpDate = time.Date(currDate.Year(), 6, 30, 0, 0, 0, 0, currDate.Location())
			} else if month <= 9 {
				tmpDate = time.Date(currDate.Year(), 9, 30, 0, 0, 0, 0, currDate.Location())
			} else {
				tmpDate = time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, currDate.Location())
			}
		}
		date = tmpDate.Format(utils.FormatDate)
	case "本半年":
		month := currDate.Month()
		var tmpDate time.Time
		switch appointDay {
		case "第一天":
			if month <= 6 {
				tmpDate = time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, currDate.Location())
			} else {
				tmpDate = time.Date(currDate.Year(), 7, 1, 0, 0, 0, 0, currDate.Location())
			}
		case "最后一天":
			if month <= 6 {
				tmpDate = time.Date(currDate.Year(), 6, 30, 0, 0, 0, 0, currDate.Location())
			} else {
				tmpDate = time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, currDate.Location())
			}
		}
		date = tmpDate.Format(utils.FormatDate)
	case "本年":
		var tmpDate time.Time
		switch appointDay {
		case "第一天":
			tmpDate = time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, currDate.Location())
		case "最后一天":
			tmpDate = time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, currDate.Location())
		}
		date = tmpDate.Format(utils.FormatDate)
	default:
		errMsg = "错误的日期频度:" + frequency
		err = errors.New(errMsg)
		return
	}

	return
}

// sortTripleDataSet 以第一组数据为基准,排序之后,空数组的位置也要同步变更
func SortChartSeriesDataSet(baseName string, baseDataList []float64, baseSeriesNoDataIndexList []int, dataListMap map[string][]float64, noDataListIndexMap map[string][]int, asc int) (newDataListMap map[string][]float64, newNoDataListIndexMap map[string][]int) {
	newDataListMap = make(map[string][]float64)
	newNoDataListIndexMap = make(map[string][]int)

	indices := make([]int, len(baseDataList))
	newIndices := make([]int, len(baseDataList)-len(baseSeriesNoDataIndexList))
	// 初始化indices
	for i := range indices {
		indices[i] = i
	}
	if len(baseSeriesNoDataIndexList) > 0 { //把空值移动到最右边
		j := 0
		for i := range indices {
			isEmpty := false
			for _, v := range baseSeriesNoDataIndexList {
				if i == v {
					isEmpty = true
					break
				}
			}
			if isEmpty {
				continue
			}
			newIndices[j] = i
			j += 1
		}
		newIndices = append(newIndices, baseSeriesNoDataIndexList...)
		// 根据排序后的indices重新排列所有组的数据
		for i, idx := range newIndices {
			for k, _ := range dataListMap {
				if _, ok := newDataListMap[k]; !ok {
					newDataListMap[k] = make([]float64, len(baseDataList))
				}
				if utils.InArrayByInt(noDataListIndexMap[k], idx) { //如果i位置上的数据为空,那么
					newNoDataListIndexMap[k] = append(newNoDataListIndexMap[k], i)
				}
				newDataListMap[k][i] = dataListMap[k][idx]
			}
		}
		dataListMap = newDataListMap
		noDataListIndexMap = newNoDataListIndexMap
		newDataListMap = make(map[string][]float64)
		newNoDataListIndexMap = make(map[string][]int)
		baseDataList, _ = dataListMap[baseName]
		//先把空的数据移动到最后面
		indices = make([]int, len(baseDataList)-len(baseSeriesNoDataIndexList)) //空值不参与排序
		newIndices = make([]int, len(baseDataList))                             //空值不参与排序
		// 初始化indices
		for i := range indices {
			indices[i] = i
		}

	}
	length := len(indices)
	baseDataSortList := make([]data_manage.ChartSectionSeriesValSort, length)
	for i, value := range baseDataList {
		if i < length {
			baseDataSortList[i] = data_manage.ChartSectionSeriesValSort{Index: i, Value: value}
		}
	}
	if asc == 1 {
		// 使用sort.Sort进行排序
		sort.Sort(data_manage.ChartSectionSeriesValSortAsc(baseDataSortList))
	} else {
		sort.Sort(data_manage.ChartSectionSeriesValSortDesc(baseDataSortList))
	}

	for k, v := range baseDataSortList {
		indices[k] = v.Index
	}

	for i := range newIndices {
		if i < length {
			newIndices[i] = indices[i]
		} else {
			newIndices[i] = i
		}
	}
	// 根据排序后的indices重新排列所有组的数据
	for i, idx := range newIndices {
		for k, _ := range dataListMap {
			if _, ok := newDataListMap[k]; !ok {
				newDataListMap[k] = make([]float64, len(baseDataList))
			}
			if utils.InArrayByInt(noDataListIndexMap[k], idx) { //如果i位置上的数据为空,那么
				newNoDataListIndexMap[k] = append(newNoDataListIndexMap[k], i)
			}
			newDataListMap[k][i] = dataListMap[k][idx]
		}
	}
	return
}