package member_center

import (
	"applet/app/db"
	"applet/app/e"
	"applet/app/md/member_center"
	svc2 "applet/app/svc"
	svc "applet/app/svc/member_center"
	"applet/app/utils"
	"code.fnuoos.com/EggPlanet/egg_models.git/src/implement"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"strings"
)

// UserManagementGetUserList
// @Summary      制度中心-会员中心-用户管理-用户信息管理(获取)
// @Tags         会员中心
// @Description  用户信息管理(获取)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    req    body	 md.UserManagementGetUserListReq 	true  "分页信息必填"
// @Success      200   {object}  md.UserManagementGetUserListResp   	"具体数据"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/userManagement/getUserList [post]
func UserManagementGetUserList(c *gin.Context) {
	var req *md.UserManagementGetUserListReq
	if err := c.ShouldBindJSON(&req); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err.Error())
		return
	}

	levelDb := implement.NewUserLevelDb(db.Db)
	levels, err1 := levelDb.UserLevelAllByAsc()
	if err1 != nil {
		e.OutErr(c, e.ERR_DB_ORM, err1.Error())
		return
	}
	levelsList := make([]map[string]interface{}, 0)
	levelsMap := make(map[int]string)
	for _, level := range levels {
		levelsList = append(levelsList, map[string]interface{}{
			"id":   level.Id,
			"name": level.LevelName,
		})
		levelsMap[level.Id] = level.LevelName
	}

	tagDb := implement.NewUserTagDb(db.Db)
	tags, err2 := tagDb.UserTagAllByAsc()
	if err2 != nil {
		e.OutErr(c, e.ERR_DB_ORM, err2.Error())
		return
	}
	tagsList := make([]map[string]interface{}, 0)
	tagsMap := make(map[int]string)
	for _, tag := range tags {
		tagsList = append(tagsList, map[string]interface{}{
			"id":   tag.Id,
			"name": tag.TagName,
		})
		tagsMap[tag.Id] = tag.TagName
	}

	stateList := []map[string]interface{}{
		{
			"name":  "正常",
			"value": "1",
		},
		{
			"name":  "冻结",
			"value": "2",
		},
	}

	users, total, err3 := svc.UserManagementGetUsers(req)
	if err3 != nil {
		e.OutErr(c, e.ERR_DB_ORM, err3.Error())
		return
	}
	userIDs := make([]int64, len(users))
	for i, user := range users {
		userIDs[i] = user.Id
	}

	recordsDb := implement.NewUserTagRecordsDb(db.Db)
	records, err := recordsDb.UserTagRecordsFindByParams(map[string]interface{}{
		"key":   "uid",
		"value": userIDs,
	})
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	var levelCounts []md.LevelCount
	err4 := db.Db.Table("user").Select("level, Count(*) AS count").GroupBy("level").Find(&levelCounts)
	if err4 != nil {
		e.OutErr(c, e.ERR_DB_ORM, err4.Error())
		return
	}

	userMap := make(map[int64]int, len(users))
	list := make([]md.UserManagementGetUserListNode, len(users))
	for i, user := range users {
		list[i] = md.UserManagementGetUserListNode{
			ID:               user.Id,
			Sex:              user.Sex,
			Avatar:           svc2.GetOssUrl(user.Avatar),
			Nickname:         user.Nickname,
			Phone:            user.Phone,
			IsRealName:       user.IsRealName,
			InviteCode:       user.SystemInviteCode,
			ParentID:         user.ParentUid,
			ParentInviteCode: user.ParentSystemInviteCode,
			ParentPhone:      user.Phone,
			RegisterTime:     user.CreateAt,
			Memo:             user.Memo,
			Wechat:           user.UnionId,
			RegisterType:     user.RegisterType,
			State:            user.State,
			LastLoginAt:      user.UpdateAt,
		}
		var tempTagList []md.TagNode
		list[i].Tag = tempTagList
		userMap[user.Id] = i
		level, ok := levelsMap[user.Level]
		if ok {
			list[i].LevelName = level
		}
	}

	for _, record := range *records {
		tempTagNode := md.TagNode{
			TagID:   record.TagId,
			TagName: tagsMap[record.TagId],
		}
		list[userMap[record.Uid]].Tag = append(list[userMap[record.Uid]].Tag, tempTagNode)
	}

	resp := md.UserManagementGetUserListResp{
		LevelsList: levelsList,
		TagsList:   tagsList,
		StateList:  stateList,
		List:       list,
		Paginate: md.Paginate{
			Limit: req.Limit,
			Page:  req.Page,
			Total: total,
		},
	}
	e.OutSuc(c, resp, nil)
}

