package eta_training_video

import (
	"encoding/json"
	"fmt"
	"hongze/hz_crm_api/controllers"
	"hongze/hz_crm_api/models"
	"hongze/hz_crm_api/models/eta_training_video"
	etaTrainingVideoService "hongze/hz_crm_api/services/eta_training_video"
	"hongze/hz_crm_api/utils"
	"html/template"
	"sort"
	"strings"
	"time"
)

// EtaTrainingVideoClassifyController ETA培训视频分类
type EtaTrainingVideoClassifyController struct {
	controllers.BaseAuthController
}

// Tree
// @Title 分类树
// @Description 分类树
// @Param   Keyword			query	string	false	"关键词: 分类名称"
// @Success 200 Ret=200 获取成功
// @router /classify/tree [get]
func (this *EtaTrainingVideoClassifyController) Tree() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	resp := new(eta_training_video.EtaTrainingVideoClassifyResp)
	resp.List = make([]*eta_training_video.EtaTrainingVideoClassifyItem, 0)

	cond := ``
	pars := make([]interface{}, 0)
	// 关键词
	keyword := this.GetString("Keyword", "")
	keyword = strings.TrimSpace(keyword)
	keyword = template.HTMLEscapeString(keyword)

	// 获取所有分类
	ob := new(eta_training_video.EtaTrainingVideoClassify)
	classifies, e := ob.GetItemsByCondition(cond, pars, []string{}, ``)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取分类列表失败, Err: " + e.Error()
		return
	}

	list := make([]*eta_training_video.EtaTrainingVideoClassify, 0)
	if keyword != "" {
		classifyMap := make(map[int]*eta_training_video.EtaTrainingVideoClassify)
		parentMap := make(map[int]*eta_training_video.EtaTrainingVideoClassify)
		existMap := make(map[int]bool)

		for _, m := range classifies {
			classifyMap[m.EtaTrainingVideoClassifyId] = m
		}
		for _, m := range classifies {
			if m.ParentId > 0 {
				parentMap[m.EtaTrainingVideoClassifyId] = classifyMap[m.ParentId]
			}
		}

		// 遍历菜单, 取出跟关键词匹配的菜单(以后可能会更改成无限级分类, 所以相似度匹配在这里处理)
		for _, m := range classifies {
			if !strings.Contains(m.ClassifyName, keyword) {
				continue
			}
			if existMap[m.EtaTrainingVideoClassifyId] {
				continue
			}
			existMap[m.EtaTrainingVideoClassifyId] = true
			list = append(list, m)

			// 取出关键词所匹配的所有父级菜单
			if m.ParentId > 0 {
				parents := etaTrainingVideoService.GetClassifyParentsRecursive(classifies, m.ParentId)
				for _, p := range parents {
					if !existMap[p.EtaTrainingVideoClassifyId] {
						existMap[p.EtaTrainingVideoClassifyId] = true
						list = append(list, p)
					}
				}
			}
		}

		sort.Slice(list, func(i, j int) bool {
			return list[j].Sort > list[i].Sort
		})
	} else {
		list = classifies
	}

	items := make([]*eta_training_video.EtaTrainingVideoClassifyItem, 0)
	for _, v := range list {
		t := &eta_training_video.EtaTrainingVideoClassifyItem{
			ClassifyId:   v.EtaTrainingVideoClassifyId,
			ClassifyName: v.ClassifyName,
			ParentId:     v.ParentId,
			Sort:         v.Sort,
			Children:     make([]*eta_training_video.EtaTrainingVideoClassifyItem, 0),
		}
		items = append(items, t)
	}

	// 递归返回树形结构
	items = etaTrainingVideoService.GetClassifyTreeRecursive(items, 0)

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

// Add
// @Title 新增分类
// @Description 新增分类
// @Param	request	body eta_training_video.EtaTrainingVideoClassifyAddReq true "type json string"
// @Success 200 Ret=200 操作成功
// @router /classify/add [post]
func (this *EtaTrainingVideoClassifyController) Add() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	// 参数校验
	var req eta_training_video.EtaTrainingVideoClassifyAddReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	req.ClassifyName = strings.TrimSpace(req.ClassifyName)
	if req.ClassifyName == "" {
		br.Msg = "请输入分类名称"
		return
	}
	nameRune := []rune(req.ClassifyName)
	if len(nameRune) > 50 {
		br.Msg = "分类名称不可超过50个字符"
		return
	}

	// 重名校验
	{
		ob := new(eta_training_video.EtaTrainingVideoClassify)
		cond := fmt.Sprintf(` AND %s = ? AND %s = ?`, eta_training_video.VideoClassifyColumns.ParentId, eta_training_video.VideoClassifyColumns.ClassifyName)
		pars := make([]interface{}, 0)
		pars = append(pars, req.ParentId, req.ClassifyName)
		exist, e := ob.GetItemByCondition(cond, pars)
		if e != nil && e.Error() != utils.ErrNoRow() {
			br.Msg = "操作失败"
			br.ErrMsg = "获取重名分类失败, Err: " + e.Error()
			return
		}
		if exist != nil {
			br.Msg = "分类名称已存在"
			return
		}
	}

	item := new(eta_training_video.EtaTrainingVideoClassify)
	item.ClassifyName = req.ClassifyName
	item.ParentId = req.ParentId
	item.SysUserId = sysUser.AdminId
	item.SysRealName = sysUser.RealName
	item.CreateTime = time.Now().Local()
	item.ModifyTime = time.Now().Local()
	if e := item.Create(); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "新增分类失败, Err: " + e.Error()
		return
	}

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

