package data_manage

import (
	"encoding/json"
	"eta_gn/eta_api/controllers"
	"eta_gn/eta_api/models"
	"eta_gn/eta_api/models/data_manage"
	"eta_gn/eta_api/models/data_manage/request"
	"eta_gn/eta_api/services/data"
	dataApproveSerice "eta_gn/eta_api/services/data/data_approve"
	"eta_gn/eta_api/services/elastic"
	"eta_gn/eta_api/utils"
	"github.com/rdlucklib/rdluck_tools/paging"
	"strconv"
	"strings"
)

// EdbPublicController 公共指标
type EdbPublicController struct {
	controllers.BaseAuthController
}

// RemoveCheck
// @Title 删除检测接口
// @Description 删除检测接口
// @Param	request	body data_manage.ClassifyDeleteCheckReq true "type json string"
// @Success 200 Ret=200 检测成功
// @router /edb_public/remove/check [post]
func (c *EdbPublicController) RemoveCheck() {
	// TODO
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()
	var req data_manage.ClassifyDeleteCheckReq
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}

	if req.ClassifyId < 0 && req.EdbInfoId <= 0 {
		br.Msg = "参数错误"
		br.IsSendEmail = false
		return
	}
	deleteStatus, tipsMsg, tableList, err, errMsg := data.DeleteEdbPublicCheck(req.EdbInfoId, c.SysUser)
	if errMsg != `` {
		br.Msg = errMsg
		br.ErrMsg = errMsg
		if err != nil {
			br.ErrMsg = err.Error()
		} else {
			br.IsSendEmail = false
		}
		return
	}
	if c.Lang == "en" {
		if utils.ViperConfig.InConfig(tipsMsg) {
			tipsMsg = utils.ViperConfig.GetString(tipsMsg)
		}
	}

	//var deleteStatus int
	//var tipsMsg string
	////删除公共分类
	//if req.ClassifyId > 0 && req.EdbInfoId == 0 {
	//	//判断公共分类下,是否含有指标
	//	count, err := data_manage.GetEdbInfoCountByClassifyId(req.ClassifyId)
	//	if err != nil {
	//		br.Msg = "删除失败"
	//		br.ErrMsg = "公共分类下是否含有指标失败,Err:" + err.Error()
	//		return
	//	}
	//
	//	if count > 0 {
	//		deleteStatus = 1
	//		tipsMsg = "若目录关联指标不可删除"
	//	}
	//}
	//
	//if deleteStatus != 1 && req.EdbInfoId == 0 {
	//	classifyCount, err := data_manage.GetClassifyCountByClassifyId(req.ClassifyId)
	//	if err != nil && !utils.IsErrNoRow(err) {
	//		br.Msg = "删除失败"
	//		br.ErrMsg = "公共分类下是否含有指标失败,Err:" + err.Error()
	//		return
	//	}
	//	if classifyCount > 0 {
	//		deleteStatus = 2
	//		tipsMsg = "确认删除当前目录及包含的子目录吗"
	//	}
	//}
	//
	////删除指标
	//if req.EdbInfoId > 0 {
	//	//判断指标是否用于作图,如果用于作图,则不可删除
	//	chartCount, err := data_manage.GetChartEdbMappingCount(req.EdbInfoId)
	//	if err != nil && !utils.IsErrNoRow(err) {
	//		br.Msg = "删除失败"
	//		br.ErrMsg = "判断指标是否被用于作图失败,Err:" + err.Error()
	//		return
	//	}
	//	if chartCount > 0 {
	//		deleteStatus = 3
	//		tipsMsg = "当前指标已用作画图,不可删除"
	//	}
	//	//判断指标是否用于计算
	//	{
	//		calculateCount, err := data_manage.GetEdbInfoCalculateMappingCount(req.EdbInfoId)
	//		if err != nil && !utils.IsErrNoRow(err) {
	//			br.Msg = "删除失败"
	//			br.ErrMsg = "判断指标是否被用于计算失败,GetEdbInfoCalculateCount Err:" + err.Error()
	//			return
	//		}
	//		if calculateCount > 0 {
	//			deleteStatus = 4
	//			tipsMsg = "当前指标已用作,指标运算,不可删除"
	//		}
	//	}
	//}

	resp := new(data_manage.ClassifyDeleteCheckResp)
	resp.DeleteStatus = deleteStatus
	resp.TipsMsg = tipsMsg
	resp.TableList = tableList
	br.Ret = 200
	br.Msg = "检测成功"
	br.Success = true
	br.Data = resp
}