// UserManagementUpdateUserInfo
// @Summary      制度中心-会员中心-用户管理-用户信息管理(更新)
// @Tags         会员中心
// @Description  用户信息管理(更新)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    req    body	 md.UserManagementUpdateUserInfoReq 	true  "用户ID 必传"
// @Success      200   {int}     	"修改数据行数"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/userManagement/updateUserInfo [post]
func UserManagementUpdateUserInfo(c *gin.Context) {
	var req *md.UserManagementUpdateUserInfoReq
	if err := c.ShouldBindJSON(&req); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err.Error())
		return
	}
	affected, err := svc.UserManagementUpdateUserInfo(db.Db, req)
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	e.OutSuc(c, affected, nil)
}

// UserManagementGetOneBasic
// @Summary      制度中心-会员中心-用户管理-会员明细概况(获取)
// @Tags         会员中心
// @Description  会员明细概况(获取)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    uid    query	 string 	true  "用户 ID"
// @Success      200   {object}  md.UserManagementGetOneBasicResp    	"会员明细概况具体数据"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/userManagement/userData [get]
func UserManagementGetOneBasic(c *gin.Context) {
	uid := c.Query("uid")
	userDb := implement.NewUserDb(db.Db)
	user, err := userDb.UserGetOneByParams(map[string]interface{}{
		"key":   "id",
		"value": uid,
	})
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	// 1. 查询等级列表
	levelDb := implement.NewUserLevelDb(db.Db)
	levels, err1 := levelDb.UserLevelAllByAsc()
	if err1 != nil {
		e.OutErr(c, e.ERR_DB_ORM, err1.Error())
		return
	}
	levelsList := make([]map[string]interface{}, 0)
	levelsMap := make(map[int]string)
	for _, level := range levels {
		levelsList = append(levelsList, map[string]interface{}{
			"id":   level.Id,
			"name": level.LevelName,
		})
		levelsMap[level.Id] = level.LevelName
	}

	//2. 查询标签列表
	tagDb := implement.NewUserTagDb(db.Db)
	tags, err2 := tagDb.UserTagAllByAsc()
	if err2 != nil {
		e.OutErr(c, e.ERR_DB_ORM, err2.Error())
		return
	}
	tagsList := make([]map[string]interface{}, 0)
	tagsMap := make(map[int]string)
	for _, tag := range tags {
		tagsList = append(tagsList, map[string]interface{}{
			"id":   tag.Id,
			"name": tag.TagName,
		})
		tagsMap[tag.Id] = tag.TagName
	}

	//3. 查询父用户信息
	parent, err := userDb.UserGetOneByParams(map[string]interface{}{
		"key":   "id",
		"value": user.ParentUid,
	})
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	//4. 查询用户标签
	recordsDb := implement.NewUserTagRecordsDb(db.Db)
	userTagRecords, err := recordsDb.UserTagRecordsFindByParams(map[string]interface{}{
		"key":   "uid",
		"value": uid,
	})
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	resp := md.UserManagementGetOneBasicResp{
		TagsList:   tagsList,
		LevelsList: levelsList,
		BasicInfo: md.BasicInfoNode{
			Avatar:   user.Avatar,
			Sex:      user.Sex,
			Nickname: user.Nickname,
			LevelId:  user.Level,
			Phone:    user.Phone,
			UnionId:  user.UnionId,
			Password: user.Password,
			State:    user.State,
			Memo:     user.Memo,
		},
		OtherInfo: md.OtherNode{
			LastLoginIp: user.LastLoginIp,
			LastLoginAt: user.UpdateAt,
			CreateAt:    user.CreateAt,
		},
	}
	tagList := make([]md.TagNode, len(*userTagRecords))
	if *userTagRecords != nil {
		for i, records := range *userTagRecords {
			tagList[i].TagID = records.TagId
			tagList[i].TagName = tagsMap[records.TagId]
		}
	}
	resp.BasicInfo.Tag = tagList
	if parent != nil {
		resp.BasicInfo.ParentUid = parent.Id
		resp.BasicInfo.ParentName = parent.Nickname
		resp.BasicInfo.ParentPhone = parent.Phone
	}
	level, ok := levelsMap[user.Level]
	if ok {
		resp.BasicInfo.LevelName = level
	}

	e.OutSuc(c, resp, nil)
}

