package data_manage

import (
	"encoding/json"
	"eta/eta_api/controllers"
	"eta/eta_api/models"
	"eta/eta_api/models/data_manage"
	dataSourceModel "eta/eta_api/models/data_source"
	"eta/eta_api/models/system"
	"eta/eta_api/services/data"
	"eta/eta_api/services/elastic"
	etaTrialService "eta/eta_api/services/eta_trial"
	"eta/eta_api/utils"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"github.com/tealeg/xlsx"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

// BaseFromRadishResearchController 萝卜投研
type BaseFromRadishResearchController struct {
	controllers.BaseAuthController
}

// IndexPageList
// @Title 指标列表-分页
// @Description 指标列表-分页
// @Success 200 {object} data_manage.RadishResearchIndexPageListResp
// @router /radish_research/index/page_list [get]
func (this *BaseFromRadishResearchController) IndexPageList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	var params data_manage.RadishResearchIndexListForm
	if e := this.ParseForm(&params); e != nil {
		br.Msg = "参数解析失败"
		br.ErrMsg = fmt.Sprintf("参数解析失败, err: %v", e)
		return
	}
	resp := new(data_manage.RadishResearchIndexPageListResp)
	resp.List = make([]*data_manage.BaseFromRadishResearchIndexItem, 0)
	classifyId, _ := this.GetInt("ClassifyId", -1)

	// 分页查询
	var startSize int
	if params.PageSize <= 0 {
		params.PageSize = utils.PageSize20
	}
	if params.CurrentIndex <= 0 {
		params.CurrentIndex = 1
	}
	startSize = utils.StartIndex(params.CurrentIndex, params.PageSize)

	// 筛选项
	indexOb := new(data_manage.BaseFromRadishResearchIndex)
	var (
		cond        string
		pars        []interface{}
		classifyIds []int
	)
	// 未分类
	if classifyId == 0 {
		cond += fmt.Sprintf(` AND %s = ?`, indexOb.Cols().ClassifyId)
		pars = append(pars, classifyId)
	}
	// 包含所有子分类的指标
	if classifyId > 0 {
		classifyOb := new(data_manage.BaseFromRadishResearchClassify)
		classifies, e := classifyOb.GetItemsByCondition(fmt.Sprintf(" AND FIND_IN_SET(%d, %s)", classifyId, classifyOb.Cols().LevelPath), make([]interface{}, 0), []string{classifyOb.Cols().PrimaryId}, fmt.Sprintf("%s ASC, %s ASC", classifyOb.Cols().ParentId, classifyOb.Cols().Sort))
		if e != nil {
			br.Msg = "获取失败"
			br.ErrMsg = fmt.Sprintf("获取子分类IDs失败, %v", e)
			return
		}
		for _, v := range classifies {
			if v.BaseFromRadishResearchClassifyId <= 0 {
				continue
			}
			classifyIds = append(classifyIds, v.BaseFromRadishResearchClassifyId)
		}
		if len(classifyIds) > 0 {
			cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().ClassifyId)
			pars = append(pars, classifyIds)
		}
	}
	// 分类多选
	params.ClassifyIds = strings.TrimSpace(params.ClassifyIds)
	if params.ClassifyIds != "" {
		idsArr := strings.Split(params.ClassifyIds, ",")
		for _, v := range idsArr {
			id, _ := strconv.Atoi(v)
			if id > 0 {
				classifyIds = append(classifyIds, id)
			}
		}
		if len(classifyIds) > 0 {
			cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().ClassifyId)
			pars = append(pars, classifyIds)
		}
	}
	// 频度多选
	params.Frequencies = strings.TrimSpace(params.Frequencies)
	if params.Frequencies != "" {
		freArr := strings.Split(params.Frequencies, ",")
		if len(freArr) > 0 {
			cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().Frequency)
			pars = append(pars, freArr)
		}
	}
	// 关键词
	params.Keyword = strings.TrimSpace(params.Keyword)
	if params.Keyword != "" {
		kw := fmt.Sprint("%", params.Keyword, "%")
		cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, indexOb.Cols().IndexName, indexOb.Cols().IndexCode)
		pars = append(pars, kw, kw)
	}
	// 是否忽略已加入指标库的
	if params.IgnoreEdbExist {
		cond += fmt.Sprintf(` AND %s = 0`, indexOb.Cols().EdbExist)
	}

	// 列表合计
	total, e := indexOb.GetCountByCondition(cond, pars)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = fmt.Sprintf("获取指标总数失败, %v", e)
		return
	}
	if total <= 0 {
		page := paging.GetPaging(params.CurrentIndex, params.PageSize, 0)
		resp.Paging = page
		br.Data = resp
		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		return
	}

	items, e := indexOb.GetPageItemsByCondition(cond, pars, []string{}, "", startSize, params.PageSize)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = fmt.Sprintf("获取指标列表失败, %v", e)
		return
	}
	for _, v := range items {
		t := v.Format2Item()
		resp.List = append(resp.List, t)
	}

	page := paging.GetPaging(params.CurrentIndex, params.PageSize, total)
	resp.Paging = page
	br.Data = resp
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// IndexDetail
// @Title 指标详情
// @Description 指标详情
// @Param   IndexId  query  string  true  "指标ID"
// @Success 200 {object} data_manage.BaseFromRadishResearchIndexDetail
// @router /radish_research/index/detail [get]
func (this *BaseFromRadishResearchController) IndexDetail() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	indexId, _ := this.GetInt("IndexId")
	if indexId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = fmt.Sprintf("参数有误, IndexId: %d", indexId)
		return
	}
	resp := new(data_manage.BaseFromRadishResearchIndexDetail)

	indexOb := new(data_manage.BaseFromRadishResearchIndex)
	item, e := indexOb.GetItemById(indexId)
	if e != nil {
		if utils.IsErrNoRow(e) {
			br.Msg = "指标不存在, 请刷新页面"
			return
		}
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("获取指标失败, %v", e)
		return
	}
	if item != nil && item.BaseFromRadishResearchIndexId <= 0 {
		br.Msg = "指标不存在, 请刷新页面"
		return
	}
	resp.BaseFromRadishResearchIndexItem = item.Format2Item()
	resp.DataList = make([]*data_manage.BaseFromRadishResearchDataItem, 0)

	dataOb := new(data_manage.BaseFromRadishResearchData)
	cond := fmt.Sprintf(` AND %s = ?`, dataOb.Cols().IndexCode)
	pars := make([]interface{}, 0)
	pars = append(pars, item.IndexCode)
	dataList, e := dataOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s DESC", dataOb.Cols().DataTime))
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = fmt.Sprintf("获取指标数据失败, %v", e)
		return
	}
	for _, v := range dataList {
		resp.DataList = append(resp.DataList, v.Format2Item())
	}

	br.Data = resp
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// IndexEdit
// @Title 编辑指标
// @Description 编辑指标
// @Success 200 {object} data_manage.RadishResearchIndexEditReq
// @router /radish_research/index/edit [post]
func (this *BaseFromRadishResearchController) IndexEdit() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req data_manage.RadishResearchIndexEditReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	if req.IndexId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = fmt.Sprintf("参数有误, IndexId: %d", req.IndexId)
		return
	}

	indexOb := new(data_manage.BaseFromRadishResearchIndex)
	item, e := indexOb.GetItemById(req.IndexId)
	if e != nil {
		if utils.IsErrNoRow(e) {
			br.Msg = "指标不存在, 请刷新页面"
			return
		}
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("获取指标失败, %v", e)
		return
	}
	if item != nil && item.BaseFromRadishResearchIndexId <= 0 {
		br.Msg = "指标不存在, 请刷新页面"
		return
	}

	// 更新指标(这里不多限制,允许移到未分类)
	item.ClassifyId = req.ClassifyId
	item.ModifyTime = time.Now().Local()
	updateCols := []string{indexOb.Cols().ClassifyId, indexOb.Cols().ModifyTime}
	if e = item.Update(updateCols); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("更新指标分类失败, %v", e)
		return
	}

	// 更新ES
	go func() {
		indexItem := new(dataSourceModel.SearchDataSource)
		indexItem.PrimaryId = item.BaseFromRadishResearchIndexId
		indexItem.IndexCode = item.IndexCode
		indexItem.IndexName = item.IndexName
		indexItem.ClassifyId = item.ClassifyId
		indexItem.Unit = item.Unit
		indexItem.Frequency = item.Frequency
		indexItem.StartDate = item.StartDate.Format(utils.FormatDate)
		indexItem.EndDate = item.EndDate.Format(utils.FormatDate)
		indexItem.LatestValue = fmt.Sprint(item.LatestValue)
		indexItem.Source = utils.DATA_SOURCE_RADISH_RESEARCH
		indexItem.SourceName = utils.DATA_SOURCE_NAME_RADISH_RESEARCH
		indexItem.IsDeleted = 0
		indexItem.CreateTime = item.CreateTime.Format(utils.FormatDateTime)
		indexItem.ModifyTime = item.ModifyTime.Format(utils.FormatDateTime)

		docId := fmt.Sprintf("%d-%d", utils.DATA_SOURCE_RADISH_RESEARCH, item.BaseFromRadishResearchIndexId)
		if e := elastic.EsAddOrEditDataSourceIndex(utils.EsDataSourceIndexName, docId, indexItem); e != nil {
			utils.FileLog.Warning("RadishResearch-写入指标ES失败, %v", e)
			return
		}
	}()

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// IndexRemove
// @Title 删除指标
// @Description 删除指标
// @Success 200 {object} data_manage.RadishResearchIndexRemoveReq
// @router /radish_research/index/remove [post]
func (this *BaseFromRadishResearchController) IndexRemove() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req data_manage.RadishResearchIndexRemoveReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	if req.IndexId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = fmt.Sprintf("参数有误, IndexId: %d", req.IndexId)
		return
	}

	indexOb := new(data_manage.BaseFromRadishResearchIndex)
	item, e := indexOb.GetItemById(req.IndexId)
	if e != nil {
		if utils.IsErrNoRow(e) {
			br.Msg = "指标不存在, 请刷新页面"
			return
		}
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("获取指标失败, %v", e)
		return
	}
	if item != nil && item.BaseFromRadishResearchIndexId <= 0 {
		br.Msg = "指标不存在, 请刷新页面"
		return
	}
	if item.EdbExist == 1 {
		br.Msg = "指标已被引用, 不允许删除"
		return
	}
	if e = indexOb.RemoveIndexAndData(item.IndexCode); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("删除指标和数据失败, %v", e)
		return
	}

	// 更新ES
	go func() {
		indexItem := new(dataSourceModel.SearchDataSource)
		indexItem.PrimaryId = item.BaseFromRadishResearchIndexId
		indexItem.IndexCode = item.IndexCode
		indexItem.IndexName = item.IndexName
		indexItem.ClassifyId = item.ClassifyId
		indexItem.Unit = item.Unit
		indexItem.Frequency = item.Frequency
		indexItem.StartDate = item.StartDate.Format(utils.FormatDate)
		indexItem.EndDate = item.EndDate.Format(utils.FormatDate)
		indexItem.LatestValue = fmt.Sprint(item.LatestValue)
		indexItem.Source = utils.DATA_SOURCE_RADISH_RESEARCH
		indexItem.SourceName = utils.DATA_SOURCE_NAME_RADISH_RESEARCH
		indexItem.IsDeleted = 1 // 标记已删除
		indexItem.CreateTime = item.CreateTime.Format(utils.FormatDateTime)
		indexItem.ModifyTime = item.ModifyTime.Format(utils.FormatDateTime)

		docId := fmt.Sprintf("%d-%d", utils.DATA_SOURCE_RADISH_RESEARCH, item.BaseFromRadishResearchIndexId)
		if e := elastic.EsAddOrEditDataSourceIndex(utils.EsDataSourceIndexName, docId, indexItem); e != nil {
			utils.FileLog.Warning("RadishResearch-写入指标ES失败, %v", e)
			return
		}
	}()

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// IndexExport
// @Title 导出指标数据
// @Description 导出指标数据
// @Param   ClassifyId  query  int  false  "分类Id"
// @Success 200  导出成功
// @router /radish_research/index/export [get]
func (this *BaseFromRadishResearchController) IndexExport() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	classifyId, _ := this.GetInt("ClassifyId", -1)

	var (
		cond        string
		pars        []interface{}
		classifyIds []int
	)
	// 未分类
	indexOb := new(data_manage.BaseFromRadishResearchIndex)
	if classifyId == 0 {
		cond += fmt.Sprintf(` AND %s = ?`, indexOb.Cols().ClassifyId)
		pars = append(pars, classifyId)
	}
	// 包含所有子分类的指标
	if classifyId > 0 {
		classifyOb := new(data_manage.BaseFromRadishResearchClassify)
		classifies, e := classifyOb.GetItemsByCondition(fmt.Sprintf(" AND FIND_IN_SET(%d, %s)", classifyId, classifyOb.Cols().LevelPath), make([]interface{}, 0), []string{classifyOb.Cols().PrimaryId}, fmt.Sprintf("%s ASC, %s ASC", classifyOb.Cols().ParentId, classifyOb.Cols().Sort))
		if e != nil {
			br.Msg = "获取失败"
			br.ErrMsg = fmt.Sprintf("获取子分类IDs失败, %v", e)
			return
		}
		for _, v := range classifies {
			if v.BaseFromRadishResearchClassifyId <= 0 {
				continue
			}
			classifyIds = append(classifyIds, v.BaseFromRadishResearchClassifyId)
		}
		if len(classifyIds) > 0 {
			cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().ClassifyId)
			pars = append(pars, classifyIds)
		}
	}

	dir, _ := os.Executable()
	exPath := filepath.Dir(dir)
	downFile := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
	xlsxFile := xlsx.NewFile()

	// 获取指标数据
	indexes, e := indexOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC, %s ASC", indexOb.Cols().Sort, indexOb.Cols().PrimaryId))
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = fmt.Sprintf("获取指标失败, %v", e)
		return
	}
	if len(indexes) == 0 {
		// 无数据返回空文件
		if e := xlsxFile.Save(downFile); e != nil {
			sheet, e := xlsxFile.AddSheet("无数据")
			if e != nil {
				br.Msg = "获取失败"
				br.ErrMsg = fmt.Sprintf("新增Sheet失败, %v", e)
				return
			}
			rowSecName := sheet.AddRow()
			celSecName := rowSecName.AddCell()
			celSecName.SetValue("")
			if e = xlsxFile.Save(downFile); e != nil {
				br.Msg = "获取失败"
				br.ErrMsg = fmt.Sprintf("保存文件失败, %v", e)
				return
			}
		}
		fileName := fmt.Sprintf("%s%s%s", utils.DATA_SOURCE_NAME_RADISH_RESEARCH, time.Now().Format("06.01.02"), ".xlsx")
		this.Ctx.Output.Download(downFile, fileName)
		defer func() {
			_ = os.Remove(downFile)
		}()
		return
	}

	// 划分指标频度
	frequencyIndex := make(map[string][]*data_manage.BaseFromRadishResearchIndex)
	frequencyIndexIds := make(map[string][]int)
	for _, v := range indexes {
		if frequencyIndex[v.Frequency] == nil {
			frequencyIndex[v.Frequency] = make([]*data_manage.BaseFromRadishResearchIndex, 0)
		}
		if frequencyIndexIds[v.Frequency] == nil {
			frequencyIndexIds[v.Frequency] = make([]int, 0)
		}
		frequencyIndexIds[v.Frequency] = append(frequencyIndexIds[v.Frequency], v.BaseFromRadishResearchIndexId)
		frequencyIndex[v.Frequency] = append(frequencyIndex[v.Frequency], v)
	}

	frequencyArr := []string{"日度", "周度", "旬度", "月度", "季度", "半年度", "年度"}
	//frequencyMap := map[string]string{
	//	"日度":  "Daily",
	//	"周度":  "Weekly",
	//	"旬度":  "ten-day",
	//	"月度":  "Monthly",
	//	"季度":  "Quarterly",
	//	"半年度": "Semi-annual",
	//	"年度":  "Annual",
	//}
	dataOb := new(data_manage.BaseFromRadishResearchData)
	for _, frequency := range frequencyArr {
		// 获取对应频度指标
		secNameList := frequencyIndex[frequency]
		if len(secNameList) == 0 {
			continue
		}

		//sheetName := fmt.Sprintf("%s(%s)", frequency, frequencyMap[frequency])
		sheetNew, e := xlsxFile.AddSheet(frequency)
		if e != nil {
			utils.FileLog.Warning(fmt.Sprintf("萝卜投研导出-AddSheet err: %v", e))
			continue
		}
		secNameRow := sheetNew.AddRow()
		frequencyRow := sheetNew.AddRow()
		unitRow := sheetNew.AddRow()
		updateTimeRow := sheetNew.AddRow()

		// 指标日期序列
		indexIds := frequencyIndexIds[frequency]
		dataTimeList, e := dataOb.GetDataTimeByIndexIds(indexIds)
		if e != nil {
			utils.FileLog.Warning(fmt.Sprintf("萝卜投研导出-GetDataTimeByIndexIds err: %v", e))
			continue
		}

		// 添加excel左侧指标日期
		setRowIndex := 4
		for rk, dv := range dataTimeList {
			rowIndex := setRowIndex + rk
			row := sheetNew.Row(rowIndex)
			displayDate, _ := time.Parse(utils.FormatDate, dv)
			displayDateCell := row.AddCell()
			style := new(xlsx.Style)
			style.ApplyAlignment = true
			style.Alignment.WrapText = true
			displayDateCell.SetStyle(style)
			displayDateCell.SetDate(displayDate)
		}
		for k, sv := range secNameList {
			// 获取数据
			dataCond := fmt.Sprintf(` AND %s = ?`, dataOb.Cols().IndexCode)
			dataPars := make([]interface{}, 0)
			dataPars = append(dataPars, sv.IndexCode)
			dataList, e := dataOb.GetItemsByCondition(dataCond, dataPars, []string{}, fmt.Sprintf("%s DESC", dataOb.Cols().DataTime))
			if e != nil {
				utils.FileLog.Warning(fmt.Sprintf("萝卜投研导出-GetIndexDataByCondition err: %v", e))
				continue
			}

			if k == 0 {
				secNameRow.AddCell().SetValue("指标名称")
				frequencyRow.AddCell().SetValue("频度")
				unitRow.AddCell().SetValue("单位")
				updateTimeRow.AddCell().SetValue("更新时间")
				minCol := k * 3
				sheetNew.SetColWidth(minCol, minCol, 15)
			}
			if len(dataList) == 0 {
				continue
			}
			secNameRow.AddCell().SetValue(sv.IndexName)
			frequencyRow.AddCell().SetValue(sv.Frequency)
			unitRow.AddCell().SetValue(sv.Unit)

			updateTimeRow.AddCell().SetValue(sv.ModifyTime)
			dataInfoMap := make(map[string]*data_manage.BaseFromRadishResearchData)
			for _, v := range dataList {
				dt := v.DataTime.Format(utils.FormatDate)
				dataInfoMap[dt] = v
			}

			for rk, dtv := range dataTimeList {
				rowIndex := setRowIndex + rk
				row := sheetNew.Row(rowIndex)
				displayDateCell := row.AddCell()
				tmpData, ok := dataInfoMap[dtv]
				if ok {
					displayDateCell.SetValue(tmpData.Value)
				}
			}
		}
	}

	// 保存文件出错返回空文件
	if e := xlsxFile.Save(downFile); e != nil {
		sheet, e := xlsxFile.AddSheet("无数据")
		if e != nil {
			br.Msg = "获取失败"
			br.ErrMsg = fmt.Sprintf("新增Sheet失败, %v", e)
			return
		}
		rowSecName := sheet.AddRow()
		celSecName := rowSecName.AddCell()
		celSecName.SetValue("")
		if e = xlsxFile.Save(downFile); e != nil {
			br.Msg = "获取失败"
			br.ErrMsg = fmt.Sprintf("保存文件失败, %v", e)
			return
		}
	}
	fileName := fmt.Sprintf("%s%s%s", utils.DATA_SOURCE_NAME_RADISH_RESEARCH, time.Now().Format("06.01.02"), ".xlsx")
	this.Ctx.Output.Download(downFile, fileName)
	defer func() {
		_ = os.Remove(downFile)
	}()

	br.Ret = 200
	br.Success = true
	br.Msg = "success"

}

