package user

import (
	"encoding/hex"
	"fmt"
	"mtp2_if/global/app"
	"mtp2_if/global/e"
	"mtp2_if/logger"
	"mtp2_if/models"
	"mtp2_if/utils"
	"net/http"

	"github.com/gin-gonic/gin"
)

// QueryUserReferNumReq 获取用户邀请码请求参数
type QueryUserReferNumReq struct {
	UserID int `form:"userID" binding:"required"`
}

// QueryUserReferNum 获取用户邀请码
// @Summary 获取用户邀请码
// @Produce json
// @Param userID query int true "用户ID"
// @Success 200 {object} app.Response
// @Failure 500 {object} app.Response
// @Router /User/QueryUserReferNum [get]
// @Tags 用户信息
func QueryUserReferNum(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req QueryUserReferNumReq
	if err := appG.C.ShouldBindQuery(&req); err != nil {
		logger.GetLogger().Errorf("QueryUserReferNum failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	var (
		userAccount *models.Useraccount
		err         error
	)
	if userAccount, err = models.GetUserAccount(req.UserID); err != nil {
		// 查询失败
		logger.GetLogger().Errorf("QueryUserReferNum failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}

	// 查询成功
	logger.GetLogger().Debugln("QueryUserReferNum successed: %v", userAccount.Refernum)
	appG.Response(http.StatusOK, e.SUCCESS, userAccount.Refernum)
}

// QueryUserInfoReq 获取用户信息请求参数
type QueryUserInfoReq struct {
	UserID    int  `form:"userID" binding:"required"`
	IsDecrypt bool `form:"isDecrypt"`
}

// QueryUserInfo 获取用户信息
// @Summary 获取用户信息
// @Produce json
// @Security ApiKeyAuth
// @Param userID query int true "用户ID"
// @Param isDecrypt query bool false "是否解密"
// @Success 200 {object} models.Userinfo
// @Failure 500 {object} app.Response
// @Router /User/QueryUserInfo [get]
// @Tags 用户信息
func QueryUserInfo(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req QueryUserInfoReq
	if err := appG.C.ShouldBindQuery(&req); err != nil {
		logger.GetLogger().Errorf("QueryUserInfo failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	// 查询数据
	var (
		data *models.Userinfo
		err  error
	)
	if data, err = models.GetUserInfo(req.UserID); err != nil {
		// 查询失败
		logger.GetLogger().Errorf("QueryUserInfo failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}

	// 解密
	if req.IsDecrypt {
		key, _ := hex.DecodeString(utils.AESSecretKey)
		// 手机号码解密
		if len(data.Mobile) > 0 {
			if phonenum, err := hex.DecodeString(data.Mobile); err == nil { // hex -> []byte
				if mobile, err := utils.AESDecrypt(phonenum, key); err == nil {
					// 脱敏
					tmp := string(mobile)
					l := len(tmp)
					if l > 7 {
						tmp = fmt.Sprintf("%s****%s", tmp[:3], tmp[l-4:])
					} else {
						tmp = fmt.Sprintf("%s****", tmp[:3])
					}
					data.Mobile = tmp
				}
			}
		}
		// 证件号码解密
		if len(data.Cardnum) > 0 {
			if cardnum, err := hex.DecodeString(data.Cardnum); err == nil { // hex -> []byte
				if c, err := utils.AESDecrypt(cardnum, key); err == nil {
					// 脱敏
					tmp := string(c)
					l := len(tmp)
					if l > 7 {
						tmp = fmt.Sprintf("%s****%s", tmp[:3], tmp[l-4:])
					} else {
						tmp = fmt.Sprintf("%s****", tmp[:3])
					}
					data.Cardnum = tmp
				}
			}
		}
	}

	// 查询成功
	logger.GetLogger().Debugln("QueryUserInfo successed: %v", data)
	appG.Response(http.StatusOK, e.SUCCESS, data)
}

// GetUserAuthStatusReq 获取用户实名认证状态请求参数
type GetUserAuthStatusReq struct {
	UserID int `form:"userID" binding:"required"` // 用户ID
}

// GetUserAuthStatus 获取用户实名认证状态
// @Summary 获取用户实名认证状态
// @Produce json
// @Security ApiKeyAuth
// @Param userID query int true "用户ID"
// @Success 200 {object} app.Response
// @Failure 500 {object} app.Response
// @Router /User/GetUserAuthStatus [get]
// @Tags 用户信息
func GetUserAuthStatus(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req GetUserAuthStatusReq
	if err := appG.C.ShouldBindQuery(&req); err != nil {
		logger.GetLogger().Errorf("GetUserAuthStatus failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	isAuth := false
	var (
		userAccount *models.Useraccount
		err         error
	)
	if userAccount, err = models.GetUserAccount(req.UserID); err != nil {
		// 查询失败
		logger.GetLogger().Errorf("GetUserAuthStatus failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}
	if userAccount != nil {
		if userAccount.Hasauth == 1 {
			isAuth = true
		}
	}

	// 查询成功
	logger.GetLogger().Debugln("GetUserAuthStatus successed: %v", isAuth)
	appG.Response(http.StatusOK, e.SUCCESS, isAuth)
}

// GetUserAccountReq 获取用户账号信息请求参数
type GetUserAccountReq struct {
	UserID int `form:"userID" binding:"required"` // 用户ID
}

// GetUserAccount 获取用户账号信息
// @Summary 获取用户账号信息
// @Produce json
// @Security ApiKeyAuth
// @Param userID query int true "用户ID"
// @Success 200 {object} models.Useraccount
// @Failure 500 {object} app.Response
// @Router /User/GetUserAccount [get]
// @Tags 用户信息
func GetUserAccount(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req GetUserAccountReq
	if err := appG.C.ShouldBindQuery(&req); err != nil {
		logger.GetLogger().Errorf("GetUserAccount failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	var (
		userAccount *models.Useraccount
		err         error
	)
	if userAccount, err = models.GetUserAccount(req.UserID); err != nil {
		// 查询失败
		logger.GetLogger().Errorf("GetUserAccount failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}

	// 查询成功
	logger.GetLogger().Debugln("GetUserAccount successed: %v", userAccount)
	appG.Response(http.StatusOK, e.SUCCESS, userAccount)
}

// LoginQueryReq 账户登录后信息查询请求参数
type LoginQueryReq struct {
	LoginID int `form:"loginID" binding:"required"`
}

// LoginQueryRsp 账户登录后信息查询返回模型
type LoginQueryRsp struct {
	UserName          string                    `json:"username"`          // 用户姓名
	LoginAccount      models.Loginaccount       `json:"loginAccount"`      // 登录账号
	UserAccount       models.Useraccount        `json:"userAccount"`       // 用户账号
	UserInfo          models.Userinfo           `json:"userInfo"`          // 用户信息
	AreaRoles         []models.Arearole         `json:"areaRoles"`         // 所属角色信息
	Markets           []models.Market           `json:"markets"`           // 市场
	Goodsgroups       []models.Goodsgroup       `json:"goodsgroups"`       // 商品组
	ExternalExchanges []models.Externalexchange `json:"externalExchanges"` // 外部交易所
	SystemParams      []models.Systemparam      `json:"systemParams"`      // 系统参数
}

// LoginQuery 账户登录后信息查询
// @Summary 账户登录后信息查询
// @Produce json
// @Security ApiKeyAuth
// @Param loginID query int true "登录账号"
// @Success 200 {object} LoginQueryRsp
// @Failure 500 {object} app.Response
// @Router /User/LoginQuery [get]
// @Tags 用户信息
func LoginQuery(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req LoginQueryReq
	if err := appG.C.ShouldBindQuery(&req); err != nil {
		logger.GetLogger().Errorf("LoginQuery failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	var rsp LoginQueryRsp
	// 登录账号
	loginAccount, err := models.GetLoginAccount(req.LoginID)
	if err != nil {
		// 查询失败
		logger.GetLogger().Errorf("LoginQuery failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}
	rsp.LoginAccount = *loginAccount
	// 用户账号
	userAccount, err := models.GetUserAccount(int(loginAccount.Userid))
	if err != nil {
		// 查询失败
		logger.GetLogger().Errorf("LoginQuery failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}
	rsp.UserAccount = *userAccount
	// 用户信息
	userInfo, err := models.GetUserInfo(int(loginAccount.Userid))
	if err != nil {
		// 查询失败
		logger.GetLogger().Errorf("LoginQuery failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}
	rsp.UserInfo = *userInfo
	// 角色信息
	var areaRole models.Arearole
	areaRoles, err := areaRole.GetAreaRolesByUserID(int(loginAccount.Userid))
	if err != nil {
		// 查询失败
		logger.GetLogger().Errorf("LoginQuery failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}
	rsp.AreaRoles = areaRoles
	// 有权限的市场
	markets, err := models.GetMarketsByLoginID(req.LoginID)
	if err != nil {
		// 查询失败
		logger.GetLogger().Errorf("LoginQuery failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}
	rsp.Markets = markets
	// 商品组
	rsp.Goodsgroups = make([]models.Goodsgroup, 0)
	if len(rsp.Markets) > 0 {
		marketIDs := make([]int, 0)
		for _, v := range rsp.Markets {
			marketIDs = append(marketIDs, int(v.Marketid))
		}
		goodsgroups, err := models.GetGoodsgroupInMarketIDs(marketIDs)
		if err != nil {
			// 查询失败
			logger.GetLogger().Errorf("LoginQuery failed: %s", err.Error())
			appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
			return
		}
		rsp.Goodsgroups = goodsgroups
	}
	// 外部交易所
	rsp.ExternalExchanges = make([]models.Externalexchange, 0)
	if len(rsp.Goodsgroups) > 0 {
		exchangeIDs := make([]int, 0)
		for _, v := range rsp.Goodsgroups {
			exchangeIDs = append(exchangeIDs, int(v.Exexchangeid))
		}
		exExchanges, err := models.GetExExchangeByIDs(exchangeIDs)
		if err != nil {
			// 查询失败
			logger.GetLogger().Errorf("LoginQuery failed: %s", err.Error())
			appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
			return
		}
		rsp.ExternalExchanges = exExchanges
	}
	// 系统参数
	systemParams, err := models.GetSystemParams()
	if err != nil {
		// 查询失败
		logger.GetLogger().Errorf("LoginQuery failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}
	rsp.SystemParams = systemParams
	// 用户姓名
	if len(rsp.LoginAccount.Logincode) > 0 {
		systemManager, _ := models.GetSysteMmanagerByLoginCode(rsp.LoginAccount.Logincode)
		if systemManager != nil {
			rsp.UserName = systemManager.Username
		}
	}

	// 查询成功
	logger.GetLogger().Debugln("LoginQuery successed: %v", rsp)
	appG.Response(http.StatusOK, e.SUCCESS, rsp)
}

// QueryUserFavoriteGoodsesReq 获取用户商品收藏信息请求参数
type QueryUserFavoriteGoodsesReq struct {
	UserID int `form:"userID" binding:"required"`
}

// QueryUserFavoriteGoodses 获取用户商品收藏信息
// @Summary 获取用户商品收藏信息
// @Produce json
// @Security ApiKeyAuth
// @Param userID query int true "用户ID"
// @Success 200 {object} models.Userfavoritegoods
// @Failure 500 {object} app.Response
// @Router /User/QueryUserFavoriteGoodses [get]
// @Tags 用户信息
func QueryUserFavoriteGoodses(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req QueryUserFavoriteGoodsesReq
	if err := appG.C.ShouldBindQuery(&req); err != nil {
		logger.GetLogger().Errorf("QueryUserFavoriteGoodses failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	userFavoriteGoodses, err := models.GetUserFavoriteGoodses(req.UserID)
	if err != nil {
		// 查询失败
		logger.GetLogger().Errorf("GetUserAuthStatus failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}

	// 查询成功
	logger.GetLogger().Debugln("QueryUserFavoriteGoodses successed: %v", userFavoriteGoodses)
	appG.Response(http.StatusOK, e.SUCCESS, userFavoriteGoodses)
}

// UpdateUserFavoriteGoodsReq 更新用户商品收藏信息请求参数
type UpdateUserFavoriteGoodsReq struct {
	UserID  int `form:"userID" binding:"required"`
	GoodsID int `form:"goodsID" binding:"required"`
}

// AddUserFavoriteGoods 添加用户商品收藏信息
// @Summary 添加用户商品收藏信息
// @Produce json
// @Security ApiKeyAuth
// @Param userID query int true "用户ID"
// @Param goodsID query int true "商品ID"
// @Success 200 {object} app.Response
// @Failure 500 {object} app.Response
// @Router /User/AddUserFavoriteGoods [post]
// @Tags 用户信息
func AddUserFavoriteGoods(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req UpdateUserFavoriteGoodsReq
	if err := appG.C.ShouldBind(&req); err != nil {
		logger.GetLogger().Errorf("AddUserFavoriteGoods failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	if err := models.InsertUserFavoriteGoods(req.UserID, req.GoodsID); err != nil {
		// 执行失败
		logger.GetLogger().Errorf("AddUserFavoriteGoods failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_OPERATION_FAILED, nil)
		return
	}

	// 执行成功
	logger.GetLogger().Debugln("AddUserFavoriteGoods successed: %v", "ok")
	appG.Response(http.StatusOK, e.SUCCESS, "")
}

// RemoveUserFavoriteGoods 移除用户商品收藏信息
// @Summary 移除用户商品收藏信息
// @Produce json
// @Security ApiKeyAuth
// @Param userID query int true "用户ID"
// @Param goodsID query int true "商品ID"
// @Success 200 {object} app.Response
// @Failure 500 {object} app.Response
// @Router /User/RemoveUserFavoriteGoods [post]
// @Tags 用户信息
func RemoveUserFavoriteGoods(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req UpdateUserFavoriteGoodsReq
	if err := appG.C.ShouldBind(&req); err != nil {
		logger.GetLogger().Errorf("RemoveUserFavoriteGoods failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	if err := models.DelUserFavoriteGoods(req.UserID, req.GoodsID); err != nil {
		// 执行失败
		logger.GetLogger().Errorf("RemoveUserFavoriteGoods failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_OPERATION_FAILED, nil)
		return
	}

	// 执行成功
	logger.GetLogger().Debugln("RemoveUserFavoriteGoods successed: %v", "ok")
	appG.Response(http.StatusOK, e.SUCCESS, "")
}

// QueryMessageBoardReq 获取用户留言板信息请求参数
type QueryMessageBoardReq struct {
	UserID int `form:"userID" binding:"required"`
}

// QueryMessageBoard 获取用户留言板信息
// @Summary 获取用户留言板信息
// @Produce json
// @Security ApiKeyAuth
// @Param userID query int true "用户ID"
// @Success 200 {object} models.Messageboard
// @Failure 500 {object} app.Response
// @Router /User/QueryMessageBoard [get]
// @Tags 用户信息
func QueryMessageBoard(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req QueryMessageBoardReq
	if err := appG.C.ShouldBindQuery(&req); err != nil {
		logger.GetLogger().Errorf("QueryMessageBoard failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	messageBoards, err := models.GetMessageBoard(req.UserID)
	if err != nil {
		// 查询失败
		logger.GetLogger().Errorf("QueryMessageBoard failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}

	// 查询成功
	logger.GetLogger().Debugln("QueryMessageBoard successed: %v", messageBoards)
	appG.Response(http.StatusOK, e.SUCCESS, messageBoards)
}

// AddMessageBoardReq 添加用户留言板信息请求参数
type AddMessageBoardReq struct {
	UserID     int    `form:"userID" binding:"required"`
	Message    string `form:"message" binding:"required"`
	ContactNum string `form:"contactNum" binding:"required"`
}

// AddMessageBoard 添加用户留言板信息
// @Summary 添加用户留言板信息
// @Produce json
// @Security ApiKeyAuth
// @Param userID query int true "用户ID"
// @Param message query string true "留言信息"
// @Param contactNum query string true "联系电话"
// @Success 200 {object} app.Response
// @Failure 500 {object} app.Response
// @Router /User/AddMessageBoard [post]
// @Tags 用户信息
func AddMessageBoard(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req AddMessageBoardReq
	if err := appG.C.ShouldBind(&req); err != nil {
		logger.GetLogger().Errorf("AddMessageBoard failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	if errCode := models.InsertMessageBoard(req.UserID, req.Message, req.ContactNum); errCode != 0 {
		// 执行失败
		logger.GetLogger().Errorf("AddMessageBoard failed: %s", e.GetMsg(errCode))
		appG.Response(http.StatusBadRequest, errCode, nil)
		return
	}

	// 执行成功
	logger.GetLogger().Debugln("AddMessageBoard successed: %v", "ok")
	appG.Response(http.StatusOK, e.SUCCESS, "")
}

// UpdateUserAccountStatusReq 更新用户状态请求参数
type UpdateUserAccountStatusReq struct {
	UserID        int `form:"userID" binding:"required"`
	AccountStatus int `form:"accountStatus" binding:"required"`
}

// UpdateUserAccountStatus 更新用户状态
// @Summary 更新用户状态
// @Produce json
// @Security ApiKeyAuth
// @Param userID query int true "用户ID"
// @Param accountStatus query int true "账户状态 -  4:正常 6:注销（停用）"
// @Success 200 {object} app.Response
// @Failure 500 {object} app.Response
// @Router /User/UpdateUserAccountStatus [post]
// @Tags 用户信息
func UpdateUserAccountStatus(c *gin.Context) {
	appG := app.Gin{C: c}

	// 获取请求参数
	var req UpdateUserAccountStatusReq
	if err := appG.C.ShouldBind(&req); err != nil {
		logger.GetLogger().Errorf("UpdateUserAccountStatus failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	if err := models.UpdateUserAccountStatus(req.UserID, req.AccountStatus); err != nil {
		// 执行失败
		logger.GetLogger().Errorf("UpdateUserAccountStatus failed: %s", err.Error())
		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
		return
	}

	// 执行成功
	logger.GetLogger().Debugln("UpdateUserAccountStatus successed: %v", "ok")
	appG.Response(http.StatusOK, e.SUCCESS, "ok")
}