// UserManagementGetFans
// @Summary      制度中心-会员中心-用户管理-会员明细粉丝情况(获取)
// @Tags         会员中心
// @Description  会员明细粉丝情况(获取)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    uid    query	 string 	true  "用户 ID"
// @Param    type    query	 string 	true  "粉丝类型(1.全部 2.直推 3.二代 4.二代以后)"
// @Param    limit    query	 string 	true  "每页大小"
// @Param    page    query	 string 	true  "页数"
// @Success      200   {object}  md.UserManagementGetFansResp    	"具体数据"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/userManagement/getFans [get]
func UserManagementGetFans(c *gin.Context) {
	uid := c.Query("uid")
	fansType := c.Query("type")
	limit := c.Query("limit")
	page := c.Query("page")

	//1. 查询符合情况用户 ID
	relateDb := implement.NewUserRelateDb(db.Db)
	var level int
	switch fansType {
	case "0":
		level = 0
	case "1":
		level = 1
	case "2":
		level = 2
	default:
		level = 3
	}
	relates, total, err := relateDb.PageFindUserRelateByParentUidAndLevel(utils.StrToInt64(uid), utils.StrToInt(page), utils.StrToInt(limit), level)
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}
	userIDs := make([]int64, len(*relates))
	for i, relate := range *relates {
		userIDs[i] = relate.Uid
	}

	//2. 查询所属代数
	platoonUserRelationDb := implement.NewPublicPlatoonUserRelationDb(db.Db)
	levelTotals, err := platoonUserRelationDb.PublicPlatoonUserRelationFindByParamsByPage(map[string]interface{}{
		"key":   "uid",
		"value": userIDs,
	}, utils.StrToInt(page), utils.StrToInt(limit))
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}
	levelTotalMap := make(map[int64]int)
	for _, levelTotal := range *levelTotals {
		levelTotalMap[levelTotal.Uid] = levelTotal.LevelTotal
	}

	//3. 查询可提现余额
	walletDb := implement.NewUserWalletDb(db.Db)
	wallets, err := walletDb.FindUserWalletByParams(map[string]interface{}{
		"key":   uid,
		"value": userIDs,
	})
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}
	walletMap := make(map[int64]string)
	for _, wallet := range *wallets {
		walletMap[wallet.Uid] = wallet.Amount
	}

	//4. 查询累计收益
	var incomeMap = map[int64]string{}
	if len(*relates) > 0 {
		userIDStrs := make([]string, len(*relates))
		for i, id := range userIDs {
			userIDStrs[i] = utils.Int64ToStr(id)
		}
		sql := "SELECT SUM(amount) as total, uid FROM `user_wallet_flow` WHERE uid in (%s) AND direction = 1 Group BY uid"
		results, err := db.QueryNativeString(db.Db, fmt.Sprintf(sql, strings.Join(userIDStrs, ",")))
		if err != nil {
			e.OutErr(c, e.ERR_DB_ORM, err.Error())
			return
		}
		for _, res := range results {
			incomeMap[utils.StrToInt64(res["uid"])] = res["total"]
		}
	}

	//5. 查询用户信息
	userDb := implement.NewUserDb(db.Db)
	users, err := userDb.UserFindByParams(map[string]interface{}{
		"key":   "uid",
		"value": userIDs,
	})
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	list := make([]md.FansNode, len(users))
	for i, user := range users {
		list[i] = md.FansNode{
			ID:         user.Id,
			Nickname:   user.Nickname,
			Phone:      user.Phone,
			RegisterAt: user.CreateAt,
		}
		val, ok := incomeMap[user.Id]
		if ok {
			list[i].TotalIncome = val
		}
		levelTotal, ok := levelTotalMap[user.Id]
		if ok {
			list[i].LevelTotal = levelTotal
		}
		amount, ok := walletMap[user.Id]
		if ok {
			list[i].Amount = amount
		}

	}

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

	e.OutSuc(c, resp, nil)
}