// Remove
// @Title 删除公共分类/指标
// @Description 删除公共分类/指标接口
// @Param	request	body data_manage.DeleteEdbClassifyReq true "type json string"
// @Success 200 Ret=200 删除成功
// @router /edb_public/remove [post]
func (c *EdbPublicController) Remove() {
	// TODO
	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
	}
	var req data_manage.DeleteEdbClassifyReq
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}

	if req.ClassifyId < 0 && req.EdbInfoId <= 0 {
		br.Msg = "参数错误"
		br.IsSendEmail = false
		return
	}

	nextItem, _, err, errMsg := data.Delete(req.ClassifyId, req.EdbInfoId, sysUser, string(c.Ctx.Input.RequestBody), c.Ctx.Input.URI())
	if errMsg != `` {
		br.Msg = errMsg
		br.ErrMsg = errMsg
		if err != nil {
			br.ErrMsg = err.Error()
		} else {
			br.IsSendEmail = false
		}
		return
	}

	resp := data_manage.AddEdbInfoResp{}
	if nextItem != nil {
		resp = data_manage.AddEdbInfoResp{
			EdbInfoId:  nextItem.EdbInfoId,
			UniqueCode: nextItem.UniqueCode,
		}
	}

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

// Save
// @Title 单个指标设置公开
// @Description 单个指标设置公开
// @Param	request	body request.SetEdbInfoShareReq true "type json string"
// @Success 200 {object} data_manage.EdbInfo
// @router /edb_info/public/save [post]
func (c *EdbPublicController) Save() {
	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
	}
	var req request.SetEdbPublicReq
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}

	if len(req.EdbInfoList) <= 0 {
		br.Msg = `请选择指标`
		br.IsSendEmail = false
	}

	// 待处理的资产
	dataPublicItemList := make([]dataApproveSerice.SetDataPublicItem, 0)

	// 校验是否重复存在已公开、已提交的指标
	{
		edbInfoIdList := make([]int, 0)
		for _, item := range req.EdbInfoList {
			edbInfoIdList = append(edbInfoIdList, item.EdbInfoId)

			dataPublicItemList = append(dataPublicItemList, dataApproveSerice.SetDataPublicItem{
				DataId:     item.EdbInfoId,
				ClassifyId: item.ClassifyId,
			})
		}

		list, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
		if err != nil {
			br.Msg = "保存失败!"
			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
			return
		}
		for _, v := range list {
			if v.PublicStatus != utils.EdbPublicDefault {
				br.Msg = `选择指标中存在已经公开/提交审批的指标,请仅选择未公开指标!`
				br.IsSendEmail = false
				return
			}
		}
	}

	// 校验是否开启了审批流
	opening, e := dataApproveSerice.CheckOpenApprove(utils.DataApproveTypeEdb)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "校验指标公开是否开启审批流失败, Err: " + e.Error()
		return
	}

	// 是否忽略审批
	var isIgnoreApprove bool
	{
		businessConf, e := models.GetBusinessConfByKey(models.IgnoreEdbApproveUserId)
		if e != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取商家配置失败, Err: " + e.Error()
			return
		}
		ignoreEdbApproveUserIdList := strings.Split(businessConf.ConfVal, `,`)
		if utils.InArrayByStr(ignoreEdbApproveUserIdList, strconv.Itoa(c.SysUser.AdminId)) {
			isIgnoreApprove = true
		}
	}

	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoList[0].EdbInfoId)
	if err != nil {
		br.Msg = "获取指标失败"
		br.ErrMsg = "获取指标失败:" + err.Error()
		return
	}
	title := edbInfo.EdbName
	if len(req.EdbInfoList) > 1 {
		title += `等指标`
	}
	title += `公开审批`

	// 没开启审批流、或者无需审批
	if !opening || isIgnoreApprove {
		err = dataApproveSerice.UpdatePublicByDataList(utils.DataApproveTypeEdb, dataApproveSerice.DataApproveStatePass, dataPublicItemList)
	} else {
		_, err = dataApproveSerice.SubmitDataApprove(utils.DataApproveTypeEdb, dataPublicItemList, title, strings.TrimSpace(req.Description), c.SysUser.AdminId, c.SysUser.RealName)
		if err != nil {
			br.Msg = "提交审批失败"
			br.ErrMsg = "提交审批失败, Err: " + err.Error()
			return
		}

		// 更新ES
		for _, dataPublicItem := range dataPublicItemList {
			data.AddOrEditEdbInfoToEs(dataPublicItem.DataId)
		}
	}

	if err != nil {
		br.Msg = "编辑失败"
		br.ErrMsg = "编辑失败,Err:" + err.Error()
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
}

