package knowledge

import (
	"encoding/json"
	"eta_gn/eta_api/controllers"
	"eta_gn/eta_api/models"
	"eta_gn/eta_api/models/knowledge"
	knowledgeServ "eta_gn/eta_api/services/knowledge"
	"eta_gn/eta_api/utils"
	"fmt"
)

// 分类
type ClassifyController struct {
	controllers.BaseAuthController
}

// @Title 新增分类接口
// @Description 新增分类
// @Param	request	body knowledge.ClassifyAddReq true "type json string"
// @Success 200 新增成功
// @router /classify/add [post]
func (this *ClassifyController) Add() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req knowledge.ClassifyAddReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}

	if req.ClassifyName == "" {
		br.Msg = "分类名称不可为空"
		return
	}

	// 新增分类
	err, errMsg, isSentEmail := knowledgeServ.AddKnowledgeClassify(req.ClassifyName, req.ParentId, req.ResourceType)
	if err != nil {
		br.Msg = "添加失败"
		if errMsg != "" {
			br.Msg = errMsg
		}
		br.ErrMsg = "添加失败,Err:" + err.Error()
		br.IsSendEmail = isSentEmail
		return
	}

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

// CheckDeleteClassify
// @Title 删除分类-检测接口
// @Description 删除分类-信息检测,是否符合删除条件
// @Param   ClassifyId   query   int  true       "分类ID"
// @Success 200 {object} knowledge.CheckDeleteClassifyResp
// @router /classify/checkDelete [get]
func (this *ClassifyController) CheckDeleteClassify() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	classifyId, err := this.GetInt("ClassifyId")
	if classifyId <= 0 {
		br.Msg = "参数错误"
		return
	}
	resourceType, _ := this.GetInt("ResourceType")

	knowledgeObj := new(knowledge.KnowledgeClassify)
	classify, err := knowledgeObj.GetClassifyById(classifyId)
	if err != nil {
		br.Msg = "获取信息失败"
		br.ErrMsg = "获取信息失败,Err:" + err.Error()
		return
	}
	if classify.ResourceType != resourceType {
		br.Msg = "分类类型错误"
		return
	}
	resp := new(knowledge.CheckDeleteClassifyResp)
	if classify == nil {
		br.Msg = "分类不存在"
		resp.Code = 1
		resp.Msg = "分类不存在"
		br.Data = resp
		br.Ret = 200
		br.Success = true
		return
	}

	count, err := knowledgeObj.GetResourceCountByClassifyId(classifyId)
	if err != nil {
		br.Msg = "获取信息失败"
		br.ErrMsg = "获取信息失败,Err:" + err.Error()
		return
	}
	if count > 0 {
		resp.Code = 2
		resp.Msg = "该分类有关联事件,不允许删除"
		br.Data = resp
		br.Ret = 200
		br.Msg = "该分类有关联事件,不允许删除"
		br.Success = true
		return
	}
	// 查询所有子分类
	classifyIds, e := knowledgeObj.GetChildClassifyIdByParentId(classifyId)
	if e != nil && !utils.IsErrNoRow(e) {
		br.Msg = "获取失败"
		br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error()
		return
	}
	if len(classifyIds) > 0 {
		condition := fmt.Sprintf(` AND classify_id IN (?) `)
		var pars []interface{}
		pars = append(pars, classifyIds)
		childCount, err := knowledge.GetKnowledgeResourceListCount(condition, pars)
		if err != nil && !utils.IsErrNoRow(err) {
			br.Msg = "删除失败"
			br.ErrMsg = "查询分类下表格数量失败,Err:" + err.Error()
			return
		}

		if childCount > 0 {
			resp.Code = 3
			resp.Msg = "子分类有关联事件,不允许删除"
			br.Data = resp
			br.Ret = 200
			br.Msg = "子分类有关联事件,不允许删除"
			br.Success = true
			return
		}
		// 查询三级分类下是否有事件,如果有也不允许删除
		classifyIds, e = knowledgeObj.GetChildClassifyIdByParentIds(classifyIds)
		if e != nil && !utils.IsErrNoRow(e) {
			br.Msg = "获取失败"
			br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error()
			return
		}
		if len(classifyIds) > 0 {
			condition = fmt.Sprintf(` AND classify_id IN (?) `)
			pars = make([]interface{}, 0)
			pars = append(pars, classifyIds)
			childCount, e = knowledge.GetKnowledgeResourceListCount(condition, pars)
			if e != nil && !utils.IsErrNoRow(e) {
				br.Msg = "删除失败"
				br.ErrMsg = "查询分类下表格数量失败,Err:" + e.Error()
				return
			}
			if childCount > 0 {
				resp.Code = 3
				resp.Msg = "子分类有关联事件,不允许删除"
				br.Data = resp
				br.Ret = 200
				br.Msg = "子分类有关联事件,不允许删除"
				br.Success = true
				return
			}
		}
	}

	resp.Code = 0
	resp.Msg = "检测完成,可进行删除操作"
	br.Ret = 200
	br.Data = resp
	br.Success = true
	br.Msg = "检测成功"
}