// UserManagementGetBalanceDetail
// @Summary      制度中心-会员中心-用户管理-会员明细(余额获取)
// @Tags         会员中心
// @Description  会员明细(余额获取)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    uid    query	 string 	true  "用户 ID"
// @Param    limit    query	 string 	true  "每页大小"
// @Param    page    query	 string 	true  "页数"
// @Success      200   {object}  md.UserManagementGetBalanceDetailResp    	"具体数据"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/userManagement/balanceDetail [get]
func UserManagementGetBalanceDetail(c *gin.Context) {
	uid := c.Query("uid")
	page := c.DefaultQuery("page", "1")
	limit := c.DefaultQuery("limit", "10")

	walletFlowDb := implement.NewUserWalletFlowDb(db.Db)
	walletFlows, total, err := walletFlowDb.UserWalletFlowFindByParams(map[string]interface{}{
		"key":   "uid",
		"value": uid,
	}, utils.StrToInt(page), utils.StrToInt(limit))
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	kindMap := map[int]string{
		1: "管理员操作增加余额",
		2: "管理员操作扣除余额",
		3: "蛋蛋能量兑换余额",
		4: "余额兑换蛋蛋能量",
	}

	list := make([]md.BalanceDetailNode, len(*walletFlows))
	for i, flow := range *walletFlows {
		list[i] = md.BalanceDetailNode{
			ID:          flow.Id,
			Amount:      flow.Amount,
			AfterAmount: flow.AfterAmount,
			Kind:        kindMap[flow.Kind],
			CreateAt:    flow.CreateAt,
		}
	}

	resp := md.UserManagementGetBalanceDetailResp{
		List: list,
		Paginate: md.Paginate{
			Limit: utils.StrToInt(limit),
			Page:  utils.StrToInt(page),
			Total: total,
		},
	}
	e.OutSuc(c, resp, nil)
}

// UserManagementGetVirtualCoinDetail
// @Summary      制度中心-会员中心-用户管理-会员明细(积分明细获取)
// @Tags         会员中心
// @Description  会员明细(积分明细获取)
// @Accept       json
// @Produce      json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param    uid    query	 string 	true  "用户 ID"
// @Param    coinId    query	 string 	true  "货币 ID"
// @Param    limit    query	 string 	true  "每页大小"
// @Param    page    query	 string 	true  "页数"
// @Success      200   {object}  md.UserManagementGetVirtualCoinDetailResp    	"具体数据"
// @Failure      400   {object}   md.Response              	"具体错误"
// @Router       /api/memberCenter/userManagement/getVirtualCoinDetail [get]
func UserManagementGetVirtualCoinDetail(c *gin.Context) {
	page := c.DefaultQuery("page", "1")
	limit := c.DefaultQuery("limit", "10")
	uid := c.Query("uid")
	coinID := c.Query("coinId")
	coinDb := implement.NewVirtualCoinDb(db.Db)
	coins, err := coinDb.VirtualCoinFindAll()
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}
	if coins == nil {
		e.OutErr(c, e.ERR_NO_DATA, errors.New("未初始化货币"))
		return
	}

	coinsList := make([]map[string]interface{}, len(coins))
	coinsMap := map[int]string{}
	for i, coin := range coins {
		coinsList[i] = map[string]interface{}{
			"coinID": coin.Id,
			"name":   coin.Name,
		}
		coinsMap[coin.Id] = coin.Name
	}

	// 传入不存在的货币类型时 默认为第一种货币类型
	var reqCoinID int
	_, ok := coinsMap[utils.StrToInt(coinID)]
	if !ok {
		reqCoinID = coinsList[0]["coinID"].(int)
	} else {
		reqCoinID = utils.StrToInt(coinID)
	}

	flowDb := implement.NewUserVirtualCoinFlowDb(db.Db)
	flows, total, err := flowDb.UserVirtualCoinFlowFindByCoinAndUser(utils.StrToInt(page), utils.StrToInt(limit), reqCoinID, utils.StrToInt64(uid), "", "", 0, false, 0)
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err.Error())
		return
	}

	list := make([]md.VirtualCoinDetailNode, len(flows))
	for i, flow := range flows {
		list[i] = md.VirtualCoinDetailNode{
			Uid:         flow.Uid,
			Amount:      flow.Amount,
			AfterAmount: flow.AfterAmount,
			Direction:   flow.Direction,
			CreateAt:    flow.CreateAt,
		}
	}

	resp := md.UserManagementGetVirtualCoinDetailResp{
		CoinList: coinsList,
		List:     list,
		Paginate: md.Paginate{
			Limit: utils.StrToInt(limit),
			Page:  utils.StrToInt(page),
			Total: total,
		},
	}

	e.OutSuc(c, resp, nil)
}