package services

import (
	"eta/eta_api/models"
	"eta/eta_api/utils"
	"fmt"
	"time"
)

// MoveReportClassify 移动分类
func MoveReportClassify(req models.ClassifyMoveReq) (err error, errMsg string) {
	classifyId := req.ClassifyId
	prevClassifyId := req.PrevClassifyId
	nextClassifyId := req.NextClassifyId

	//如果有传入 上一个兄弟节点分类id
	var (
		classifyInfo *models.Classify
		prevClassify *models.Classify
		nextClassify *models.Classify

		prevSort int
		nextSort int
	)

	// 移动对象为分类， 判断权限
	classifyInfo, err = models.GetClassifyById(classifyId)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			errMsg = "分类不存在, 请刷新页面"
			err = fmt.Errorf("获取分类信息失败,Err:" + err.Error())
			return
		}
		errMsg = "移动失败"
		err = fmt.Errorf("获取分类信息失败,Err:" + err.Error())
		return
	} else if classifyInfo.Id == 0 {
		errMsg = "分类不存在, 请刷新页面"
		err = fmt.Errorf("获取分类信息失败,Err:" + err.Error())
		return
	}

	parentClassifyId := classifyInfo.ParentId
	if prevClassifyId > 0 {
		prevClassify, err = models.GetClassifyById(prevClassifyId)
		if err != nil {
			if err.Error() == utils.ErrNoRow() {
				errMsg = "上一个分类不存在, 请刷新页面"
				err = fmt.Errorf("获取分类信息失败,Err:" + err.Error())
				return
			}
			errMsg = "移动失败"
			err = fmt.Errorf("获取上一个兄弟节点分类信息失败,Err:" + err.Error())
			return
		}
		if prevClassify.ParentId != parentClassifyId {
			errMsg = "禁止拖动到其他节点"
			err = fmt.Errorf(errMsg)
			return
		}
		prevSort = prevClassify.Sort
	}

	if nextClassifyId > 0 {
		//下一个兄弟节点
		nextClassify, err = models.GetClassifyById(nextClassifyId)
		if err != nil {
			if err.Error() == utils.ErrNoRow() {
				errMsg = "下一个分类不存在, 请刷新页面"
				err = fmt.Errorf("获取分类信息失败,Err:" + err.Error())
				return
			}
			errMsg = "移动失败"
			err = fmt.Errorf("获取下一个兄弟节点分类信息失败,Err:" + err.Error())
			return
		}
		if nextClassify.ParentId != parentClassifyId {
			errMsg = "禁止拖动到其他节点"
			err = fmt.Errorf(errMsg)
			return
		}
		nextSort = nextClassify.Sort
	}

	err, errMsg = moveReportClassify(classifyInfo, prevClassify, nextClassify, parentClassifyId, prevSort, nextSort)
	return
}

// moveReportClassify 移动分类
func moveReportClassify(classifyInfo, prevClassify, nextClassify *models.Classify, parentId, prevSort, nextSort int) (err error, errMsg string) {
	ob := new(models.Classify)
	updateCol := make([]string, 0)

	//判断上级id是否一致，如果不一致的话，那么需要移动该分类层级
	if classifyInfo.ParentId != parentId {
		errMsg = "移动失败"
		err = fmt.Errorf("不支持目录层级变更")
		return
	}

	if prevSort > 0 {
		//如果是移动在两个兄弟节点之间
		if nextSort > 0 {
			//下一个兄弟节点
			//如果上一个兄弟与下一个兄弟的排序权重是一致的，那么需要将下一个兄弟（以及下个兄弟的同样排序权重）的排序权重+2，自己变成上一个兄弟的排序权重+1
			if prevSort == nextSort || prevSort == classifyInfo.Sort {
				//变更兄弟节点的排序
				updateSortStr := `sort + 2`

				//变更分类
				if prevClassify != nil {
					_ = models.UpdateClassifySortByParentId(parentId, prevClassify.Id, prevClassify.Sort, updateSortStr)
				} else {
					_ = models.UpdateClassifySortByParentId(parentId, 0, prevSort, updateSortStr)
				}

			} else {
				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层，那么需要再加一层了
				if nextSort-prevSort == 1 {
					//变更兄弟节点的排序
					updateSortStr := `sort + 1`

					//变更分类
					if prevClassify != nil {
						_ = models.UpdateClassifySortByParentId(parentId, prevClassify.Id, prevSort, updateSortStr)
					} else {
						_ = models.UpdateClassifySortByParentId(parentId, 0, prevSort, updateSortStr)
					}

				}
			}
		}

		classifyInfo.Sort = prevSort + 1
		classifyInfo.ModifyTime = time.Now()
		updateCol = append(updateCol, "Sort", "ModifyTime")
	} else if prevClassify == nil && nextClassify == nil && parentId > 0 {
		//处理只拖动到目录里，默认放到目录底部的情况
		var maxSort int
		maxSort, err = ob.GetMaxSortByParentId(parentId)
		if err != nil {
			errMsg = "移动失败"
			err = fmt.Errorf("查询组内排序信息失败,Err:" + err.Error())
			return
		}
		classifyInfo.Sort = maxSort + 1 //那就是排在组内最后一位
		classifyInfo.ModifyTime = time.Now()
		updateCol = append(updateCol, "Sort", "ModifyTime")
	} else {
		// 拖动到父级分类的第一位
		firstPermission, tmpErr := ob.GetFirstClassifyByParentId(parentId)
		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
			errMsg = "移动失败"
			err = fmt.Errorf("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
			return
		}

		//如果该分类下存在其他分类，且第一个其他分类的排序等于0，那么需要调整排序
		if firstPermission != nil && firstPermission.Id != 0 && firstPermission.Sort == 0 {
			updateSortStr := ` sort + 1 `
			_ = models.UpdateClassifySortByParentId(parentId, firstPermission.Id-1, 0, updateSortStr)
		}

		classifyInfo.Sort = 0 //那就是排在第一位
		classifyInfo.ModifyTime = time.Now()
		updateCol = append(updateCol, "Sort", "ModifyTime")
	}

	//更新
	if len(updateCol) > 0 {
		err = classifyInfo.UpdateClassify(updateCol)
		if err != nil {
			errMsg = "移动失败"
			err = fmt.Errorf("修改失败,Err:" + err.Error())
			return
		}
	}
	return
}
