package controllers

import (
	"encoding/json"
	"eta/eta_index_lib/logic"
	"eta/eta_index_lib/models"
	"eta/eta_index_lib/services"
	"eta/eta_index_lib/utils"
	"fmt"
	"strconv"
	"strings"
	"time"
)

// BusinessIndexController 自有数据（商家）
type BusinessIndexController struct {
	BaseAuthController
}

// HandleBusinessIndexData
// @Title 处理外部指标（商家）的接口
// @Description 处理外部指标（商家）的接口
// @Success 200 {object} models.BaseFromBusinessIndexResp
// @router /handle [post]
func (c *BusinessIndexController) HandleBusinessIndexData() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()
	body := c.Ctx.Input.RequestBody
	var req models.AddBusinessIndexReq
	err := json.Unmarshal(body, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	// 如果没有传入指标编码的话，那么自动生成指标编码
	if req.IndexCode == `` {
		cacheKey := utils.CACHE_SELF_EDB_HANDLE
		if utils.Rc.IsExist(cacheKey) {
			br.Ret = 501
			br.Success = true
			br.Msg = "系统处理中，请稍后重试"
			return
		}

		// 刷新指标
		utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
		defer func() {
			_ = utils.Rc.Delete(cacheKey)
		}()
	}

	businessIndex, err := services.HandleBusinessIndex(&req)
	if err != nil {
		fmt.Println("HandleBusinessIndexData Err:" + err.Error())
		br.Msg = "处理失败"
		br.ErrMsg = "处理失败,Err:" + err.Error()
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "处理成功"
	br.Data = businessIndex
}

// DelIndex
// @Title 删除外部指标（商家）的接口
// @Description 删除外部指标（商家）的接口
// @Success 200 string "删除成功"
// @router /index/del [post]
func (c *BusinessIndexController) DelIndex() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()
	body := c.Ctx.Input.RequestBody
	var req models.DelBusinessIndexReq
	err := json.Unmarshal(body, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	// 如果没有传入指标编码的话，那么自动生成指标编码
	if len(req.IndexCodeList) < 0 {
		br.Msg = "指标编码不允许为空"
		return
	}

	joinEdbCodeList, needDelEdbCodeList, err, errMsg := services.DelBusinessIndex(req.IndexCodeList)
	if err != nil {
		br.Msg = errMsg
		br.ErrMsg = "删除失败,Err:" + err.Error()
		return
	}

	resp := services.DelBusinessIndexResp{
		IsDeleteEdbCodeList: needDelEdbCodeList,
		NoDeleteEdbCodeList: joinEdbCodeList,
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "删除成功"
	br.Data = resp
}

// DelIndexData
// @Title 删除外部指标（商家）的指定日期数据接口
// @Description 删除外部指标（商家）的指定日期数据接口
// @Success 200 string "删除成功"
// @router /data/del [post]
func (c *BusinessIndexController) DelIndexData() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()
	body := c.Ctx.Input.RequestBody
	var req models.DelBusinessIndexDataReq
	err := json.Unmarshal(body, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	// 如果没有传入指标编码的话，那么自动生成指标编码
	if req.IndexCode == `` {
		br.Msg = "指标编码不允许为空"
		return
	}
	if req.StartDate == `` && req.EndDate == `` {
		br.Msg = "开始日期和结束日期不允许同时为空"
		return
	}

	err, errMsg := services.DelBusinessIndexData(req.IndexCode, req.StartDate, req.EndDate)
	if err != nil {
		br.Msg = errMsg
		br.ErrMsg = "删除失败,Err:" + err.Error()
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "删除成功"
}

// Add
// @Title 新增自有数据（商家）指标接口
// @Description 新增自有数据（商家）指标接口
// @Success 200 {object} models.AddEdbBaseInfoReq
// @router /add [post]
func (c *BusinessIndexController) Add() {
	br := new(models.BaseResponse).Init()
	var cacheKey string
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()
	var req models.AddEdbBaseInfoReq
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.EdbCode == "" {
		br.Msg = "请输入指标编码！"
		br.ErrMsg = "请输入指标编码，指标编码为空"
		return
	}
	cacheKey = utils.CACHE_EDB_DATA_ADD + "_BusinessIndexController_" + req.EdbCode
	if utils.Rc.IsExist(cacheKey) {
		br.Ret = 501
		br.Success = true
		br.Msg = "系统处理中，请稍后重试"
		return
	}

	utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
	defer func() {
		_ = utils.Rc.Delete(cacheKey)
	}()

	baseFromBusinessIndexObj := models.BaseFromBusinessIndex{}

	businessIndexItem, err := baseFromBusinessIndexObj.GetIndexItem(req.EdbCode)
	if err != nil {
		br.Msg = "获取数据源中指标信息失败！"
		br.ErrMsg = "获取数据源中指标信息失败 baseFromBusinessIndexObj.GetIndexItem，Err:" + err.Error()
		return
	}

	// 添加指标
	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
	params := models.AddBaseParams{
		EdbCode:         req.EdbCode,
		EdbName:         req.EdbName,
		Unit:            req.Unit,
		ClassifyId:      req.ClassifyId,
		SysUserId:       req.SysUserId,
		SysUserRealName: req.SysUserRealName,
		UniqueCode:      uniqueCode,
	}
	obj := models.Business{}
	edbInfo, err, errMsg := obj.Add(params, businessIndexItem)
	if err != nil {
		br.Msg = "生成" + obj.GetSourceName() + "失败"
		if errMsg != `` {
			br.Msg = errMsg
		}
		br.ErrMsg = "生成" + obj.GetSourceName() + "失败 Err:" + err.Error()
		return
	}

	if edbInfo == nil {
		br.Msg = "生成" + obj.GetSourceName() + "失败2"
		br.ErrMsg = "生成" + obj.GetSourceName() + "失败"
		return
	}

	// 更新指标最大最小值
	err = obj.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo)
	if err != nil {
		br.Msg = "更新指标最大最小值失败"
		br.ErrMsg = err.Error()
		return
	}

	// 添加到es
	go logic.UpdateEs(edbInfo.EdbInfoId)

	resp := models.AddEdbInfoResp{
		EdbInfoId:  edbInfo.EdbInfoId,
		UniqueCode: edbInfo.UniqueCode,
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
	br.IsAddLog = true
}

// Edit
// @Title 编辑自有数据（商家）指标接口
// @Description 编辑自有数据（商家）指标接口
// @Success 200 {object} models.EditEdbBaseInfoReq
// @router /edit [post]
func (c *BusinessIndexController) Edit() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	var req models.EditEdbBaseInfoReq
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	cacheKey := utils.CACHE_EDB_DATA_EDIT + "_BusinessIndexController_" + fmt.Sprint(req.EdbInfoId)
	if utils.Rc.IsExist(cacheKey) {
		br.Ret = 501
		br.Success = true
		br.Msg = "系统处理中，请稍后重试"
		return
	}

	utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
	defer func() {
		_ = utils.Rc.Delete(cacheKey)
	}()

	if req.EdbInfoId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "指标ID：" + strconv.Itoa(req.EdbInfoId)
		br.IsSendEmail = false
		return
	}

	req.EdbName = strings.Trim(req.EdbName, " ")
	if req.EdbName == "" {
		br.Msg = "指标名称不能为空"
		br.IsSendEmail = false
		return
	}

	//if req.Frequency == "" {
	//	br.Msg = "频率不能为空"
	//	return
	//}

	if req.Unit == "" {
		br.Msg = "单位不能为空"
		br.IsSendEmail = false
		return
	}

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

	// 根据指标名称和指标ID校验库中是否还存在其他同名指标
	existEdbName, err := logic.CheckExistByEdbNameAndEdbInfoId(0, req.EdbInfoId, req.EdbName, c.Lang)
	if err != nil {
		br.Msg = "判断指标名称是否存在失败"
		br.ErrMsg = "判断指标名称是否存在失败,Err:" + err.Error()
		return
	}
	if existEdbName {
		br.Msg = "指标名称已存在，请重新填写"
		br.ErrMsg = "指标名称已存在，请重新填写"
		br.IsSendEmail = false
		return
	}

	//判断公式，指标是否有改动
	edbInfo, err := models.GetEdbInfoById(req.EdbInfoId)
	if err != nil {
		br.Msg = "修改失败"
		br.Msg = "获取指标信息失败,GetEdbInfoById Err:" + err.Error()
		return
	}
	if edbInfo == nil {
		br.Msg = "修改失败"
		br.Msg = "指标信息不存在，EdbInfoId:" + strconv.Itoa(req.EdbInfoId)
		return
	}

	baseFromBusinessIndexObj := models.BaseFromBusinessIndex{}

	businessIndexItem, err := baseFromBusinessIndexObj.GetIndexItem(edbInfo.EdbCode)
	if err != nil {
		br.Msg = "获取数据源中指标信息失败！"
		br.ErrMsg = "获取数据源中指标信息失败 baseFromBusinessIndexObj.GetIndexItem，Err:" + err.Error()
		return
	}

	// 额外赋值
	switch c.Lang {
	case utils.EnLangVersion:
		req.EdbNameEn = req.EdbName
		req.UnitEn = req.Unit

		req.EdbName = edbInfo.EdbName
		req.Unit = edbInfo.Unit
	default:
		req.EdbNameEn = edbInfo.EdbNameEn
		req.UnitEn = edbInfo.UnitEn
	}

	// 编辑指标
	params := models.EditBaseParams{
		EdbCode:         edbInfo.EdbCode,
		EdbName:         req.EdbName,
		Unit:            req.Unit,
		ClassifyId:      req.ClassifyId,
		SysUserId:       req.SysUserId,
		SysUserRealName: req.SysUserRealName,
		Lang:            c.Lang,
		EdbInfo:         edbInfo,
		EdbNameEn:       req.EdbNameEn,
		UnitEn:          req.UnitEn,
	}
	obj := models.Business{}
	err, errMsg := obj.Edit(params, businessIndexItem)
	if err != nil {
		br.Msg = "修改" + obj.GetSourceName() + "失败"
		if errMsg != `` {
			br.Msg = errMsg
		}
		br.ErrMsg = "修改" + obj.GetSourceName() + "失败 Err:" + err.Error()
		return
	}

	// 更新指标最大最小值
	err = obj.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo)
	if err != nil {
		br.Msg = "更新指标最大最小值失败"
		br.ErrMsg = err.Error()
		return
	}

	// 添加到es
	go logic.UpdateEs(edbInfo.EdbInfoId)

	resp := models.AddEdbInfoResp{
		EdbInfoId:  edbInfo.EdbInfoId,
		UniqueCode: edbInfo.UniqueCode,
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
	br.IsAddLog = true
}

// Refresh
// @Title 刷新计算指标接口
// @Description 刷新计算指标接口
// @Success 200 {object} models.RefreshEdbInfoReq
// @router /refresh [post]
func (c *BusinessIndexController) Refresh() {
	br := new(models.BaseResponse).Init()
	var cacheKey string
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()
	var req models.RefreshEdbInfoReq
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.EdbCode == "" {
		br.Msg = "请输入指标编码！"
		br.ErrMsg = "请输入指标编码，指标编码为空"
		return
	}
	if req.EdbInfoId <= 0 {
		br.Msg = "请输入指标ID！"
		br.ErrMsg = "请输入指标ID"
		return
	}
	edbInfo, err := models.GetEdbInfoById(req.EdbInfoId)
	if err != nil {
		br.Msg = "指标不存在！"
		br.ErrMsg = "指标不存在"
		return
	}

	cacheKey = utils.CACHE_EDB_DATA_REFRESH + strconv.Itoa(edbInfo.Source) + "_" + req.EdbCode

	if utils.Rc.IsExist(cacheKey) {
		br.Ret = 501
		br.Success = true
		br.Msg = "系统处理中，请稍后重试"
		return
	}

	// 刷新指标
	utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
	defer func() {
		_ = utils.Rc.Delete(cacheKey)
	}()

	params := models.RefreshBaseParams{
		EdbInfo:   edbInfo,
		StartDate: req.StartDate,
	}
	obj := models.Business{}

	err, errMsg := obj.Refresh(params)
	if errMsg != `` {
		br.Msg = "刷新指标失败！"
		br.ErrMsg = "刷新指标失败，err:" + errMsg
		return
	}
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "刷新指标信息失败！"
		br.ErrMsg = "刷新指标信息失败 BusinessIndexController，Err:" + err.Error()
		return
	}

	// 更新指标最大最小值
	err = obj.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo)
	if err != nil {
		br.Msg = "更新指标最大最小值失败"
		br.ErrMsg = err.Error()
		return
	}

	// 更新ES
	go logic.UpdateEs(edbInfo.EdbInfoId)

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