package controllers

import (
	"encoding/json"
	"fmt"
	"hongze/hongze_chart_lib/models"
	"hongze/hongze_chart_lib/models/data_manage"
	correlationServ "hongze/hongze_chart_lib/services/data/correlation"
	future_goodServ "hongze/hongze_chart_lib/services/data/future_good"
	"hongze/hongze_chart_lib/utils"
	"strings"
	"time"
)

// CommonChartInfoDetailFromUniqueCode
// @Title 根据编码获取图表详情
// @Description 根据编码获取图表详情接口
// @Param   UniqueCode   query   int  true       "图表唯一编码,如果是管理后台访问,传固定字符串:7c69b590249049942070ae9dcd5bf6dc"
// @Param   IsCache   query   bool  true       "是否走缓存,默认false"
// @Success 200 {object} data_manage.ChartInfoDetailFromUniqueCodeResp
// @router /common/detail [get]
func (this *ChartController) CommonChartInfoDetailFromUniqueCode() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	uniqueCode := this.GetString("UniqueCode")
	if uniqueCode == "" {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误,uniqueCode is empty"
		return
	}
	key := utils.HZ_CHART_LIB_DETAIL + uniqueCode
	resp := new(models.ChartInfoDetailResp)
	//判断是否有缓存
	if utils.Re == nil {
		if utils.Re == nil && utils.Rc.IsExist(key) {
			if data, err1 := utils.Rc.RedisBytes(key); err1 == nil {
				err := json.Unmarshal(data, &resp)
				if err == nil && resp != nil {
					br.Ret = 200
					br.Success = true
					br.Msg = "获取成功"
					br.Data = resp
					fmt.Println("source redis")
					return
				}
			}
		}
	}

	chartInfo, err := models.GetChartInfoByUniqueCode(uniqueCode)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Msg = "该图已被删除,请刷新页面"
			br.ErrMsg = "该图已被删除,请刷新页面,Err:" + err.Error()
			return
		}
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
		return
	}

	switch chartInfo.Source {
	case utils.CHART_SOURCE_DEFAULT:
		resp, isOk, msg, errMsg := GetChartInfoDetailFromUniqueCode(chartInfo, key)
		if !isOk {
			br.Msg = msg
			br.ErrMsg = errMsg
			return
		}
		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		br.Data = resp
	case utils.CHART_SOURCE_FUTURE_GOOD:
		resp, isOk, msg, errMsg := GetFutureGoodChartInfoDetailFromUniqueCode(chartInfo, key)
		if !isOk {
			br.Msg = msg
			br.ErrMsg = errMsg
			return
		}
		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		br.Data = resp
	case utils.CHART_SOURCE_CORRELATION:
		resp, isOk, msg, errMsg := GetCorrelationChartInfoDetailFromUniqueCode(chartInfo, key)
		if !isOk {
			br.Msg = msg
			br.ErrMsg = errMsg
			return
		}
		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		br.Data = resp
	default:
		br.Msg = "错误的图表"
		br.ErrMsg = "错误的图表"
		return
	}
}