// @Title 删除分类接口
// @Description 删除分类
// @Param	request	body knowledge.DeleteClassifyReq true "type json string"
// @Success 200 Ret=200,删除成功
// @router /classify/delete [post]
func (this *ClassifyController) Delete() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req knowledge.DeleteClassifyReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.ClassifyId <= 0 {
		br.Msg = "参数错误"
		return
	}
	//todo 是否需要删除
	knowledgeObj := new(knowledge.KnowledgeClassify)
	classifyId := req.ClassifyId
	deleteClassifyIds := make([]int, 0)
	deleteClassifyIds = append(deleteClassifyIds, classifyId)
	classify, err := knowledgeObj.GetClassifyById(req.ClassifyId)
	if err != nil {
		if utils.IsErrNoRow(err) {
			br.Msg = "分类不存在"
			return
		}
		br.Msg = "获取信息失败"
		br.ErrMsg = "获取信息失败,Err:" + err.Error()
		return
	}
	if classify.ResourceType != req.ResourceType {
		br.Msg = "资源类型不匹配"
		return
	}
	count, err := knowledgeObj.GetResourceCountByClassifyId(classifyId)
	if err != nil {
		br.Msg = "获取信息失败"
		br.ErrMsg = "获取信息失败,Err:" + err.Error()
		return
	}
	if count > 0 {
		br.Msg = "该分类有关联事件,不允许删除"
		return
	}
	// 查询所有子分类
	classifyIds, e := knowledgeObj.GetChildClassifyIdByParentId(classifyId)
	if e != nil && !utils.IsErrNoRow(e) {
		br.Msg = "获取失败"
		br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error()
		return
	}
	if len(classifyIds) > 0 {
		condition := fmt.Sprintf(` AND classify_id IN (?) `)
		var pars []interface{}
		pars = append(pars, classifyIds)
		childCount, err := knowledge.GetKnowledgeResourceListCount(condition, pars)
		if err != nil && !utils.IsErrNoRow(err) {
			br.Msg = "删除失败"
			br.ErrMsg = "查询分类下表格数量失败,Err:" + err.Error()
			return
		}

		if childCount > 0 {
			br.Msg = "子分类有关联事件,不允许删除"
			return
		}
		deleteClassifyIds = append(deleteClassifyIds, classifyIds...)
		// 查询三级分类下是否有事件,如果有也不允许删除
		classifyIds, e = knowledgeObj.GetChildClassifyIdByParentIds(classifyIds)
		if e != nil && !utils.IsErrNoRow(e) {
			br.Msg = "获取失败"
			br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error()
			return
		}
		if len(classifyIds) > 0 {
			condition = fmt.Sprintf(` AND classify_id IN (?) `)
			pars = make([]interface{}, 0)
			pars = append(pars, classifyIds)
			childCount, e = knowledge.GetKnowledgeResourceListCount(condition, pars)
			if e != nil && !utils.IsErrNoRow(e) {
				br.Msg = "删除失败"
				br.ErrMsg = "查询分类下表格数量失败,Err:" + e.Error()
				return
			}
			if childCount > 0 {
				br.Msg = "子分类有关联事件,不允许删除"
				return
			}
			deleteClassifyIds = append(deleteClassifyIds, classifyIds...)
		}
	}

	err = knowledgeObj.DeleteByIds(deleteClassifyIds)
	if err != nil {
		br.Msg = "删除失败"
		br.ErrMsg = "删除失败,Err:" + err.Error()
		return
	}
	// 获取父级分类下的子分类数量
	/*	if item.ParentId > 0 {
		childClassifyCount, err := knowledgeObj.GetCountClassifyChildByParentId(req.ClassifyId)
		if err != nil {
			br.Msg = "获取父级分类的子分类信息失败"
			br.ErrMsg = "获取父级分类的子分类信息失败,Err:" + err.Error()
			return
		}
		if childClassifyCount <= 0 {
			parentClassifyItem, err := knowledgeObj.GetClassifyById(item.ParentId)
			if err != nil {
				br.Msg = "获取父级分类信息失败"
				br.ErrMsg = "获取父级分类信息失败,Err:" + err.Error()
				return
			}
			parentClassifyItem.HasChild = 0
			err = parentClassifyItem.Update([]string{"HasChild"})
			if err != nil {
				br.Msg = "更新父级分类信息失败"
				br.ErrMsg = "更新父级分类信息失败,Err:" + err.Error()
				return
			}
		}
	}*/

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

