package data_manage

import (
	"encoding/json"
	"eta_gn/eta_api/cache"
	"eta_gn/eta_api/controllers"
	"eta_gn/eta_api/models"
	"eta_gn/eta_api/models/data_manage"
	"eta_gn/eta_api/models/data_manage/data_approve"
	"eta_gn/eta_api/models/data_manage/request"
	"eta_gn/eta_api/models/system"
	"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"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"strconv"
	"strings"
)

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

// 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
		return
	}

	// 待处理的资产
	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.DataPublicDefault {
				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()
	}()

	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

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

	edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
	if err != nil {
		br.Msg = "保存失败!"
		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
		return
	}

	// 判断指标公共状态
	if !utils.InArrayByInt([]int{utils.DataPublicSuccess, utils.DataPublicReject, utils.DataPublicCommit}, edbInfo.PublicStatus) {
		br.Msg = "保存失败,指标公开状态异常!"
		br.ErrMsg = "保存失败,指标公开状态异常,public_status:" + fmt.Sprint(edbInfo.PublicStatus)
		return
	}

	// 如果公开状态是:已驳回、已提交,那么直接去撤销审批单
	if utils.InArrayByInt([]int{utils.DataPublicReject, utils.DataPublicCommit}, edbInfo.PublicStatus) {
		obj := data_approve.DataApproveRelation{}
		dataApproveId, err := obj.GetDataApproveIdByDataId(edbInfoId, utils.DataApproveTypeEdb)
		if err != nil {
			br.Msg = "保存失败!"
			br.ErrMsg = "获取审批单失败,Err:" + err.Error()
			return
		}
		// 撤销审批
		msg, e := dataApproveSerice.DataApproveCancel(dataApproveId, sysUser.AdminId, sysUser.RealName)
		if e != nil {
			if msg != "" {
				br.Msg = msg
			} else {
				br.Msg = "操作失败"
			}
			br.ErrMsg = "撤销审批失败, Err: " + e.Error()
			return
		}
	}

	checkUserIdList := []int{sysUser.AdminId}

	// 已经分享的用户
	{
		obj := data_manage.EdbInfoShare{}
		userIdList, err := obj.GetAllUserIdListByEdbInfoId(edbInfo.EdbInfoId)
		if err != nil {
			br.Msg = "设置失败!"
			br.ErrMsg = "设置失败,Err:" + err.Error()
			return
		}
		if len(userIdList) > 0 {
			checkUserIdList = append(checkUserIdList, userIdList...)
		}
	}

	noReferenced, otherUserIdList, err, tips := data.CheckEdbReferencedByOthers(edbInfo.EdbInfoType, []int{edbInfo.EdbInfoId}, checkUserIdList)
	if err != nil {
		br.Msg = "保存失败"
		if tips != "" {
			br.Msg = tips
		}
		br.ErrMsg = "撤销指标公开失败,查找指标的关联用户失败,Err:" + err.Error()
		return
	}

	if !noReferenced {
		userNameStr := ``
		if len(otherUserIdList) > 0 {
			userNameList := make([]string, 0)
			userList, err := system.GetAdminListByIdList(otherUserIdList)
			if err != nil {
				br.Msg = "保存失败"
				if tips != "" {
					br.Msg = tips
				}
				br.ErrMsg = "撤销指标公开失败,查找用户信息失败,Err:" + err.Error()
				return
			}
			for _, userInfo := range userList {
				userNameList = append(userNameList, userInfo.RealName)
			}
			userNameStr = strings.Join(userNameList, ",")
		}
		msg := `指标被其他用户使用,无法撤销公开`
		if userNameStr != "" {
			msg = fmt.Sprintf(`指标被用户%s使用,无法撤销公开`, userNameStr)
		}
		if tips != "" {
			msg = fmt.Sprintf(`%s,用户为:%s,无法撤销公开`, tips, userNameStr)
		}
		br.Msg = msg
		br.ErrMsg = "指标被其他用户共享,无法撤销公开,EdbInfoId:" + strconv.Itoa(edbInfo.EdbInfoId)
		br.IsSendEmail = false
		return
	}

	edbInfo.PublicStatus = utils.DataPublicDefault
	edbInfo.EdbPublicClassifyId = 0
	err = edbInfo.Update([]string{"PublicStatus", "EdbPublicClassifyId"})
	if err != nil {
		br.Msg = "保存失败"
		br.ErrMsg = "取消指标公共失败,Err:" + err.Error()
		return
	}

	// 修改ES数据
	data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)

	// 指标收藏操作处理
	go cache.AddDataCollectHandler(edbInfo.EdbInfoId, utils.DataCollectTypeEdb)

	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 {
		// 图表map
		edbInfoMap := make(map[int]*data_manage.EdbInfo)
		classifyMap := make(map[int]*data_manage.EdbClassify)
		publicClassifyMap := make(map[int]*data_manage.EdbPublicClassify)

		// 指标id,分类id,公共分类id
		edbInfoIdList := make([]int, 0)
		tmpClassifyIdList := make([]int, 0)
		tmpPublicClassifyIdList := 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
			}
			for _, v := range tmpEdbList {
				edbInfoMap[v.EdbInfoId] = v
				tmpClassifyIdList = append(tmpClassifyIdList, v.ClassifyId)
				tmpPublicClassifyIdList = append(tmpPublicClassifyIdList, v.EdbPublicClassifyId)
			}
		}

		// 指标分类
		{
			tmpList, err := data_manage.GetEdbClassifyByIdList(tmpClassifyIdList)
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取所有有权限的图表分类失败,Err:" + err.Error()
				return
			}
			for _, v := range tmpList {
				classifyMap[v.ClassifyId] = v
			}
		}

		// 公共分类
		{
			obj := data_manage.EdbPublicClassify{}
			tmpList, err := obj.GetEdbClassifyByIdList(tmpPublicClassifyIdList)
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取所有有权限的公共分类失败,Err:" + err.Error()
				return
			}
			for _, v := range tmpList {
				publicClassifyMap[v.EdbPublicClassifyId] = v
			}
		}

		// 数据重新赋值
		for _, v := range edbInfoList {
			if tmpEdbInfo, ok := edbInfoMap[v.EdbInfoId]; ok {
				v.IsJoinPermission = tmpEdbInfo.IsJoinPermission
			}

			// 普通分类
			if classifyItem, ok := classifyMap[v.ClassifyId]; ok {
				v.ClassifyNamePath = classifyItem.ClassifyNamePath
			}

			// 公共分类
			if classifyItem, ok := publicClassifyMap[v.EdbPublicClassifyId]; ok {
				v.PublicClassifyNamePath = classifyItem.EdbPublicClassifyNamePath
			}
		}
	}

	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
}