// GetFutureGoodChartInfoDetailFromUniqueCode 根据编码获取图表详情
func GetFutureGoodChartInfoDetailFromUniqueCode(chartInfo *models.ChartInfo, key string) (resp *models.ChartInfoDetailResp, isOk bool, msg, errMsg string) {
	resp = new(models.ChartInfoDetailResp)

	chartInfoId := chartInfo.ChartInfoId

	startDate := chartInfo.StartDate
	endDate := chartInfo.EndDate

	// 兼容日期错误
	{
		if strings.Count(startDate, "-") == 1 {
			startDate = startDate + "-01"
		}
		if strings.Count(endDate, "-") == 1 {
			endDate = endDate + "-01"
		}
	}

	edbInfoMapping, err := models.GetEtaEdbChartEdbMapping(chartInfoId)
	if err != nil {
		msg = "获取失败"
		errMsg = "获取图表,现货指标信息失败,Err:" + err.Error()
		return
	}
	futureGoodEdbInfoMapping, err := models.GetFutureGoodEdbChartEdbMapping(chartInfoId)
	if err != nil {
		msg = "获取失败"
		errMsg = "获取图表的期货商品指标信息失败,Err:" + err.Error()
		return
	}

	// 商品价格曲线图的一些配置
	var barConfig data_manage.BarChartInfoReq
	barChartInfoDateList := make([]data_manage.BarChartInfoDateReq, 0)
	//barChartInfoSort := data_manage.BarChartInfoSortReq{}

	if chartInfo.BarConfig == `` {
		msg = "商品价格曲线图未配置"
		errMsg = "商品价格曲线图未配置"
		return
	}
	err = json.Unmarshal([]byte(chartInfo.BarConfig), &barConfig)
	if err != nil {
		msg = "商品价格曲线图配置异常"
		errMsg = "商品价格曲线图配置异常"
		return
	}

	barChartInfoDateList = barConfig.DateList
	//barChartInfoSort = barConfig.Sort

	// 获取图表中的指标数据
	barConfigEdbInfoIdList, edbList, xEdbIdValue, xDataList, yDataList, err := future_goodServ.GetChartEdbData(chartInfoId, startDate, endDate, edbInfoMapping, futureGoodEdbInfoMapping, barChartInfoDateList)
	if err != nil {
		msg = "获取失败"
		errMsg = "获取图表,指标信息失败,Err:" + err.Error()
		return
	}
	warnEdbList := make([]string, 0)
	if len(edbList) <= 0 {
		msg = "商品价格曲线图表指标异常"
		errMsg = "商品价格曲线图表异常"
		return
	}
	baseEdbInfo := edbList[0] //现货指标

	for _, v := range edbList {
		if v.IsNullData {
			warnEdbList = append(warnEdbList, v.EdbName+"("+v.EdbCode+")")
		}
		// 指标别名
		if barConfigEdbInfoIdList != nil && len(barConfigEdbInfoIdList) > 0 {
			for _, reqEdb := range barConfigEdbInfoIdList {
				if v.EdbInfoId == reqEdb.EdbInfoId {
					v.EdbAliasName = reqEdb.Name
					v.EdbAliasNameEn = reqEdb.NameEn
				}
			}
		}
	}
	chartInfo.UnitEn = baseEdbInfo.UnitEn

	resp.ChartInfo = chartInfo
	resp.EdbInfoList = edbList
	resp.XEdbIdValue = xEdbIdValue
	resp.YDataList = yDataList
	resp.XDataList = xDataList
	//resp.BarChartInfo = barConfig
	//resp.Status = true

	// 将数据加入缓存
	if utils.Re == nil {
		data, _ := json.Marshal(resp)
		utils.Rc.Put(key, data, 2*time.Hour)
	}
	isOk = true

	return
}