// IndexSelect
// @Title 批量加入指标库-选择指标
// @Description 批量加入指标库-选择指标
// @Success 200 {object} data_manage.BaseFromRadishResearchIndexItem
// @router /radish_research/index/select [post]
func (this *BaseFromRadishResearchController) IndexSelect() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req data_manage.RadishResearchIndexSelectReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	resp := make([]*data_manage.BaseFromRadishResearchIndexItem, 0)

	indexOb := new(data_manage.BaseFromRadishResearchIndex)
	var (
		cond string
		pars []interface{}
	)
	// 忽略已加入指标库的
	cond += fmt.Sprintf(` AND %s = 0`, indexOb.Cols().EdbExist)
	if len(req.ClassifyIds) > 0 {
		cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().ClassifyId)
		pars = append(pars, req.ClassifyIds)
	}
	if len(req.Frequencies) > 0 {
		cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().Frequency)
		pars = append(pars, req.Frequencies)
	}
	req.Keyword = strings.TrimSpace(req.Keyword)
	if req.Keyword != "" {
		kw := fmt.Sprint("%", req.Keyword, "%")
		cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, indexOb.Cols().IndexName, indexOb.Cols().IndexCode)
		pars = append(pars, kw, kw)
	}
	// 列表全选-SelectAll-true: IndexCodes为排除的指标, SelectAll-false: IndexCodes为选择的指标
	if len(req.IndexCodes) > 0 {
		if req.SelectAll {
			cond += fmt.Sprintf(` AND %s NOT IN ?`, indexOb.Cols().IndexCode)
		} else {
			cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().IndexCode)
		}
		pars = append(pars, req.IndexCodes)
	}

	items, e := indexOb.GetItemsByCondition(cond, pars, []string{}, "")
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = fmt.Sprintf("获取指标列表失败, %v", e)
		return
	}
	if len(items) > 30 {
		br.Msg = "批量添加指标数量不得超过30个"
		return
	}
	for _, v := range items {
		t := v.Format2Item()
		resp = append(resp, t)
	}

	br.Data = resp
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// EdbAdd
// @Title 加入指标库
// @Description 加入指标库
// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
// @Success Ret=200 保存成功
// @router /radish_research/edb/add [post]
func (this *BaseFromRadishResearchController) EdbAdd() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	deleteCache := true
	cacheKey := fmt.Sprintf("CACHE_EDB_INFO_ADD_%d_%d", utils.DATA_SOURCE_RADISH_RESEARCH, sysUser.AdminId)
	defer func() {
		if deleteCache {
			_ = utils.Rc.Delete(cacheKey)
		}
	}()
	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
		deleteCache = false
		br.Msg = "系统处理中,请稍后重试"
		return
	}
	var req data_manage.AddEdbInfoReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常"
		br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
		return
	}
	req.EdbCode = strings.TrimSpace(req.EdbCode)
	req.EdbName = strings.TrimSpace(req.EdbName)
	if req.EdbCode == "" {
		br.Msg = "指标编码不能为空"
		return
	}
	if req.EdbName == "" {
		br.Msg = "指标名称不能为空"
		return
	}
	if req.Frequency == "" {
		br.Msg = "频率不能为空"
		return
	}
	if req.Unit == "" {
		br.Msg = "单位不能为空"
		return
	}
	if req.ClassifyId <= 0 {
		br.Msg = "请选择分类"
		return
	}

	// 是否加入过指标库
	exist, e := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_RADISH_RESEARCH, req.EdbCode)
	if e != nil && !utils.IsErrNoRow(e) {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("校验是否加入过指标库失败, %v", e)
		return
	}
	if exist != nil && exist.EdbInfoId > 0 {
		br.Msg = "指标库已存在,请刷新页面"
		return
	}

	// 指标入库
	edbInfo, err, errMsg, isSendEmail := data.EdbInfoAdd(utils.DATA_SOURCE_RADISH_RESEARCH, utils.DATA_SUB_SOURCE_EDB, req.ClassifyId, req.EdbCode, req.EdbName, req.Frequency, req.Unit, req.StartDate, req.EndDate, sysUser.AdminId, sysUser.RealName, this.Lang)
	if err != nil {
		br.Msg = "保存失败"
		if errMsg != `` {
			br.Msg = errMsg
		}
		br.ErrMsg = err.Error()
		br.IsSendEmail = isSendEmail
		return
	}

	// 刷新指标数据
	refreshRes, e := data.RefreshEdbData(edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, "")
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("刷新指标数据失败, %v", e)
		return
	}
	if refreshRes != nil && refreshRes.Ret != 200 {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("刷新指标数据失败, Ret: %d, Msg: %s, ErrMsg: %s", refreshRes.Ret, refreshRes.Msg, refreshRes.ErrMsg)
		return
	}

	// 更新指标EdbExist
	indexOb := new(data_manage.BaseFromRadishResearchIndex)
	if e := indexOb.UpdateEdbExists(1, []string{req.EdbCode}); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = fmt.Sprintf("更新数据源EdbExist失败, %v", e)
		return
	}

	//新增操作日志
	{
		edbLog := new(data_manage.EdbInfoLog)
		edbLog.EdbInfoId = edbInfo.EdbInfoId
		edbLog.SourceName = edbInfo.SourceName
		edbLog.Source = edbInfo.Source
		edbLog.EdbCode = edbInfo.EdbCode
		edbLog.EdbName = edbInfo.EdbName
		edbLog.ClassifyId = edbInfo.ClassifyId
		edbLog.SysUserId = sysUser.AdminId
		edbLog.SysUserRealName = sysUser.RealName
		edbLog.CreateTime = time.Now()
		edbLog.Content = string(this.Ctx.Input.RequestBody)
		edbLog.Status = "新增指标"
		edbLog.Method = this.Ctx.Input.URI()
		go data_manage.AddEdbInfoLog(edbLog)
	}

	// 更新es
	go data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)

	// 试用平台更新用户累计新增指标数
	if utils.BusinessCode == utils.BusinessCodeSandbox {
		go func() {
			adminItem, e := system.GetSysAdminById(sysUser.AdminId)
			if e != nil {
				return
			}
			if adminItem != nil && adminItem.AdminId <= 0 {
				return
			}
			if adminItem.DepartmentName != "ETA试用客户" {
				return
			}

			var r etaTrialService.EtaTrialUserReq
			r.Mobile = adminItem.Mobile
			_, _ = etaTrialService.UpdateUserIndexNum(r)
		}()
	}

	resp := new(data_manage.AddEdbInfoResp)
	resp.EdbInfoId = edbInfo.EdbInfoId
	resp.UniqueCode = edbInfo.UniqueCode
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
	br.IsAddLog = true
}

