package member_center

import (
	"applet/app/db"
	"applet/app/e"
	md2 "applet/app/md/member_center"
	svc "applet/app/svc/member_center"
	"applet/app/utils"
	"code.fnuoos.com/EggPlanet/egg_models.git/src/implement"
	"code.fnuoos.com/EggPlanet/egg_models.git/src/model"
	"code.fnuoos.com/EggPlanet/egg_system_rules.git/enum"
	"errors"
	"github.com/gin-gonic/gin"
	"time"
)

// GetLevelList
// @Summary      制度中心-会员中心-等级管理(获取)
// @Tags         会员中心
// @Description  标签管理(获取)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    limit    query	 int 	true  "每页大小"
// @Param    page    query	 int 	true  "页数"
// @Success      200   {object}  md.GetLevelListResp    	"具体数据"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/levelManagement/getLevelList [get]
func GetLevelList(c *gin.Context) {
	page := c.DefaultQuery("page", "1")
	limit := c.DefaultQuery("limit", "10")

	levelDb := implement.NewUserLevelDb(db.Db)
	levels, total, err := levelDb.UserLevelAllByAscByPage(utils.StrToInt(page), utils.StrToInt(limit))
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	sql := "SElECT count(distinct id) as total, level FROM `user` GROUP BY level"
	results, err := db.QueryNativeString(db.Db, sql)
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}
	var countMap = map[int]string{}
	for _, res := range results {
		countMap[utils.StrToInt(res["level"])] = res["total"]
	}

	list := make([]md2.LevelListNode, len(levels))
	for i, level := range levels {
		list[i].LevelWeight = level.LevelWeight
		list[i].LevelID = level.Id
		list[i].LevelName = level.LevelName
		list[i].Count = countMap[level.Id]
		list[i].CreateAt = level.CreateAt
		list[i].IsUse = level.IsUse
		list[i].Memo = level.Memo
	}

	resp := md2.GetLevelListResp{
		List: list,
		Paginate: md2.Paginate{
			Limit: utils.StrToInt(limit),
			Page:  utils.StrToInt(page),
			Total: total,
		},
	}

	e.OutSuc(c, resp, nil)
}

// GetOneLevel
// @Summary      制度中心-会员中心-等级管理-等级明细(获取)
// @Tags         会员中心
// @Description  等级明细(获取)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    level_id    query	 int 	true  "等级 ID"
// @Success      200   {object}  md.GetOneLevelResp    	"具体数据"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/levelManagement/getOneLevel [get]
func GetOneLevel(c *gin.Context) {
	id := c.Query("level_id")
	if id == "" {
		e.OutErr(c, e.ERR_INVALID_ARGS, errors.New("必须传入等级ID"))
		return
	}

	taskType := []map[string]interface{}{
		{
			"name":  enum.UserLevelTaskType.String(enum.DirectPushMembersNum),
			"value": enum.DirectPushMembersNum,
		},
		{
			"name":  enum.UserLevelTaskType.String(enum.DirectPushActiveDayNum),
			"value": enum.DirectPushActiveDayNum,
		},
		{
			"name":  enum.UserLevelTaskType.String(enum.DirectPushLevel),
			"value": enum.DirectPushLevel,
		},
	}

	levelDb := implement.NewUserLevelDb(db.Db)
	level, err := levelDb.UserLevelByID(id)
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	userLevelTaskDb := implement.NewUserLevelTaskDb(db.Db)
	tasks, err := userLevelTaskDb.UserLevelTaskFindByParams(map[string]interface{}{
		"key":   "level_id",
		"value": id,
	})
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	resp := md2.GetOneLevelResp{
		TaskType:       taskType,
		LevelID:        level.Id,
		IsUse:          level.IsUse,
		LevelName:      level.LevelName,
		Memo:           level.Memo,
		AutoUpdate:     level.AutoUpdate,
		ChoosableNum:   level.ChoosableNum,
		LevelWeight:    level.LevelWeight,
		UserLevelTasks: tasks,
	}

	e.OutSuc(c, resp, nil)
}

// UpdateLevel
// @Summary      制度中心-会员中心-等级管理(更新)
// @Tags         会员中心
// @Description  等级管理(更新)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    req    body	 md.UpdateLevelReq 	true  "需要修改的等级信息"
// @Success      200   {string}     	"success"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/levelManagement/updateLevel [post]
func UpdateLevel(c *gin.Context) {
	var req *md2.UpdateLevelReq
	if err := c.ShouldBindJSON(&req); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err.Error())
		return
	}
	var forceColumns []string
	level := &model.UserLevel{
		Id:           utils.StrToInt(req.LevelID),
		LevelName:    req.LevelName,
		Memo:         req.Memo,
		ChoosableNum: utils.StrToInt(req.ChoosableNum),
	}
	if req.LevelWeight != "" {
		level.LevelWeight = utils.StrToInt(req.LevelWeight)
		forceColumns = append(forceColumns, "level_weight")
	}
	if req.IsUse == "0" || req.IsUse == "1" {
		level.LevelWeight = utils.StrToInt(req.IsUse)
		forceColumns = append(forceColumns, "is_use")
	}
	if req.AutoUpdate == "0" || req.AutoUpdate == "1" {
		level.AutoUpdate = utils.StrToInt(req.AutoUpdate)
		forceColumns = append(forceColumns, "auto_update")
	}

	session := db.Db.NewSession()
	defer session.Close()

	// 1. 更新等级信息
	levelDb := implement.NewUserLevelDb(db.Db)
	affected, err := levelDb.UserLevelUpdateBySession(session, req.LevelID, level, forceColumns...)
	if err != nil {
		if err.Error() == "no columns found to be updated" {
			e.OutSuc(c, affected, nil)
			return
		}
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	// 2. 更新任务信息
	// 2.1 删除关联任务
	taskDb := implement.NewUserLevelTaskDb(db.Db)
	_, err = taskDb.UserLevelTaskDeleteByParamsBySession(session, map[string]interface{}{
		"key":   "level_id",
		"value": req.LevelID,
	})
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	// 2.2 添加更新后的任务
	err = svc.BatchAddLevelTask(session, req.UserLevelTasks, utils.StrToInt(req.LevelID))
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	err = session.Commit()
	if err != nil {
		session.Rollback()
		e.OutErr(c, e.ERR_DB_ORM, nil)
		return
	}
	e.OutSuc(c, "success", nil)
}

