package excel

import (
	"encoding/json"
	"eta/eta_api/models"
	"eta/eta_api/models/data_manage"
	excelModel "eta/eta_api/models/data_manage/excel"
	"eta/eta_api/models/data_manage/excel/request"
	"eta/eta_api/services/data"
	"eta/eta_api/services/data/excel"
	"eta/eta_api/utils"
	"fmt"
	"strconv"
	"strings"
	"time"
)

// EdbList
// @Title 指标列表
// @Description 指标列表
// @Param   ExcelInfoId   query   int  true       "excel的id"
// @Param   Keyword   query   string  false	"指标关键词"
// @Success 200 {object} []excel.ExcelEdbMappingItem
// @router /edb/list [get]
func (c *CustomAnalysisController) EdbList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	excelInfoId, _ := c.GetInt("ExcelInfoId")
	if excelInfoId <= 0 {
		br.Msg = "请选择excel"
		br.IsSendEmail = false
		return
	}
	keyword := c.GetString("Keyword")
	keyword = strings.TrimSpace(keyword)
	if keyword != "" {
		keyword = fmt.Sprint("%", keyword, "%")
	}

	// 获取excel表详情
	excelInfo, err := excelModel.GetExcelInfoById(excelInfoId)
	if err != nil {
		br.Msg = "找不到该EXCEL!"
		br.ErrMsg = "找不到该EXCEL!err:" + err.Error()
		return
	}

	if excelInfo.Source != utils.CUSTOM_ANALYSIS_TABLE {
		br.Msg = "EXCEL异常!"
		br.IsSendEmail = false
		return
	}

	list, err := excelModel.GetExcelEdbMappingItemByExcelInfoIdOrKeyword(excelInfo.ExcelInfoId, keyword)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败,Err:" + err.Error()
		return
	}

	for k, v := range list {
		var tmpCalculateFormula excelModel.CalculateFormula
		err = json.Unmarshal([]byte(v.CalculateFormula), &tmpCalculateFormula)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "公式转换失败,Err:" + err.Error()
			return
		}
		v.DateSequenceStr = tmpCalculateFormula.DateSequenceStr
		v.DataSequenceStr = tmpCalculateFormula.DataSequenceStr
		list[k] = v
	}

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

// AddEdb
// @Title 新增指标接口
// @Description 新增指标接口
// @Param	request	body request.AddEdb true "type json string"
// @Success 200 {object} data_manage.AddEdbInfoResp
// @router /edb/add [post]
func (c *CustomAnalysisController) AddEdb() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	deleteCache := true
	cacheKey := "CACHE_EXCEL_TABLE_INFO_ADD_EDB_" + 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(c.Ctx.Input.RequestBody)
		return
	}
	var req request.AddEdb
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	req.EdbName = strings.Trim(req.EdbName, " ")
	if req.EdbName == "" {
		br.Msg = "请填写指标名称!"
		br.IsSendEmail = false
		return
	}

	if req.ExcelInfoId <= 0 {
		br.Msg = "请选择excel!"
		br.IsSendEmail = false
		return
	}

	if req.ClassifyId <= 0 {
		br.Msg = "请选择指标分类!"
		br.IsSendEmail = false
		return
	}

	excelInfo, err := excelModel.GetExcelInfoById(req.ExcelInfoId)
	if err != nil {
		br.Msg = "找不到该EXCEL!"
		br.ErrMsg = "找不到该EXCEL!err:" + err.Error()
		return
	}

	if excelInfo.Source != utils.CUSTOM_ANALYSIS_TABLE {
		br.Msg = "EXCEL异常!"
		br.IsSendEmail = false
		return
	}

	//excel.GetCustomAnalysisExcelData(excelInfo)

	dateList, dataList, err, errMsg := excel.HandleEdbSequenceVal(req.DateSequenceVal, req.DataSequenceVal)
	if err != nil {
		br.Msg = "时间序列或数据序列异常!"
		if errMsg != `` {
			br.Msg = errMsg
		}
		br.ErrMsg = "时间序列或数据序列处理异常!err:" + err.Error()
		return
	}

	type CustomAnalysisData struct {
		ExcelInfoId int `description:"excel的id"`
		DateList    []string
		DataList    []float64
	}

	type Formula struct {
		DateSequenceStr string `description:"日期序列"`
		DataSequenceStr string `description:"数据序列"`
	}

	formulaByte, err := json.Marshal(Formula{
		DateSequenceStr: req.DateSequenceStr,
		DataSequenceStr: req.DataSequenceStr,
	})
	if err != nil {
		br.Msg = "时间序列或数据序列配置异常!"
		br.ErrMsg = "json序列化时间序列或数据序列异常!err:" + err.Error()
		return
	}

	req2 := &data_manage.EdbInfoCalculateBatchSaveReqByEdbLib{
		AdminId:    sysUser.AdminId,
		AdminName:  sysUser.RealName,
		EdbName:    req.EdbName,
		Frequency:  req.Frequency,
		Unit:       req.Unit,
		ClassifyId: req.ClassifyId,
		Formula:    string(formulaByte), //公式
		Source:     utils.DATA_SOURCE_CALCULATE_ZDYFX,
		Data: CustomAnalysisData{
			ExcelInfoId: req.ExcelInfoId,
			DateList:    dateList,
			DataList:    dataList,
		},
	}

	// 调用指标库去更新
	reqJson, err := json.Marshal(req2)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	respItem, err := data.BatchSaveEdbCalculateData(string(reqJson), c.Lang)
	if err != nil {
		br.Msg = "新增失败"
		br.ErrMsg = "新增失败,Err:" + err.Error()
		return
	}
	if respItem.Ret != 200 {
		br.Msg = respItem.Msg
		br.ErrMsg = respItem.ErrMsg
		return
	}

	resp := respItem.Data

	//添加es
	data.AddOrEditEdbInfoToEs(resp.EdbInfoId)

	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
}