// BatchMoveEdb
// @Title 指标批量移动接口
// @Description 指标批量移动接口
// @Param	request	body request.MoveEdbClassifyReq true "type json string"
// @Success Ret=200 移动成功
// @router /edb_info/public/batch_move [post]
func (c *EdbPublicController) BatchMoveEdb() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

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

	if req.NewClassifyId <= 0 {
		br.Msg = `请选择要转移的新分类`
		br.IsSendEmail = false
		return
	}

	// 校验分类
	obj := data_manage.EdbPublicClassify{}
	publicClassifyItem, err := obj.GetEdbClassifyById(req.NewClassifyId)
	if err != nil {
		br.Msg = "获取公共分类失败!"
		br.ErrMsg = "获取公共分类失败!" + err.Error()
		return
	}
	if publicClassifyItem.EdbPublicClassifyId <= 0 {
		br.Msg = "公共分类不存在!"
		br.ErrMsg = "公共分类不存在!"
		return
	}

	// 只是取公开
	req.SearchPublicEdbReq.EdbPublicList = []int{3}

	edbInfoIdList := make([]int, 0)
	if req.IsSelectAll {
		// 获取指标
		edbInfoList, 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 _, edbInfo := range edbInfoList {
				if _, ok := noEdbIdMap[edbInfo.EdbInfoId]; !ok {
					if edbInfo.PublicStatus != utils.DataPublicSuccess {
						br.Msg = `存在未公开的指标:` + edbInfo.EdbName
						br.IsSendEmail = false
						return
					}

					// 如果不在未选中的指标id列表中,那么就加入到选中的指标id列表
					edbInfoIdList = append(edbInfoIdList, edbInfo.EdbInfoId)
				}
			}
		} else {
			for _, edbInfo := range edbInfoList {
				if edbInfo.PublicStatus != utils.DataPublicSuccess {
					br.Msg = `存在未公开的指标:` + edbInfo.EdbName
					br.IsSendEmail = false
					return
				}
				edbInfoIdList = append(edbInfoIdList, edbInfo.EdbInfoId)
			}
		}
	} else {
		edbInfoList, err := data_manage.GetEdbInfoListByCond(` AND edb_info_id in (?) `, []interface{}{req.EdbIdList})
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
			return
		}
		for _, v := range edbInfoList {
			if v.PublicStatus != utils.DataPublicSuccess {
				br.Msg = `存在未公开的指标:` + v.EdbName
				br.IsSendEmail = false
				return
			}
		}
		edbInfoIdList = req.EdbIdList
	}

	num := len(edbInfoIdList)
	if num <= 0 {
		br.Msg = `请选择要移动的指标!`
		br.IsSendEmail = false
		return
	}
	if num > 100 {
		br.Msg = `最多只能选择100条指标!`
		br.IsSendEmail = false
		return
	}

	// 开始批量修改指标分类
	if len(edbInfoIdList) > 0 {
		err = data_manage.UpdatePublicClassifyIdByEdbInfoIdList(edbInfoIdList, req.NewClassifyId)
		if err != nil {
			br.Msg = `指标移动失败!`
			br.ErrMsg = `指标移动失败,ERR:` + err.Error()
			return
		}
		// 还得修改ES呢
		for _, v := range edbInfoIdList {
			data.AddOrEditEdbInfoToEs(v)
		}
	}

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