// Edit
// @Title 编辑分类
// @Description 编辑分类
// @Param	request	body eta_training_video.EtaTrainingVideoTagEditReq true "type json string"
// @Success 200 Ret=200 操作成功
// @router /classify/edit [post]
func (this *EtaTrainingVideoClassifyController) Edit() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	// 参数校验
	var req eta_training_video.EtaTrainingVideoClassifyEditReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	if req.ClassifyId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = fmt.Sprintf("参数有误, 分类ID: %d", req.ClassifyId)
		return
	}
	req.ClassifyName = strings.TrimSpace(req.ClassifyName)
	if req.ClassifyName == "" {
		br.Msg = "请输入分类名称"
		return
	}
	nameRune := []rune(req.ClassifyName)
	if len(nameRune) > 50 {
		br.Msg = "分类名称不可超过50个字符"
		return
	}

	ob := new(eta_training_video.EtaTrainingVideoClassify)
	item, e := ob.GetItemById(req.ClassifyId)
	if e != nil {
		if e.Error() != utils.ErrNoRow() {
			br.Msg = "分类不存在, 请刷新页面"
			return
		}
		br.Msg = "操作失败"
		br.ErrMsg = "获取分类失败, Err: " + e.Error()
		return
	}
	if item.ParentId == req.ParentId && item.ClassifyName == req.ClassifyName {
		br.Ret = 200
		br.Success = true
		br.Msg = "操作成功"
		return
	}

	// 重名校验
	{
		cond := fmt.Sprintf(` AND %s = ? AND %s = ?`, eta_training_video.VideoClassifyColumns.ParentId, eta_training_video.VideoClassifyColumns.ClassifyName)
		pars := make([]interface{}, 0)
		pars = append(pars, req.ParentId, req.ClassifyName)
		exist, e := ob.GetItemByCondition(cond, pars)
		if e != nil && e.Error() != utils.ErrNoRow() {
			br.Msg = "操作失败"
			br.ErrMsg = "获取重名分类失败, Err: " + e.Error()
			return
		}
		if exist != nil && exist.EtaTrainingVideoClassifyId != item.EtaTrainingVideoClassifyId {
			br.Msg = "分类已存在"
			return
		}
	}

	now := time.Now().Local()
	item.ClassifyName = req.ClassifyName
	item.ParentId = req.ParentId
	item.ModifyTime = now
	cols := []string{"ClassifyName", "ParentId", "ModifyTime"}
	if e := item.Update(cols); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "更新分类失败, Err: " + e.Error()
		return
	}

	// 更新关联表冗余
	go func() {
		relateOB := new(eta_training_video.EtaTrainingVideoClassifyRelate)
		_ = relateOB.UpdateClassifyInfoByClassifyId(item.EtaTrainingVideoClassifyId, req.ParentId, req.ClassifyName)
	}()

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

// Remove
// @Title 删除分类
// @Description 删除分类
// @Param	request	body eta_training_video.EtaTrainingVideoClassifyRemoveReq true "type json string"
// @Success 200 Ret=200 操作成功
// @router /classify/remove [post]
func (this *EtaTrainingVideoClassifyController) Remove() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	// 参数校验
	var req eta_training_video.EtaTrainingVideoClassifyRemoveReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	if req.ClassifyId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = fmt.Sprintf("参数有误, 分类ID: %d", req.ClassifyId)
		return
	}

	ob := new(eta_training_video.EtaTrainingVideoClassify)
	item, e := ob.GetItemById(req.ClassifyId)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			br.Ret = 200
			br.Success = true
			br.Msg = "操作成功"
			return
		}
		br.Msg = "操作失败"
		br.ErrMsg = "获取分类失败, Err: " + e.Error()
		return
	}

	// 删除校验
	{
		// 子分类
		childCond := fmt.Sprintf(` AND %s = ?`, eta_training_video.VideoClassifyColumns.ParentId)
		childPars := make([]interface{}, 0)
		childPars = append(childPars, item.EtaTrainingVideoClassifyId)
		childTotal, e := ob.GetCountByCondition(childCond, childPars)
		if e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = "获取子分类数失败, Err: " + e.Error()
			return
		}
		if childTotal > 0 {
			br.Msg = "该分类下已关联内容, 不可删除"
			return
		}

		// 引用
		useOB := new(eta_training_video.EtaTrainingVideoClassifyRelate)
		useCond := fmt.Sprintf(` AND %s = ?`, eta_training_video.VideoClassifyRelateColumns.EtaTrainingVideoClassifyId)
		usePars := make([]interface{}, 0)
		usePars = append(usePars, item.EtaTrainingVideoClassifyId)
		useTotal, e := useOB.GetCountByCondition(useCond, usePars)
		if e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = "获取分类引用数失败, Err: " + e.Error()
			return
		}
		if useTotal > 0 {
			br.Msg = "该分类下已关联内容, 不可删除"
			return
		}
	}

	if e := item.Del(); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "删除分类失败, Err: " + e.Error()
		return
	}

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