// FutureGoodChartInfoRefresh
// @Title 商品价格图表刷新接口
// @Description 商品价格图表刷新接口
// @Param   UniqueCode   query   string  true       "图表唯一编码,如果是管理后台访问,传固定字符串:7c69b590249049942070ae9dcd5bf6dc"
// @Success Ret=200 刷新成功
// @router /future_good/refresh [get]
func (this *ChartController) FutureGoodChartInfoRefresh() {
	br := new(models.BaseResponse).Init()
	chartId := 0
	defer func() {
		// 添加日志
		if chartId > 0 {
			shareChartRefreshLogInfo := &models.ShareChartRefreshLog{
				Ip:         this.Ctx.Input.IP(),
				ChartId:    chartId,
				CreateTime: time.Now(),
			}
			models.AddShareChartRefreshLog(shareChartRefreshLogInfo)
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()

	uniqueCode := this.GetString("UniqueCode")
	if uniqueCode == "" {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误,uniqueCode is empty"
		return
	}
	chartInfo, err := models.GetChartInfoByUniqueCode(uniqueCode)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Msg = "该图已被删除,请刷新页面"
			br.ErrMsg = "该图已被删除,请刷新页面,Err:" + err.Error()
			return
		}
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
		return
	}
	chartId = chartInfo.ChartInfoId

	err = future_goodServ.FutureGoodChartInfoRefresh(chartInfo.ChartInfoId)
	if err != nil {
		br.Msg = "刷新失败"
		br.ErrMsg = "刷新图表关联指标信息失败,Err:" + err.Error()
		return
	}
	//err = data.ChartInfoRefresh(chartInfo.ChartInfoId)
	//if err != nil {
	//	br.Msg = "刷新失败"
	//	br.ErrMsg = "刷新图表关联指标信息失败,Err:" + err.Error()
	//	return
	//}

	//err = data.ChartInfoRefreshV2(chartInfo.ChartInfoId)
	//if err != nil {
	//	br.Msg = "刷新失败"
	//	br.ErrMsg = "刷新图表关联指标信息失败,Err:" + err.Error()
	//	return
	//}

	//清除数据缓存
	key := utils.HZ_CHART_LIB_DETAIL + uniqueCode
	if utils.Re == nil {
		utils.Rc.Delete(key)
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "刷新成功"
}

// GetCorrelationChartInfoDetailFromUniqueCode 根据编码获取相关性图表详情
func GetCorrelationChartInfoDetailFromUniqueCode(chartInfo *models.ChartInfo, key string) (resp *models.ChartInfoDetailResp, isOk bool, msg, errMsg string) {
	resp = new(models.ChartInfoDetailResp)

	chartInfoId := chartInfo.ChartInfoId

	startDate := chartInfo.StartDate
	endDate := chartInfo.EndDate

	// 兼容日期错误
	{
		if strings.Count(startDate, "-") == 1 {
			startDate = startDate + "-01"
		}
		if strings.Count(endDate, "-") == 1 {
			endDate = endDate + "-01"
		}
	}

	// 相关性图表信息
	correlationChart := new(data_manage.ChartInfoCorrelation)
	if e := correlationChart.GetItemById(chartInfoId); e != nil {
		msg = "获取失败"
		errMsg = "获取图表相关性信息失败, Err:" + e.Error()
		return
	}
	if correlationChart.PeriodData == "" || correlationChart.CorrelationData == "" {
		msg = "获取失败"
		errMsg = "相关性图表数据有误"
		return
	}
	//chartInfo.CorrelationLeadUnit = correlationChart.LeadUnit
	xData := make([]int, 0)
	yData := make([]float64, 0)
	if e := json.Unmarshal([]byte(correlationChart.PeriodData), &xData); e != nil {
		msg = "获取失败"
		errMsg = "相关性图表X轴数据有误, Err:" + e.Error()
		return
	}
	if e := json.Unmarshal([]byte(correlationChart.CorrelationData), &yData); e != nil {
		msg = "获取失败"
		errMsg = "相关性图表X轴数据有误, Err:" + e.Error()
		return
	}

	// 获取指标信息
	edbInfoMappingA, e := models.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdFirst)
	if e != nil {
		msg = "获取失败"
		errMsg = "获取相关性图表, A指标mapping信息失败, Err:" + e.Error()
		return
	}
	edbInfoMappingB, e := models.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdSecond)
	if e != nil {
		msg = "获取失败"
		errMsg = "获取相关性图表, B指标mapping信息失败, Err:" + e.Error()
		return
	}

	xEdbIdValue := xData
	yDataList := make([]models.YData, 0)
	yDate := "0000-00-00"
	yDataList = append(yDataList, models.YData{
		Date:  yDate,
		Value: yData,
	})

	// 完善指标信息
	edbList, e := correlationServ.GetChartEdbInfoFormat(chartInfo.ChartInfoId, edbInfoMappingA, edbInfoMappingB)
	if e != nil {
		msg = "获取失败"
		errMsg = "获取相关性图表, 完善指标信息失败, Err:" + e.Error()
		return
	}
	correlationInfo := new(models.CorrelationInfo)
	correlationInfo.LeadValue = correlationChart.LeadValue
	correlationInfo.LeadUnit = correlationChart.LeadUnit
	correlationInfo.StartDate = correlationChart.StartDate.Format(utils.FormatDate)
	correlationInfo.EndDate = correlationChart.EndDate.Format(utils.FormatDate)
	correlationInfo.LeadValue = correlationChart.LeadValue
	correlationInfo.EdbInfoIdFirst = correlationChart.EdbInfoIdFirst
	correlationInfo.EdbInfoIdSecond = correlationChart.EdbInfoIdSecond

	resp.ChartInfo = chartInfo
	resp.EdbInfoList = edbList
	resp.XEdbIdValue = xEdbIdValue
	resp.YDataList = yDataList
	resp.CorrelationChartInfo = correlationInfo

	// 将数据加入缓存
	if utils.Re == nil {
		d, _ := json.Marshal(resp)
		_ = utils.Rc.Put(key, d, 2*time.Hour)
	}
	isOk = true
	return
}

// CorrelationChartInfoRefresh
// @Title 商品价格图表刷新接口
// @Description 商品价格图表刷新接口
// @Param   UniqueCode   query   string  true       "图表唯一编码,如果是管理后台访问,传固定字符串:7c69b590249049942070ae9dcd5bf6dc"
// @Success Ret=200 刷新成功
// @router /correlation/refresh [get]
func (this *ChartController) CorrelationChartInfoRefresh() {
	br := new(models.BaseResponse).Init()
	chartId := 0
	defer func() {
		// 添加日志
		if chartId > 0 {
			shareChartRefreshLogInfo := &models.ShareChartRefreshLog{
				Ip:         this.Ctx.Input.IP(),
				ChartId:    chartId,
				CreateTime: time.Now(),
			}
			models.AddShareChartRefreshLog(shareChartRefreshLogInfo)
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()

	uniqueCode := this.GetString("UniqueCode")
	if uniqueCode == "" {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误,uniqueCode is empty"
		return
	}
	chartInfo, err := models.GetChartInfoByUniqueCode(uniqueCode)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Msg = "该图已被删除,请刷新页面"
			br.ErrMsg = "该图已被删除,请刷新页面,Err:" + err.Error()
			return
		}
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
		return
	}
	chartId = chartInfo.ChartInfoId

	// 刷新相关性图表
	if e := correlationServ.ChartInfoRefresh(chartInfo.ChartInfoId); e != nil {
		br.Msg = "刷新失败"
		br.ErrMsg = "刷新相关性图表失败, Err:" + e.Error()
		return
	}

	//清除数据缓存
	key := utils.HZ_CHART_LIB_DETAIL + uniqueCode
	if utils.Re == nil {
		_ = utils.Rc.Delete(key)
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "刷新成功"
}