// EditEdb
// @Title 编辑指标接口
// @Description 编辑指标接口
// @Param	request	body request.EditEdb true "type json string"
// @Success 200 {object} data_manage.AddEdbInfoResp
// @router /edb/edit [post]
func (c *CustomAnalysisController) EditEdb() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	deleteCache := true
	cacheKey := "CACHE_EXCEL_TABLE_INFO_ADD_EDB_" + 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(c.Ctx.Input.RequestBody)
		return
	}
	var req request.EditEdb
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	req.EdbName = strings.Trim(req.EdbName, " ")
	if req.EdbName == "" {
		br.Msg = "请填写指标名称!"
		br.IsSendEmail = false
		return
	}

	if req.ExcelInfoId <= 0 {
		br.Msg = "请选择excel!"
		br.IsSendEmail = false
		return
	}

	if req.EdbInfoId <= 0 {
		br.Msg = "请选择指标!"
		br.IsSendEmail = false
		return
	}

	if req.ClassifyId <= 0 {
		br.Msg = "请选择指标分类!"
		br.IsSendEmail = false
		return
	}

	excelInfo, err := excelModel.GetExcelInfoById(req.ExcelInfoId)
	if err != nil {
		br.Msg = "找不到该EXCEL!"
		br.ErrMsg = "找不到该EXCEL!err:" + err.Error()
		return
	}

	if excelInfo.Source != utils.CUSTOM_ANALYSIS_TABLE {
		br.Msg = "EXCEL异常!"
		br.IsSendEmail = false
		return
	}

	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Msg = "指标已被删除,请刷新页面"
			br.ErrMsg = "指标已被删除,请刷新页面:Err:" + err.Error()
			return
		}
		br.Msg = "获取指标信息失败"
		br.ErrMsg = "获取指标信息失败:Err:" + err.Error()
		return
	}

	//excel.GetCustomAnalysisExcelData(excelInfo)

	dateList, dataList, err, errMsg := excel.HandleEdbSequenceVal(req.DateSequenceVal, req.DataSequenceVal)
	if err != nil {
		br.Msg = "时间序列或数据序列异常!"
		if errMsg != `` {
			br.Msg = errMsg
		}
		br.ErrMsg = "时间序列或数据序列处理异常!err:" + err.Error()
		return
	}

	type CustomAnalysisData struct {
		ExcelInfoId int `description:"excel的id"`
		DateList    []string
		DataList    []float64
	}

	type Formula struct {
		DateSequenceStr string `description:"日期序列"`
		DataSequenceStr string `description:"数据序列"`
	}

	formulaByte, err := json.Marshal(Formula{
		DateSequenceStr: req.DateSequenceStr,
		DataSequenceStr: req.DataSequenceStr,
	})
	if err != nil {
		br.Msg = "时间序列或数据序列配置异常!"
		br.ErrMsg = "json序列化时间序列或数据序列异常!err:" + err.Error()
		return
	}

	// 构造请求
	req2 := &data_manage.EdbInfoCalculateBatchEditReqByEdbLib{
		EdbInfoId:  req.EdbInfoId,
		EdbName:    req.EdbName,
		Frequency:  req.Frequency,
		Unit:       req.Unit,
		ClassifyId: req.ClassifyId,
		Formula:    string(formulaByte), //公式
		Source:     utils.DATA_SOURCE_CALCULATE_ZDYFX,
		Data: CustomAnalysisData{
			ExcelInfoId: req.ExcelInfoId,
			DateList:    dateList,
			DataList:    dataList,
		},
	}

	// 调用指标库去更新
	reqJson, err := json.Marshal(req2)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	respItem, err := data.BatchEditEdbCalculateData(string(reqJson), c.Lang)
	if err != nil {
		br.Msg = "编辑失败"
		br.ErrMsg = "编辑失败,Err:" + err.Error()
		return
	}
	if respItem.Ret != 200 {
		br.Msg = respItem.Msg
		br.ErrMsg = respItem.ErrMsg
		return
	}

	resp := respItem.Data

	//添加es
	data.AddOrEditEdbInfoToEs(resp.EdbInfoId)

	// 修改关联的预测指标基础信息
	go data.ModifyPredictEdbBaseInfoBySourceEdb(edbInfo, req.Frequency, req.Unit)

	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
}