// AddLevel
// @Summary      制度中心-会员中心-等级管理(新增)
// @Tags         会员中心
// @Description  等级管理(新增)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    req    body	 md.AddLevelReq 	true  "需要新增的等级信息"
// @Success      200   {int}     	"新增等级ID"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/levelManagement/addLevel [post]
func AddLevel(c *gin.Context) {
	var req *md2.AddLevelReq
	if err := c.ShouldBindJSON(&req); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err.Error())
		return
	}

	level := &model.UserLevel{
		LevelName:    req.LevelName,
		Memo:         req.Memo,
		ChoosableNum: utils.StrToInt(req.ChoosableNum),
		CreateAt:     time.Now().Format("2006-01-02 15:04:05"),
	}
	if req.LevelWeight != "" {
		level.LevelWeight = utils.StrToInt(req.LevelWeight)
	}
	if req.IsUse == "0" || req.IsUse == "1" {
		level.LevelWeight = utils.StrToInt(req.IsUse)
	}
	if req.AutoUpdate == "0" || req.AutoUpdate == "1" {
		level.AutoUpdate = utils.StrToInt(req.AutoUpdate)
	}

	session := db.Db.NewSession()
	defer session.Close()

	// 1. 创建等级信息
	levelDb := implement.NewUserLevelDb(db.Db)
	id, err := levelDb.UserLevelInsertBySession(session, level)
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	// 2. 创建任务信息
	err = svc.BatchAddLevelTask(session, req.UserLevelTasks, id)
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	err = session.Commit()
	if err != nil {
		session.Rollback()
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}
	e.OutSuc(c, id, nil)
}

// DeleteLevelTask
// @Summary      制度中心-会员中心-等级管理-等级任务(删除)
// @Tags         会员中心
// @Description  等级任务(删除)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    req    body	 md.DeleteTaskReq 	true  "需要删除的等级任务ID"
// @Success      200   {int}     	"成功删除数据数量"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/levelManagement/deleteLevelTask [delete]
func DeleteLevelTask(c *gin.Context) {
	var req *md2.DeleteTaskReq
	if err := c.ShouldBindJSON(&req); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err.Error())
		return
	}

	taskDb := implement.NewUserLevelTaskDb(db.Db)
	session := db.Db.Where("")
	// 不需要使用事务
	affected, err := taskDb.UserLevelTaskDeleteByParamsBySession(session, map[string]interface{}{
		"key":   "id",
		"value": req.TaskID,
	})
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}
	e.OutSuc(c, affected, nil)
}

// DeleteLevel
// @Summary      制度中心-会员中心-等级管理(删除)
// @Tags         会员中心
// @Description  等级管理(删除)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    req    body	 md.DeleteLevelReq 	true  "需要删除的等级 ID"
// @Success      200   {int}     	"成功删除数据数量"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/levelManagement/deleteLevel [delete]
func DeleteLevel(c *gin.Context) {
	var req *md2.DeleteLevelReq
	if err := c.ShouldBindJSON(&req); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err.Error())
		return
	}

	userDb := implement.NewUserDb(db.Db)
	exist, err := userDb.UserExistByParams(map[string]interface{}{
		"key":   "level",
		"value": req.LevelID,
	})
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}
	if exist {
		e.OutErr(c, e.ERR, errors.New("该等级下存在会员,无法删除,请移除对应等级下会员或将会员移动到其他等级").Error())
		return
	}

	session := db.Db.NewSession()
	defer session.Close()
	session.Begin()
	levelDb := implement.NewUserLevelDb(db.Db)
	affected, err := levelDb.UserLevelDeleteBySession(session, req.LevelID)
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}
	taskDb := implement.NewUserLevelTaskDb(db.Db)
	taskAffected, err := taskDb.UserLevelTaskDeleteByParamsBySession(session, map[string]interface{}{
		"key":   "level_id",
		"value": req.LevelID,
	})
	if err != nil {
		return
	}
	err = session.Commit()
	if err != nil {
		session.Rollback()
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}
	affected += taskAffected
	e.OutSuc(c, affected, nil)
}