// @Title 修改分类接口
// @Description 修改分类
// @Param	request	body knowledge.EditClassifyReq true "type json string"
// @Success 200 Ret=200,修改成功
// @router /classify/edit [post]
func (this *ClassifyController) Edit() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req knowledge.EditClassifyReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}

	if req.ClassifyId <= 0 {
		br.Msg = "参数错误"
		return
	}
	if req.ClassifyName == "" {
		br.Msg = "分类名称不可为空"
		return
	}

	// 修改分类
	err, errMsg, isSentEmail := knowledgeServ.EditKnowledgeClassify(req.ClassifyId, req.ParentId, req.ClassifyName, req.ResourceType)
	if err != nil {
		br.Msg = "修改失败"
		if errMsg != "" {
			br.Msg = errMsg
		}
		br.ErrMsg = "修改失败,Err:" + err.Error()
		br.IsSendEmail = isSentEmail
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "修改成功"
}

// ParentClassify
// @Title 获取父级分类接口
// @Description 获取父级分类
// @Success 200 {object} knowledge.Classify
// @router /classify/parent [get]
func (this *ClassifyController) ParentClassify() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	resourceType, _ := this.GetInt("ResourceType")
	knowledgeObj := new(knowledge.KnowledgeClassify)
	items, err := knowledgeObj.GetAllClassify(resourceType)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}

	classifyIds := make([]int, 0)
	for i := range items {
		classifyIds = append(classifyIds, items[i].ClassifyId)
	}
	classifyLen := len(classifyIds)
	if classifyLen == 0 {
		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		return
	}

	resp := make([]*knowledge.KnowledgeClassifyItem, 0)
	for i := range items {
		resp = append(resp, &knowledge.KnowledgeClassifyItem{
			KnowledgeClassify: *items[i],
		})
	}

	resp = knowledgeServ.GetClassifyTreeRecursive(resp, 0)

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

// @Title 根据id获取分类详情接口
// @Description 根据id获取分类详情
// @Param	request	body knowledge.FindByIdClassifyReq true "type json string"
// @Success 200 {object} knowledge.Classify
// @router /classify/findById [get]
func (this *ClassifyController) FindByIdClassify() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req knowledge.FindByIdClassifyReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	knowledgeObj := new(knowledge.KnowledgeClassify)
	items, err := knowledgeObj.GetClassifyById(req.ClassifyId)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}
	br.Data = items
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// @Title 获取分类列表
// @Description 获取分类列表
// @Param   KeyWord   query   string  true       "检索关键词"
// @Param   CompanyType   query   string  false       "产品类型,枚举值:'ficc','权益';不传默认返回全部"
// @Param   HideDayWeek   query   int  false       "是否隐藏晨周报"
// @Success 200 {object} knowledge.Classify
// @router /classify/list [get]
func (this *ClassifyController) ListClassify() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	keyWord := this.GetString("Keyword")
	resourceType, _ := this.GetInt("ResourceType", 0)
	knowledgeObj := new(knowledge.KnowledgeClassify)
	list, err := knowledgeObj.GetClassifyListByKeyword(keyWord, resourceType)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}

	if keyWord != `` {
		idMap := make(map[int]bool)

		currParentClassifyIdList := make([]int, 0)
		for _, v := range list {
			idMap[v.ClassifyId] = true
			if v.ParentId > 0 {
				currParentClassifyIdList = append(currParentClassifyIdList, v.ParentId)
			}
		}

		findList := list
		list = make([]*knowledge.KnowledgeClassifyItem, 0)

		tmpList, tmpErr := knowledgeServ.GetParentClassifyListByParentIdList(currParentClassifyIdList)
		if tmpErr != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取上级分类信息失败,Err:" + tmpErr.Error()
			return
		}
		for _, v := range tmpList {
			if _, ok := idMap[v.ClassifyId]; !ok {
				list = append(list, v)
			}
		}

		list = append(list, findList...)
	}

	classifyIdList := make([]int, 0)
	for i := range list {
		classifyIdList = append(classifyIdList, list[i].ClassifyId)
	}
	parentIdLen := len(classifyIdList)
	if parentIdLen == 0 {
		resp := &knowledge.KnowledgeClassifyListResp{
			List: list,
		}
		br.Data = resp
		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		return
	}

	// 先将分类列表排序
	knowledgeServ.SortClassifyListBySortAndCreateTime(list)
	// 接着转换结构
	list = knowledgeServ.GetClassifyListTreeRecursive(list, 0)

	resp := new(knowledge.KnowledgeClassifyListResp)
	resp.List = list
	br.Data = resp
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// Move
// @Title 移动分类接口
// @Description 移动分类
// @Param	request	body knowledge.ClassifyMoveReq true "type json string"
// @Success 200 新增成功
// @router /classify/move [post]
func (this *ClassifyController) Move() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req knowledge.ClassifyMoveReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.ClassifyId <= 0 {
		br.Msg = "请选择分类"
		return
	}
	e, msg := knowledgeServ.MoveKnowledgeClassify(req)
	if e != nil {
		br.Msg = msg
		br.ErrMsg = "移动分类失败, Err: " + e.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}