// Package data_manage
// @Author gmy 2024/8/12 14:31:00
package data_manage

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

// BaseFromRzdIndexController 睿姿得数据控制器
type BaseFromRzdIndexController struct {
	controllers.BaseAuthController
}

// RzdClassify
// @Title 睿姿得数据分类
// @Description 汾渭数据分类接口
// @Success 200 {object} data_manage.BaseFromRzdClassifyResponse
// @router /rzd/classify [get]
func (this *BaseFromRzdIndexController) RzdClassify() {
	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
	}

	classifies, e := data.RzdClassifyList()
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取睿姿得数据分类失败, Err: " + e.Error()
		return
	}

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

// RzdIndexData
// @Title 获取睿姿得数据
// @Description 获取睿姿得数据
// @Param   PageSize   query   int  true       "每页数据条数"
// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
// @Param   ClassifyId   query   string  true       "分类id"
// @Param   Frequency   query   string  true       "频率"
// @Success 200
// @router /rzd/index/data [get]
func (this *BaseFromRzdIndexController) RzdIndexData() {
	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
	}

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")
	var startSize int

	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = utils.StartIndex(currentIndex, pageSize)

	classifyId, _ := this.GetInt("ClassifyId")
	if classifyId < 0 {
		br.Msg = "请选择分类"
		br.ErrMsg = "请选择分类"
		return
	}
	frequency := this.GetString("Frequency")

	resultList, err := data.RzdIndexData(classifyId, frequency, currentIndex, startSize, pageSize)
	if err != nil {
		return
	}

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

// RzdIndexDetail
// @Title 获取睿姿得数据指标详情
// @Description 获取睿姿得数据指标详情
// @Param   IndexCode   query   string  true       "查询参数 指标id"
// @Success 200
// @router /rzd/index/detail [get]
func (this *BaseFromRzdIndexController) RzdIndexDetail() {
	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
	}

	indexCode := this.GetString("IndexCode")

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")
	var startSize int

	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = utils.StartIndex(currentIndex, pageSize)

	indexDetail, err := data.GetRzdIndexDetail(indexCode, currentIndex, startSize, pageSize)
	if err != nil {
		return
	}

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

// RzdIndexList
// @Title 获取睿姿得数据指标列表
// @Description 获取睿姿得数据指标详情
// @Param   searchParams   query   string  true       "查询参数 指标id/指标名称"
// @Success 200
// @router /rzd/index/list [get]
func (this *BaseFromRzdIndexController) RzdIndexList() {
	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
	}

	searchParams := this.GetString("SearchParams")

	indexList, err := data.GetRzdIndexList(searchParams)
	if err != nil {
		return
	}

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