// Cancel
// @Title 撤销指标公开
// @Description 撤销指标公开
// @Param   EdbInfoId   query   int  true       "指标id"
// @Success 200 {object} data_manage.EdbInfo
// @router /edb_info/public/cancel [post]
func (c *EdbPublicController) Cancel() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	// TODO 单个指标撤销的时候,需要校验状态,然后撤销
	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	edbInfoId, _ := c.GetInt("EdbInfoId")
	if edbInfoId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误"
		return
	}

	var req request.SetEdbPublicReq
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}

	if len(req.EdbInfoList) <= 0 {
		br.Msg = `请选择指标`
		br.IsSendEmail = false
	}

	// 待处理的资产
	dataPublicItemList := make([]dataApproveSerice.SetDataPublicItem, 0)

	// 校验是否重复存在已公开、已提交的指标
	{
		edbInfoIdList := make([]int, 0)
		for _, item := range req.EdbInfoList {
			edbInfoIdList = append(edbInfoIdList, item.EdbInfoId)

			dataPublicItemList = append(dataPublicItemList, dataApproveSerice.SetDataPublicItem{
				DataId:     item.EdbInfoId,
				ClassifyId: item.ClassifyId,
			})
		}

		list, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
		if err != nil {
			br.Msg = "保存失败!"
			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
			return
		}
		for _, v := range list {
			if v.PublicStatus != utils.EdbPublicDefault {
				br.Msg = `选择指标中存在已经公开/提交审批的指标,请仅选择未公开指标!`
				br.IsSendEmail = false
				return
			}
		}
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
}