// EdbNameCheck
// @Title 批量加入指标库-重名校验
// @Description 批量加入指标库-重名校验
// @Success 200 {object} data_manage.EdbNameCheckResult
// @router /radish_research/edb/name_check [post]
func (this *BaseFromRadishResearchController) EdbNameCheck() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req []*data_manage.NameCheckEdbInfoReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	if len(req) == 0 {
		br.Msg = "请选择指标"
		return
	}
	codeMaxT := 30
	codeLen := len(req)
	if codeLen > codeMaxT {
		br.Msg = "批量添加指标数量不得超过30个"
		return
	}

	indexNames := make([]string, 0)
	resp := make([]*data_manage.EdbNameCheckResult, 0)
	nameCount := make(map[string]int)
	for _, v := range req {
		v.EdbCode = strings.TrimSpace(v.EdbCode)
		if v.EdbCode == "" {
			br.Msg = "指标ID不可为空"
			return
		}
		v.EdbName = strings.TrimSpace(v.EdbName)
		if v.EdbName == "" {
			br.Msg = "请输入指标名称"
			return
		}
		nameCount[v.EdbName] += 1

		indexNames = append(indexNames, v.EdbName)
		resp = append(resp, &data_manage.EdbNameCheckResult{
			EdbCode: v.EdbCode,
			EdbName: v.EdbName,
		})
	}
	// 本次提交的名称中也不允许重复
	for _, v := range resp {
		if nameCount[v.EdbName] > 1 {
			v.Exist = true
		}
	}

	// 重名校验
	edbList, e := data_manage.GetEdbInfoByNameArr(indexNames, utils.EDB_INFO_TYPE)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "获取重名指标失败, Err: " + e.Error()
		return
	}
	nameExists := make(map[string]bool)
	for _, v := range edbList {
		nameExists[v.EdbName] = true
	}
	if len(nameExists) > 0 {
		for _, v := range resp {
			v.Exist = nameExists[v.EdbName]
		}
	}

	br.Data = resp
	br.Msg = "校验成功"
	br.Ret = 200
	br.Success = true
}