// EdbRefresh
// @Title 指标列表
// @Description 指标列表
// @Param   ExcelInfoId   query   int  true       "excel的id"
// @Success 200 {object} []excel.ExcelEdbMappingItem
// @router /edb/refresh [get]
func (c *CustomAnalysisController) EdbRefresh() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()
	excelInfoId, _ := c.GetInt("ExcelInfoId")
	if excelInfoId <= 0 {
		br.Msg = "请选择excel"
		br.IsSendEmail = false
		return
	}
	cacheKey := "CACHE_EXCEL_EDB_REFRESH_" + strconv.Itoa(c.SysUser.AdminId)
	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
		br.Msg = "系统处理中,请稍后重试!"
		br.ErrMsg = "系统处理中,请稍后重试!" + c.SysUser.RealName + ";data:" + string(c.Ctx.Input.RequestBody)
		return
	}
	defer func() {
		_ = utils.Rc.Delete(cacheKey)
	}()

	// 获取excel表详情
	excelInfo, err := excelModel.GetExcelInfoById(excelInfoId)
	if err != nil {
		br.Msg = "找不到该EXCEL!"
		br.ErrMsg = "找不到该EXCEL!err:" + err.Error()
		return
	}

	if excelInfo.Source != utils.CUSTOM_ANALYSIS_TABLE {
		br.Msg = "EXCEL异常!"
		br.IsSendEmail = false
		return
	}

	err, errMsg, isSendEmail := excel.Refresh(excelInfo, c.Lang)
	if err != nil {
		br.Msg = "刷新失败"
		if errMsg != `` {
			br.Msg = errMsg
		}
		br.ErrMsg = "刷新失败,Err:" + err.Error()
		br.IsSendEmail = isSendEmail
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "刷新成功"
}

//func init() {
//	excelInfo, err := excelModel.GetExcelInfoById(160)
//	if err != nil {
//		fmt.Println("查找excel失败:", err)
//		return
//	}
//	_, err, _ = excel.GenerateExcelCustomAnalysisExcel(excelInfo)
//	if err != nil {
//		fmt.Println("生成excel失败:", err)
//		return
//	}
//}