// GetRzdFrequencyList
// @Title 查询频率列表
// @Description 查询频率列表
// @Param   classifyId   query  int  false   "指标唯一编码"
// @Success 200 {object} []string
// @router /rzd/frequency/list [get]
func (this *BaseFromRzdIndexController) GetRzdFrequencyList() {
	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")
	if classifyId < 0 {
		br.Msg = "请选择分类"
		br.ErrMsg = "请选择分类"
		return
	}
	frequencyList, err := data.GetRzdIndexFrequency(classifyId)
	if err != nil {
		return
	}

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

// RzdIndexAddValidate
// @Title 新增加入到指标库校验
// @Description 新增加入到指标库校验
// @Param   req    body   data_manage.BaseFromFenWeiIndexBatchAddCheckReq     true        "请求参数"
// @Success 200 {object} []data_manage.IndexCheckData
// @router /rzd/index/add/validate [post]
func (this *BaseFromRzdIndexController) RzdIndexAddValidate() {
	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.BaseFromRzdIndexBatchAddCheckReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}

	// 校验指标编码是否存在
	addValidate, err := data.RzdIndexAddValidate(req)
	if err != nil {
		br.Ret = 403
		br.Success = false
		br.Msg = err.Error()
		return
	}
	br.Data = addValidate
	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// RzdIndexAdd
// @Title 指标添加到指标库
// @Description 指标添加到指标库
// @Param   req    body   []data_manage.AddEdbInfoReq     true        "请求参数"
// @Success 200 string "操作成功"
// @router /rzd/index/add [post]
func (this *BaseFromRzdIndexController) RzdIndexAdd() {
	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 := "CACHE_EDB_INFO_BATCH_ADD_RZD_" + strconv.Itoa(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 = "批量添加指标数量不得超过" + strconv.Itoa(30) + "个"
		return
	}

	indexNames := make([]string, 0)
	resp := make([]*data_manage.RzdNameCheckResult, 0)
	for _, index := range req {
		index.EdbCode = strings.TrimSpace(index.EdbCode)
		if index.EdbCode == "" {
			br.Msg = "指标ID不可为空"
			return
		}
		index.EdbName = strings.TrimSpace(index.EdbName)
		if index.EdbName == "" {
			br.Msg = "请输入指标名称"
			return
		}
		index.Frequency = strings.TrimSpace(index.Frequency)
		if index.Frequency == "" {
			br.Msg = "请选择频度"
			return
		}
		index.Unit = strings.TrimSpace(index.Unit)
		if index.Unit == "" {
			br.Msg = "请输入单位"
			return
		}
		if index.ClassifyId <= 0 {
			br.Msg = "请选择分类"
			return
		}
		indexNames = append(indexNames, index.EdbName)
		resp = append(resp, &data_manage.RzdNameCheckResult{
			IndexCode: index.EdbCode,
			IndexName: index.EdbName,
			Exist:     false,
		})
	}

	// 指标名称重复校验
	nameCheck, err := data.RzdIndexNameCheck(indexNames, resp)
	if err != nil {
		br.Msg = err.Error()
		br.ErrMsg = err.Error()
		return
	}
	for _, v := range nameCheck {
		if v.Exist {
			br.Msg = "指标名称重复"
			br.Data = nameCheck
			br.Ret = 200
			br.Success = true
			return
		}
	}

	for _, v := range req {
		var rzdIndexAddReq data_manage.RzdIndexAddReq
		rzdIndexAddReq.EdbCode = v.EdbCode
		rzdIndexAddReq.EdbName = v.EdbName
		rzdIndexAddReq.Frequency = v.Frequency
		rzdIndexAddReq.Unit = v.Unit
		rzdIndexAddReq.ClassifyId = v.ClassifyId
		rzdIndexAddReq.AdminId = sysUser.AdminId
		rzdIndexAddReq.AdminRealName = sysUser.RealName

		// 新增指标到指标库
		edbInfo, e, errMsg, skip := data.RzdIndexAdd(rzdIndexAddReq, this.Lang)
		if e != nil {
			br.Msg = "操作失败"
			if errMsg != "" {
				br.Msg = errMsg
			}
			br.ErrMsg = e.Error()
			return
		}
		if skip {
			continue
		}

		// todo 下面两段代码能否抽离出来???
		// 试用平台更新用户累计新增指标数
		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)
		}
	}

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

