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"
)

// ChartPublicController 公共图表
type ChartPublicController struct {
	controllers.BaseAuthController
}

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

	if len(req.ChartInfoList) <= 0 {
		br.Msg = `请选择图表`
		br.IsSendEmail = false
		return
	}

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

	// 校验是否重复存在已公开、已提交的图表
	{
		chartInfoIdList := make([]int, 0)
		for _, item := range req.ChartInfoList {
			chartInfoIdList = append(chartInfoIdList, item.ChartInfoId)

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

		list, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
		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.DataApproveTypeChart)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "校验图表公开是否开启审批流失败, Err: " + e.Error()
		return
	}

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

	chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoList[0].ChartInfoId)
	if err != nil {
		br.Msg = "获取图表失败"
		br.ErrMsg = "获取图表失败:" + err.Error()
		return
	}
	title := chartInfo.ChartName
	if len(req.ChartInfoList) > 1 {
		title += `等图表`
	}
	title += `公开审批`

	// 没开启审批流、或者无需审批
	if !opening || isIgnoreApprove {
		err = dataApproveSerice.UpdatePublicByDataList(utils.DataApproveTypeChart, dataApproveSerice.DataApproveStatePass, dataPublicItemList)
	} else {
		_, err = dataApproveSerice.SubmitDataApprove(utils.DataApproveTypeChart, 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.EsAddOrEditChartInfo(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   ChartInfoId   query   int  true       "图表id"
// @Success 200 {object} data_manage.ChartInfo
// @router /chart_info/public/cancel [post]
func (c *ChartPublicController) 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
	}

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

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

	if len(req.ChartInfoList) <= 0 {
		br.Msg = `请选择图表`
		br.IsSendEmail = false
		return
	}

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

	// 校验是否重复存在已公开、已提交的图表
	{
		chartInfoIdList := make([]int, 0)
		for _, item := range req.ChartInfoList {
			chartInfoIdList = append(chartInfoIdList, item.ChartInfoId)

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

		list, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
		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
			}
		}
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
}

// ListByEs
// @Title 图表筛选接口
// @Description 图表筛选接口
// @Success 200 {object} data_manage.ChartInfoList
// @Param	request	body request.SearchPublicChartReq true "type json string"
// @Success 200 {object} data_manage.ChartInfoFilterDataResp
// @router /chart_info/public/list/es [post]
func (c *ChartPublicController) ListByEs() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	var req request.SearchPublicChartReq
	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, searchChartPublicList, sourceList, chartTypeList, chartClassifyIdList, publicClassifyIdList, chartAuth, sortMap := data.GetChartSearchPar(req)

	total, chartInfoList, err := elastic.SearchChartInfoDataByPublic(keyword, startSize, pageSize, searchChartPublicList, sourceList, chartTypeList, chartClassifyIdList, publicClassifyIdList, chartAuth, c.SysUser.AdminId, sortMap)
	if err != nil {
		chartInfoList = make([]*data_manage.ChartInfoView, 0)
	}

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

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

		tmpChartList, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取所有有权限的图表失败,Err:" + err.Error()
			return
		}
		chartInfoMap := make(map[int]*data_manage.ChartInfo)
		for _, v := range tmpChartList {
			chartInfoMap[v.ChartInfoId] = v
		}

		for _, v := range chartInfoList {
			tmpChartInfo, ok := chartInfoMap[v.ChartInfoId]
			if !ok {
				continue
			}
			v.IsJoinPermission = tmpChartInfo.IsJoinPermission
		}
	}

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