// EdbMultiAdd
// @Title 批量加入指标库
// @Description 批量加入指标库
// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
// @Success 200 string "操作成功"
// @router /radish_research/edb/multi_add [post]
func (this *BaseFromRadishResearchController) EdbMultiAdd() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	deleteCache := true
	cacheKey := fmt.Sprintf("CACHE_EDB_INFO_BATCH_ADD_%d_%d", utils.DATA_SOURCE_RADISH_RESEARCH, sysUser.AdminId)
	defer func() {
		if deleteCache {
			_ = utils.Rc.Delete(cacheKey)
		}
	}()
	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
		deleteCache = false
		br.Msg = "系统处理中,请稍后重试!"
		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
		return
	}
	var req []*data_manage.AddEdbInfoReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	if len(req) == 0 {
		br.Msg = "请选择指标"
		return
	}
	if len(req) > 30 {
		br.Msg = "批量添加指标数量不得超过30个"
		return
	}
	for _, v := range req {
		v.EdbCode = strings.TrimSpace(v.EdbCode)
		if v.EdbCode == "" {
			br.Msg = "指标ID不可为空"
			return
		}
		v.EdbName = strings.TrimSpace(v.EdbName)
		if v.EdbName == "" {
			br.Msg = "请输入指标名称"
			return
		}
		v.Frequency = strings.TrimSpace(v.Frequency)
		if v.Frequency == "" {
			br.Msg = "请选择频度"
			return
		}
		v.Unit = strings.TrimSpace(v.Unit)
		if v.Unit == "" {
			br.Msg = "请输入单位"
			return
		}
		if v.ClassifyId <= 0 {
			br.Msg = "请选择分类"
			return
		}
	}

	// 限定同一时间最多批量新增30个指标
	var successCodes []string
	for _, v := range req {
		// 是否加入过指标库
		exist, e := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_RADISH_RESEARCH, v.EdbCode)
		if e != nil && !utils.IsErrNoRow(e) {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("校验是否加入过指标库失败, %v", e)
			return
		}
		if exist != nil && exist.EdbInfoId > 0 {
			// 加入过指标库这里直接忽略掉
			continue
		}

		// 指标入库
		edbInfo, err, errMsg, isSendEmail := data.EdbInfoAdd(utils.DATA_SOURCE_RADISH_RESEARCH, utils.DATA_SUB_SOURCE_EDB, v.ClassifyId, v.EdbCode, v.EdbName, v.Frequency, v.Unit, v.StartDate, v.EndDate, sysUser.AdminId, sysUser.RealName, this.Lang)
		if err != nil {
			br.Msg = "保存失败"
			if errMsg != `` {
				br.Msg = errMsg
			}
			br.ErrMsg = err.Error()
			br.IsSendEmail = isSendEmail
			return
		}
		successCodes = append(successCodes, v.EdbCode)

		// 刷新指标数据
		refreshRes, e := data.RefreshEdbData(edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, "")
		if e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("刷新指标数据失败, %v", e)
			return
		}
		if refreshRes != nil && refreshRes.Ret != 200 {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("刷新指标数据失败, Ret: %d, Msg: %s, ErrMsg: %s", refreshRes.Ret, refreshRes.Msg, refreshRes.ErrMsg)
			return
		}

		// 试用平台更新用户累计新增指标数
		if utils.BusinessCode == utils.BusinessCodeSandbox {
			go func() {
				adminItem, e := system.GetSysAdminById(sysUser.AdminId)
				if e != nil {
					tips := fmt.Sprintf("试用平台更新用户累计新增指标数-获取用户失败, Err: " + e.Error())
					utils.FileLog.Info(tips)
					return
				}
				if adminItem.DepartmentName != "ETA试用客户" {
					return
				}
				var ur etaTrialService.EtaTrialUserReq
				ur.Mobile = adminItem.Mobile
				_, _ = etaTrialService.UpdateUserIndexNum(ur)
			}()
		}

		// 新增操作日志
		{
			edbLog := new(data_manage.EdbInfoLog)
			edbLog.EdbInfoId = edbInfo.EdbInfoId
			edbLog.SourceName = edbInfo.SourceName
			edbLog.Source = edbInfo.Source
			edbLog.EdbCode = edbInfo.EdbCode
			edbLog.EdbName = edbInfo.EdbName
			edbLog.ClassifyId = edbInfo.ClassifyId
			edbLog.SysUserId = sysUser.AdminId
			edbLog.SysUserRealName = sysUser.RealName
			edbLog.CreateTime = time.Now()
			edbLog.Content = string(this.Ctx.Input.RequestBody)
			edbLog.Status = "新增指标"
			edbLog.Method = this.Ctx.Input.URI()
			go data_manage.AddEdbInfoLog(edbLog)
		}

		// 更新es
		go data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
	}

	// 更新指标EdbExist
	if len(successCodes) > 0 {
		indexOb := new(data_manage.BaseFromRadishResearchIndex)
		if e := indexOb.UpdateEdbExists(1, successCodes); e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = fmt.Sprintf("更新数据源EdbExist失败, %v", e)
			return
		}
	}

	br.Msg = "操作成功"
	br.Ret = 200
	br.Success = true
	br.IsAddLog = true
}