// RzdIndexDataExport
// @Title 导出指标数据
// @Description 导出指标数据
// @Param  IndexCode     query   string     false        "指标编码"
// @Param  ClassifyId     query   int     false        "分类ID"
// @Success 200 string "操作成功"
// @router /rzd/index/data/export [get]
func (this *BaseFromRzdIndexController) RzdIndexDataExport() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请重新登录"
		return
	}

	classifyId, _ := this.GetInt("ClassifyId") //分类
	indexCode := this.GetString("IndexCode")   //指标唯一编码

	if classifyId <= 0 {
		br.Msg = "请选择分类"
		return
	}

	dir, _ := os.Executable()
	exPath := filepath.Dir(dir)

	downLoadFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
	xlsxFile := xlsx.NewFile()

	classifyIdList, err := data.RzdClassifyRecursiveQuery(classifyId)
	if err != nil {
		br.Msg = "查询分类失败"
		br.ErrMsg = "查询分类失败"
		return
	}
	classifyIdList = append(classifyIdList, classifyId)

	frequencies, err := data_manage.GetRzdIndexFrequency(classifyIdList)
	if err != nil {
		br.Msg = "查询频度失败"
		br.ErrMsg = "查询频度失败"
		return
	}

	fileName := `睿姿得数据`
	if classifyId > 0 && indexCode == "" {
		fenWeiClassify, err := data_manage.GetRzdClassifyItemByClassifyId(classifyId)
		if err != nil {
			return
		}
		fileName = fenWeiClassify.ClassifyName
	}
	if frequencies == nil {
		sheet, err := xlsxFile.AddSheet("无数据")
		if err != nil {
			br.Msg = "新增Sheet失败"
			br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
			return
		}
		rowSecName := sheet.AddRow()
		celSecName := rowSecName.AddCell()
		celSecName.SetValue("")
	}

	for _, frequency := range frequencies {
		fenWeiIndices, err := data_manage.GetRzdIndexByCodeAndClassify(indexCode, classifyIdList, frequency)
		if err != nil {
			return
		}
		var sheet *xlsx.Sheet
		if len(fenWeiIndices) > 0 {
			sheetName := *frequency
			if sheetName == "" {
				sheetName = "无频度"
			}
			sheet, err = xlsxFile.AddSheet(sheetName)
			if err != nil {
				br.Msg = "新增Sheet失败"
				br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
				return
			}
		} else {
			continue
		}

		if indexCode != "" {
			fileName = fenWeiIndices[0].IndexName
		}

		//获取指标数据
		rowSecName := sheet.AddRow()
		celSecName := rowSecName.AddCell()
		celSecName.SetValue("指标名称/Metric Nome")
		rowFrequency := sheet.AddRow()
		celFrequency := rowFrequency.AddCell()
		celFrequency.SetValue("频率/Frequency")
		rowUnit := sheet.AddRow()
		celUnit := rowUnit.AddCell()
		celUnit.SetValue("单位/Unit")
		rowModifyDate := sheet.AddRow()
		rowModifyCell := rowModifyDate.AddCell()
		rowModifyCell.SetValue("更新时间/Update Time")

		dataMap := make(map[string]map[string]*data_manage.BaseFromRzdData)
		var tradeCodeList []string
		for _, v := range fenWeiIndices {
			cellSenName := rowSecName.AddCell()
			cellSenName.SetValue(v.IndexName)
			celFrequency := rowFrequency.AddCell()
			celFrequency.SetValue(v.Frequency)
			celUnit := rowUnit.AddCell()
			celUnit.SetValue(v.Unit)
			rowModifyCell := rowModifyDate.AddCell()
			updateTimeStr := utils.FormatDateString(v.ModifyTime)
			rowModifyCell.SetValue(updateTimeStr)
			tradeCodeList = append(tradeCodeList, v.IndexCode)

			var dataList []*data_manage.BaseFromRzdData
			dataList, err = data_manage.GetBaseFormRzdDataByIndexCode(v.IndexCode)
			if err != nil && !utils.IsErrNoRow(err) {
				br.ErrMsg = "GetBaseFormRzdDataByIndexCode,Err:" + err.Error()
				br.Msg = "获取数据失败"
				return
			}
			for _, item := range dataList {
				if dataMap[item.IndexCode] == nil {
					dataMap[item.IndexCode] = make(map[string]*data_manage.BaseFromRzdData)
				}
				dataMap[item.IndexCode][item.DataTime] = item
			}
		}

		tradeCodeStr := strings.Join(tradeCodeList, "','")
		tradeCodeStr = "'" + tradeCodeStr + "'"
		dataTimeList, err := data_manage.GetRzdDataListByIndexCodes(tradeCodeStr)
		if err != nil {
			br.Msg = "获取数据失败"
			br.ErrMsg = "获取数据失败,Err:" + err.Error()
			return
		}
		for _, dataTime := range dataTimeList {
			rowData := sheet.AddRow()
			celDate := rowData.AddCell()
			celDate.SetValue(dataTime)

			for _, m := range fenWeiIndices {
				celData := rowData.AddCell()
				if dataMap[m.IndexCode][dataTime] != nil {
					celData.SetValue(dataMap[m.IndexCode][dataTime].Value)
				}
			}
		}
	}

	err = xlsxFile.Save(downLoadFilePath)
	if err != nil {
		//有指标无数据时先导出一遍空表
		sheet, err := xlsxFile.AddSheet("无数据")
		if err != nil {
			br.Msg = "新增Sheet失败"
			br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
			return
		}
		rowSecName := sheet.AddRow()
		celSecName := rowSecName.AddCell()
		celSecName.SetValue("")
		err = xlsxFile.Save(downLoadFilePath)
		if err != nil {
			br.Msg = "保存文件失败"
			br.ErrMsg = "保存文件失败"
			return
		}
	}

	fileName += time.Now().Format("06.01.02") + `.xlsx` //文件名称
	this.Ctx.Output.Download(downLoadFilePath, fileName)
	defer func() {
		os.Remove(downLoadFilePath)
	}()
	br.Ret = 200
	br.Success = true
	br.Msg = "success"
}

// GetRzdIndexInfo
// @Title 添加指标-根据条件获取指标信息
// @Description 添加指标-根据条件获取指标信息
// @Param   KeyWord   query   string  false       "关键字"
// @Param   ClassifyIds   query   string  false       "分类id"
// @Param   Frequencies   query   string  false       "频率"
// @Param   PageSize   query   int  false       "每页数据条数"
// @Param   CurrentIndex   query   int  false       "当前页页码,从1开始"
// @Success 200 {object} data_manage.BaseFromRzdIndexPage
// @router /rzd/get/index/info [get]
func (this *BaseFromRzdIndexController) GetRzdIndexInfo() {
	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
	}

	keyWord := this.GetString("KeyWord")
	classifyIds := this.GetString("ClassifyIds")
	frequencies := this.GetString("Frequencies")

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")
	var startSize int

	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = utils.StartIndex(currentIndex, pageSize)

	var classifyIdList []string
	var frequencyList []string
	if classifyIds != "" {
		classifyIdList = strings.Split(classifyIds, ",")
	}
	if frequencies != "" {
		frequencyList = strings.Split(frequencies, ",")
	}
	indexInfoPage, err := data.GetRzdIndexInfo(keyWord, classifyIdList, frequencyList, currentIndex, startSize, pageSize)
	if err != nil {
		return
	}

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