// AllListByEs
// @Title 图表筛选接口
// @Description 图表筛选接口
// @Success 200 {object} data_manage.ChartInfoList
// @Param	request	body request.SearchChartInfoShareReq true "type json string"
// @Success 200 {object} data_manage.ChartInfoFilterDataResp
// @router /chart_info/public/list/es/all [post]
func (c *ChartPublicController) AllListByEs() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

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

	// 选中的图表id列表
	chartInfoList := make([]*data_manage.ChartInfoView, 0)

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

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

			for _, v := range tmpChartInfoList {
				if _, ok := noChartIdMap[v.ChartInfoId]; !ok {
					// 如果不在未选中的图表id列表中,那么就加入到选中的图表id列表
					chartInfoList = append(chartInfoList, v)
				}
			}
		} else {
			chartInfoList = tmpChartInfoList
		}

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

			chartInfoIdList := make([]int, 0)
			for _, v := range chartInfoList {
				v.ConvertToResp()
				v.HaveOperaAuth = true
				chartInfoIdList = append(chartInfoIdList, v.ChartInfoId)
			}

			tmpChartList, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取所有有权限的图表失败,Err:" + err.Error()
				return
			}
			chartInfoMap := make(map[int]*data_manage.ChartInfo)
			for _, v := range tmpChartList {
				chartInfoMap[v.ChartInfoId] = v
			}

			for _, v := range chartInfoList {
				tmpChartInfo, ok := chartInfoMap[v.ChartInfoId]
				if !ok {
					continue
				}
				v.IsJoinPermission = tmpChartInfo.IsJoinPermission
			}
		}
	} else {
		// 因为是ES查找的,所以需要重新查一下图表的信息,主要是为了把是否授权字段找出来
		if len(req.ChartIdList) > 0 {
			chartInfoList, err = data_manage.GetChartInfoViewByIdList(req.ChartIdList)
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取所有有权限的图表失败,Err:" + err.Error()
				return
			}
		}
	}

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

// BatchMoveChart
// @Title 图表批量移动接口
// @Description 图表批量移动接口
// @Param	request	body request.MoveChartClassifyReq true "type json string"
// @Success Ret=200 移动成功
// @router /chart_info/public/batch_move [post]
func (c *ChartPublicController) BatchMoveChart() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	var req request.MoveChartClassifyReq
	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.ChartPublicClassify{}
	publicClassifyItem, err := obj.GetChartClassifyById(req.NewClassifyId)
	if err != nil {
		br.Msg = "获取公共分类失败!"
		br.ErrMsg = "获取公共分类失败!" + err.Error()
		return
	}
	if publicClassifyItem.ChartPublicClassifyId <= 0 {
		br.Msg = "公共分类不存在!"
		br.ErrMsg = "公共分类不存在!"
		return
	}

	chartInfoIdList := make([]int, 0)
	if req.IsSelectAll {
		// 获取图表
		chartInfoList, err := data.GetAllChartInfoListBySearchPublicChartReq(req.SearchPublicChartReq, c.SysUser.AdminId)
		if err != nil {
			br.Msg = "获取图表列表失败!"
			br.ErrMsg = "获取图表列表失败,Err:" + err.Error()
			return
		}
		// 如果有过滤图表,那么就过滤吧
		if len(req.NoChartIdList) > 0 {
			noChartIdMap := make(map[int]bool)
			for _, v := range req.NoChartIdList {
				noChartIdMap[v] = true
			}

			for _, chartInfo := range chartInfoList {
				if _, ok := noChartIdMap[chartInfo.ChartInfoId]; !ok {
					if chartInfo.PublicStatus != utils.DataPublicSuccess {
						br.Msg = `存在未公开的图表:` + chartInfo.ChartName
						br.IsSendEmail = false
						return
					}

					// 如果不在未选中的图表id列表中,那么就加入到选中的图表id列表
					chartInfoIdList = append(chartInfoIdList, chartInfo.ChartInfoId)
				}
			}
		} else {
			for _, chartInfo := range chartInfoList {
				if chartInfo.PublicStatus != utils.DataPublicSuccess {
					br.Msg = `存在未公开的图表:` + chartInfo.ChartName
					br.IsSendEmail = false
					return
				}
				chartInfoIdList = append(chartInfoIdList, chartInfo.ChartInfoId)
			}
		}
	} else {
		chartInfoList, err := data_manage.GetChartInfoViewByIdList(req.ChartIdList)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取所有有权限的图表失败,Err:" + err.Error()
			return
		}
		for _, v := range chartInfoList {
			if v.PublicStatus != utils.DataPublicSuccess {
				br.Msg = `存在未公开的图表:` + v.ChartName
				br.IsSendEmail = false
				return
			}
		}
		chartInfoIdList = req.ChartIdList
	}

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

	// 开始批量修改图表分类
	if len(chartInfoIdList) > 0 {
		err = data_manage.UpdatePublicClassifyIdByChartInfoIdList(chartInfoIdList, req.NewClassifyId)
		if err != nil {
			br.Msg = `图表移动失败!`
			br.ErrMsg = `图表移动失败,ERR:` + err.Error()
			return
		}
	}

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