// ListByEs
// @Title 指标筛选接口
// @Description 指标筛选接口
// @Success 200 {object} data_manage.EdbInfoList
// @Param	request	body request.SearchPublicEdbReq true "type json string"
// @Success 200 {object} data_manage.EdbInfoFilterDataResp
// @router /edb_info/public/list/es [post]
func (c *EdbPublicController) ListByEs() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	var req request.SearchPublicEdbReq
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}

	pageSize := req.PageSize
	currentIndex := req.CurrentIndex

	var total int64

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

	// 获取查询参数
	keyword, searchEdbPublicList, sourceList, edbClassifyIdList, publicClassifyIdList, edbTypeList, edbInfoType, edbAuth, sortMap := data.GetSearchPar(req)

	total, edbInfoList, err := elastic.SearchEdbInfoDataByPublic(keyword, startSize, pageSize, searchEdbPublicList, sourceList, edbClassifyIdList, publicClassifyIdList, edbTypeList, edbInfoType, edbAuth, c.SysUser.AdminId, sortMap)
	if err != nil {
		edbInfoList = make([]*data_manage.EdbInfoList, 0)
	}

	page := paging.GetPaging(currentIndex, pageSize, int(total))

	edbInfoListLen := len(edbInfoList)

	// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
	if len(edbInfoList) > 0 {
		edbInfoIdList := make([]int, 0)
		for _, v := range edbInfoList {
			v.ConvertToResp()
			v.EdbNameAlias = v.EdbName
			v.HaveOperaAuth = true
			edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
		}

		tmpEdbList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
			return
		}
		edbInfoMap := make(map[int]*data_manage.EdbInfo)
		for _, v := range tmpEdbList {
			edbInfoMap[v.EdbInfoId] = v
		}

		for _, v := range edbInfoList {
			tmpEdbInfo, ok := edbInfoMap[v.EdbInfoId]
			if !ok {
				continue
			}
			v.IsJoinPermission = tmpEdbInfo.IsJoinPermission
		}
	}

	for i := 0; i < edbInfoListLen; i++ {
		for j := 0; j < edbInfoListLen; j++ {
			if (edbInfoList[i].EdbNameAlias == edbInfoList[j].EdbNameAlias) &&
				(edbInfoList[i].EdbInfoId != edbInfoList[j].EdbInfoId) &&
				!(strings.Contains(edbInfoList[i].EdbName, edbInfoList[i].SourceName)) {
				edbInfoList[i].EdbName = edbInfoList[i].EdbName + "(" + edbInfoList[i].SourceName + ")"
			}
		}
	}

	resp := data_manage.EdbInfoFilterDataResp{
		Paging: page,
		List:   edbInfoList,
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// AllListByEs
// @Title 指标筛选接口
// @Description 指标筛选接口
// @Success 200 {object} data_manage.EdbInfoList
// @Param	request	body request.SearchEdbInfoShareReq true "type json string"
// @Success 200 {object} data_manage.EdbInfoFilterDataResp
// @router /edb_info/public/list/es/all [post]
func (c *EdbPublicController) AllListByEs() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	var req request.AllSearchPublicEdbReq
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	// 选择所有指标,所以需要通过es获取数据

	// 选中的指标id列表
	edbInfoList := make([]*data_manage.EdbInfoList, 0)

	// 选择所有指标,所以需要通过es获取数据
	if req.IsSelectAll {
		tmpEdbInfoList, err := data.GetAllEdbInfoListBySearchPublicEdbReq(req.SearchPublicEdbReq, c.SysUser.AdminId)
		if err != nil {
			br.Msg = "获取指标列表失败!"
			br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
			return
		}

		// 如果有过滤指标,那么就过滤吧
		if len(req.NoEdbIdList) > 0 {
			noEdbIdMap := make(map[int]bool)
			for _, v := range req.NoEdbIdList {
				noEdbIdMap[v] = true
			}

			for _, v := range tmpEdbInfoList {
				if _, ok := noEdbIdMap[v.EdbInfoId]; !ok {
					// 如果不在未选中的指标id列表中,那么就加入到选中的指标id列表
					edbInfoList = append(edbInfoList, v)
				}
			}
		} else {
			edbInfoList = tmpEdbInfoList
		}

		// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
		if len(edbInfoList) > 0 {

			edbInfoIdList := make([]int, 0)
			for _, v := range edbInfoList {
				v.ConvertToResp()
				v.EdbNameAlias = v.EdbName
				v.HaveOperaAuth = true
				edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
			}

			tmpEdbList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
				return
			}
			edbInfoMap := make(map[int]*data_manage.EdbInfo)
			for _, v := range tmpEdbList {
				edbInfoMap[v.EdbInfoId] = v
			}

			for _, v := range edbInfoList {
				tmpEdbInfo, ok := edbInfoMap[v.EdbInfoId]
				if !ok {
					continue
				}
				v.IsJoinPermission = tmpEdbInfo.IsJoinPermission
			}
		}
	} else {
		// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
		if len(req.EdbIdList) > 0 {
			edbInfoList, err = data_manage.GetEdbInfoListByCond(` AND edb_info_id in (?) `, []interface{}{req.EdbIdList})
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
				return
			}
		}
	}

	edbInfoListLen := len(edbInfoList)

	for i := 0; i < edbInfoListLen; i++ {
		for j := 0; j < edbInfoListLen; j++ {
			if (edbInfoList[i].EdbNameAlias == edbInfoList[j].EdbNameAlias) &&
				(edbInfoList[i].EdbInfoId != edbInfoList[j].EdbInfoId) &&
				!(strings.Contains(edbInfoList[i].EdbName, edbInfoList[i].SourceName)) {
				edbInfoList[i].EdbName = edbInfoList[i].EdbName + "(" + edbInfoList[i].SourceName + ")"
			}
		}
	}

	resp := data_manage.EdbInfoFilterDataResp{
		List: edbInfoList,
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}