package twi

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"

	"github.com/33cn/chain33/common/address"
	"github.com/dghubble/oauth1"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"courseSign/server/global"
	"courseSign/server/model/common/request"
	"courseSign/server/model/common/response"
	"courseSign/server/model/system"
	systemReq "courseSign/server/model/system/request"
	"courseSign/server/model/twi"
	twiReq "courseSign/server/model/twi/request"
	"courseSign/server/service"
	"courseSign/server/utils"
	"courseSign/server/utils/TwiApi"
)

type TwiMetamaskApi struct {
}

var twiMetamaskService      = service.ServiceGroupApp.TwiServiceGroup.TwiMetamaskService
var jwtService              = service.ServiceGroupApp.SystemServiceGroup.JwtService

// CreateTwiMetamask 创建TwiMetamask
// @Tags TwiMetamask
// @Summary 创建TwiMetamask
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body twi.TwiMetamask true "创建TwiMetamask"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /twiMetamask/createTwiMetamask [post]
func (twiMetamaskApi *TwiMetamaskApi) CreateTwiMetamask(c *gin.Context) {
	var twiMetamask twi.TwiMetamask
	err := c.ShouldBindJSON(&twiMetamask)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
    verify := utils.Rules{
        "Address":{utils.NotEmpty()},
    }
	if err := utils.Verify(twiMetamask, verify); err != nil {
    		response.FailWithMessage(err.Error(), c)
    		return
    	}
	if err := twiMetamaskService.CreateTwiMetamask(twiMetamask); err != nil {
        global.GVA_LOG.Error("创建失败!", zap.Error(err))
		response.FailWithMessage("创建失败", c)
	} else {
		response.OkWithMessage("创建成功", c)
	}
}

// DeleteTwiMetamask 删除TwiMetamask
// @Tags TwiMetamask
// @Summary 删除TwiMetamask
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body twi.TwiMetamask true "删除TwiMetamask"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /twiMetamask/deleteTwiMetamask [delete]
func (twiMetamaskApi *TwiMetamaskApi) DeleteTwiMetamask(c *gin.Context) {
	var twiMetamask twi.TwiMetamask
	err := c.ShouldBindJSON(&twiMetamask)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := twiMetamaskService.DeleteTwiMetamask(twiMetamask); err != nil {
        global.GVA_LOG.Error("删除失败!", zap.Error(err))
		response.FailWithMessage("删除失败", c)
	} else {
		response.OkWithMessage("删除成功", c)
	}
}

// DeleteTwiMetamaskByIds 批量删除TwiMetamask
// @Tags TwiMetamask
// @Summary 批量删除TwiMetamask
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "批量删除TwiMetamask"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
// @Router /twiMetamask/deleteTwiMetamaskByIds [delete]
func (twiMetamaskApi *TwiMetamaskApi) DeleteTwiMetamaskByIds(c *gin.Context) {
	var IDS request.IdsReq
    err := c.ShouldBindJSON(&IDS)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := twiMetamaskService.DeleteTwiMetamaskByIds(IDS); err != nil {
        global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
		response.FailWithMessage("批量删除失败", c)
	} else {
		response.OkWithMessage("批量删除成功", c)
	}
}

// UpdateTwiMetamask 更新TwiMetamask
// @Tags TwiMetamask
// @Summary 更新TwiMetamask
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body twi.TwiMetamask true "更新TwiMetamask"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /twiMetamask/updateTwiMetamask [put]
func (twiMetamaskApi *TwiMetamaskApi) UpdateTwiMetamask(c *gin.Context) {
	var twiMetamask twi.TwiMetamask
	err := c.ShouldBindJSON(&twiMetamask)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
      verify := utils.Rules{
          "Address":{utils.NotEmpty()},
      }
    if err := utils.Verify(twiMetamask, verify); err != nil {
      	response.FailWithMessage(err.Error(), c)
      	return
     }
     if twiMetamask.Invitor != "" {
     	err = address.CheckAddress(twiMetamask.Invitor,-1)
     	if err != nil {
			response.FailWithMessage(err.Error(), c)
			return
		}
	 }
	if err := twiMetamaskService.UpdateTwiMetamask(twiMetamask); err != nil {
        global.GVA_LOG.Error("更新失败!", zap.Error(err))
		response.FailWithMessage("更新失败", c)
	} else {
		response.OkWithMessage("更新成功", c)
	}
}

// FindTwiMetamask 用id查询TwiMetamask
// @Tags TwiMetamask
// @Summary 用id查询TwiMetamask
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query twi.TwiMetamask true "用id查询TwiMetamask"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /twiMetamask/findTwiMetamask [get]
func (twiMetamaskApi *TwiMetamaskApi) FindTwiMetamask(c *gin.Context) {
	var twiMetamask twi.TwiMetamask
	err := c.ShouldBindQuery(&twiMetamask)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if retwiMetamask, err := twiMetamaskService.GetTwiMetamask(twiMetamask.ID); err != nil {
        global.GVA_LOG.Error("查询失败!", zap.Error(err))
		response.FailWithMessage("查询失败", c)
	} else {
		response.OkWithData(gin.H{"retwiMetamask": retwiMetamask}, c)
	}
}

// GetTwiMetamaskList 分页获取TwiMetamask列表
// @Tags TwiMetamask
// @Summary 分页获取TwiMetamask列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query twiReq.TwiMetamaskSearch true "分页获取TwiMetamask列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /twiMetamask/getTwiMetamaskList [get]
func (twiMetamaskApi *TwiMetamaskApi) GetTwiMetamaskList(c *gin.Context) {
	var pageInfo twiReq.TwiMetamaskSearch
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if list, total, err := twiMetamaskService.GetTwiMetamaskInfoList(pageInfo); err != nil {
	    global.GVA_LOG.Error("获取失败!", zap.Error(err))
        response.FailWithMessage("获取失败", c)
    } else {
        response.OkWithDetailed(response.PageResult{
            List:     list,
            Total:    total,
            Page:     pageInfo.Page,
            PageSize: pageInfo.PageSize,
        }, "获取成功", c)
    }
}

// Login metamask 验签登录
// @Tags TwiMetamask
// @Summary 验签登录
// @accept application/json
// @Produce application/json
// @Param data query twiReq.TwiUserLogin true "验签登录 Timestamp:1234567890"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /twiMetamask/login [get]
func (twiMetamaskApi *TwiMetamaskApi) Login(c *gin.Context) {
	var pageInfo twiReq.TwiUserLogin
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err = utils.Verify(pageInfo,utils.MetaMaskVerify);err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	global.GVA_LOG.Info("params",zap.Any("KEY",pageInfo))
	signTime,err := utils.GetTimeStampFromMsg(pageInfo.Msg)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if time.Now().Unix() - 1800 > signTime {
		response.FailWithMessage("签名时间已过期，请重新签名", c)
		return
	}
	var invitorId int64
	if pageInfo.Invitor != "" {
		if err := address.CheckAddress(pageInfo.Invitor,-1);err != nil {
			response.FailWithMessage("Wrong Invitor Address type",c)
			return
		}
		if invitor,err := twiMetamaskService.GetTwiMetamaskByAddr(pageInfo.Invitor);err != nil {
			response.FailWithMessage("Invitor Address not login",c)
			return
		} else {
			invitorId = int64(invitor.ID)
		}
	}
	// 先从 twi_metamask 判断用户是否存在
	info,err := twiMetamaskService.GetTwiMetamaskByAddr(pageInfo.Addr)
	if err != nil && err != gorm.ErrRecordNotFound{
		global.GVA_LOG.Error("GetTwiMetamaskByAddr err:",zap.Error(err))
		response.FailWithMessage(err.Error(), c)
		return
	} else if err != nil && err == gorm.ErrRecordNotFound {
		err = twiMetamaskService.CreateTwiMetamask(twi.TwiMetamask{
			Address:    pageInfo.Addr,
			Invitor:	pageInfo.Invitor,
			InvitorId:  invitorId,
		})
		if err != nil {
			global.GVA_LOG.Error("CreateTwiMetamask err:",zap.Error(err))
			response.FailWithMessage("create addr fail", c)
			return
		}
		info,err = twiMetamaskService.GetTwiMetamaskByAddr(pageInfo.Addr)
		if err != nil {
			global.GVA_LOG.Error("GetTwiMetamaskByAddr err:",zap.Error(err))
			response.FailWithMessage(err.Error(), c)
			return
		}
	}

	// jwt保存
	twiMetamaskApi.TokenNext(c,info)
}

func (twiMetamaskApi *TwiMetamaskApi)CheckTwiBind(user twi.TwiMetamask) (*url.URL,error) {
	url := &url.URL{}
	if global.GVA_CONFIG.Twitter.ApiKey == "" || global.GVA_CONFIG.Twitter.ApiSecret == "" {
		return url,errors.New("参数异常,consumerKey Secret未设置")
	}
	config := TwiApi.GetOauthConfig(global.GVA_CONFIG.Twitter.ApiKey,global.GVA_CONFIG.Twitter.ApiSecret)

	reqToken,reqSecret,err := config.RequestToken()
	if err != nil {
		return url,err
	}
	global.GVA_LOG.Info("Step 2  授权登录:",zap.String("req_token",reqToken),zap.String("req_secret",reqSecret))
	url,err = config.AuthorizationURL(reqToken)
	if err != nil {
		global.GVA_LOG.Error("AuthorizationURL 失败!", zap.Error(err))
		return url,err
	}
	user.ReqToken = reqToken
	user.ReqSecret = reqSecret
	user.AuthUrl = url.String()
	global.GVA_LOG.Info("Step 2  浏览器地址:",zap.String("url",url.String()))

	uid := utils.UniqueId(int64(user.ID))
	if userCache,err := jwtService.GetOauthInfo(uid);err == redis.Nil {
		if err := jwtService.SetOauthInfo(user,uid);err != nil {
			global.GVA_LOG.Error("CheckTwiBind SetOauthInfo 失败!", zap.Error(err))
			return url,err
		}
	} else if err != nil {
		global.GVA_LOG.Error("CheckTwiBind GetOauthInfo 获取失败!", zap.Error(err))
		return url,err
	} else {
		userCache.ReqToken = reqToken
		userCache.ReqSecret = reqSecret
		userCache.AuthUrl = url.String()
		if err := jwtService.SetOauthInfo(userCache,uid);err != nil {
			global.GVA_LOG.Error("CheckTwiBind SetOauthInfo 更新失败!", zap.Error(err))
			return url,err
		}
	}

	byteUser,err := json.Marshal(user)
	if err != nil {
		return url,err
	}
	err = jwtService.SetReqTokenInfoTwi(byteUser,reqToken)
	if err != nil {
		return url,err
	}

	return url,nil
}

// TokenNext 登录以后签发jwt
func (twiMetamaskApi *TwiMetamaskApi) TokenNext(c *gin.Context, user twi.TwiMetamask) {
	uid := fmt.Sprintf("addr-%d",user.ID)
	if _,err := jwtService.GetOauthInfo(uid);err == redis.Nil {
		if err := jwtService.SetOauthInfo(user,uid);err != nil {
			global.GVA_LOG.Error("SetOauthInfo 失败!", zap.Error(err))
			response.FailWithMessage("设置user cache失败", c)
			return
		}
	} else if err != nil {
		global.GVA_LOG.Error("GetOauthInfo 获取失败!", zap.Error(err))
		response.FailWithMessage("获取用户信息状态失败", c)
		return
	}
	j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名
	claims := j.CreateClaims(systemReq.BaseClaims{
		ID:          user.ID,
		NickName:    user.Address,
		Username:    user.Address,
	})
	token, err := j.CreateToken(claims)
	if err != nil {
		global.GVA_LOG.Error("获取token失败!", zap.Error(err))
		response.FailWithMessage("获取token失败", c)
		return
	}

	if jwtStr, err := jwtService.GetRedisJWT(user.Address); err == redis.Nil {
		if err := jwtService.SetRedisJWT(token, user.Address); err != nil {
			global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
			response.FailWithMessage("设置登录状态失败", c)
			return
		}
		response.OkWithData(token, c)
	} else if err != nil {
		global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
		response.FailWithMessage("设置登录状态失败", c)
	} else {
		var blackJWT system.JwtBlacklist
		blackJWT.Jwt = jwtStr
		if err := jwtService.JsonInBlacklist(blackJWT); err != nil {
			response.FailWithMessage("jwt作废失败", c)
			return
		}
		if err := jwtService.SetRedisJWT(token, user.Address); err != nil {
			response.FailWithMessage("设置登录状态失败", c)
			return
		}
		response.OkWithData(token, c)
	}
}

// CallBack get oauthToken and oauthVerify
// @Tags TwiMetamask
// @Summary get oauthToken and oauthVerify
// @accept application/json
// @Produce application/json
// @Param data query twi.TwiMetamask true "回调接口"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /twiMetamask/callback [get]
func (twiMetamaskApi *TwiMetamaskApi) CallBack(c *gin.Context) {
	var pageInfo twi.TwiMetamask
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if pageInfo.OauthToken == "" || pageInfo.OauthVerifier == "" {
		response.FailWithMessage("参数异常,oauth-token oauth-verifier 不能为空", c)
		return
	}
	global.GVA_LOG.Info("step 3 callback:",zap.String("oauth-token",pageInfo.OauthToken),zap.String("oauth-verifier",pageInfo.OauthVerifier))
	if global.GVA_CONFIG.Twitter.ApiKey == "" || global.GVA_CONFIG.Twitter.ApiSecret == "" {
		response.FailWithMessage("参数异常,consumerKey Secret未设置", c)
		return
	}

	twiMetamaskApi.SetAccessToken(pageInfo.OauthToken,pageInfo.OauthVerifier,c)
}

func (twiMetamaskApi *TwiMetamaskApi)SetAccessToken(token string,oauthVerifier string,c *gin.Context)  {

	config := TwiApi.GetOauthConfig(global.GVA_CONFIG.Twitter.ApiKey,global.GVA_CONFIG.Twitter.ApiSecret)
	var userReqToken twi.TwiMetamask
	tokenInfo,err := jwtService.GetReqTokenInfoTwi(token)
	if err != nil {
		global.GVA_LOG.Error("GetReqTokenInfoJWT err",zap.Error(err))
		response.FailWithMessage("获取req_token缓存失败", c)
		return
	}
	err = json.Unmarshal([]byte(tokenInfo),&userReqToken)
	if err != nil {
		global.GVA_LOG.Error("Unmarshal err",zap.Error(err))
		response.FailWithMessage("parse req_token缓存失败", c)
		return
	}
	accessToken,accessSecret ,err := config.AccessToken(token,userReqToken.ReqSecret,oauthVerifier)
	if err != nil {
		global.GVA_LOG.Error("AccessToken err",zap.Error(err))
		response.FailWithMessage("获取access_token 失败", c)
		return
	}
	global.GVA_LOG.Debug("step 4 get user accessToken info ",zap.String("token",accessToken),zap.String("secret",accessSecret))

	// /2/users/me
	oauthToken := oauth1.NewToken(accessToken,accessSecret)

	httpClient := config.Client(oauth1.NoContext, oauthToken)
	var isTwiAuth bool
	// 查询用户信息
	// path := "https://api.twitter.com/2/users/me"
	path := TwiApi.UserAuthLookupEndpoint.Url(TwiApi.TwiApiUrl)
	global.GVA_LOG.Info("twi api ",zap.String("path",path))
	resp, _ := httpClient.Get(path)
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)
	global.GVA_LOG.Info("Raw Response Body:", zap.Any("users/me",string(body)))
	var resMe twiReq.ResTwiUserMe
	err = json.Unmarshal(body,&resMe)
	if err != nil {
		global.GVA_LOG.Error("decode 2/users/me 失败",zap.Error(err))
		response.FailWithMessage("获取推特信息失败", c)
		return
	}
	isTwiAuth = true
	TwiApi.GetLimitRate(resp.Header,resp.Request.URL.String())

	// 检查地址是否已经绑定推特
	if checkUser,err := twiMetamaskService.GetTwiMetamaskByAddr(userReqToken.Address);err != nil {
		if err != gorm.ErrRecordNotFound {
			global.GVA_LOG.Error("GetTwiMetamaskByAddr err",zap.Error(err))
			response.FailWithMessage("获取地址信息失败", c)
			return
		}
	} else {
		if checkUser.TwiId != "" {
			if checkUser.TwiId != resMe.Data.Id {
				global.GVA_LOG.Error("already bind ",zap.String("bind username",checkUser.TwiUsername),zap.String("new username",resMe.Data.Username))
				response.FailWithMessage("地址已经绑定推特账户:"+checkUser.TwiUsername, c)
				return

			} else {
				global.GVA_LOG.Error("already bind ",zap.String("bind username",checkUser.TwiUsername),zap.String("new username",resMe.Data.Username))
				response.FailWithMessage("无需重复绑定",c)
				return
			}
		}
	}

	// 检查推特是否绑定其他地址
	if checkTwi,err := twiMetamaskService.GetTwiMetamaskByName(resMe.Data.Username);err != nil {
		if err != gorm.ErrRecordNotFound {
			global.GVA_LOG.Error("GetTwiMetamaskByAddr err",zap.Error(err))
			response.FailWithMessage("获取地址信息失败", c)
			return
		}
	} else {
		if strings.ToLower(checkTwi.Address) != strings.ToLower(userReqToken.Address) {
				global.GVA_LOG.Error("already bind ",zap.String("bind addr",checkTwi.Address),zap.String("new username",userReqToken.Address))
				response.FailWithMessage("推特已经绑定地址:"+checkTwi.Address, c)
				return
		} else {
			global.GVA_LOG.Error("already bind ",zap.String("bind addr",checkTwi.Address),zap.String("new username",userReqToken.Address))
			response.FailWithMessage("无需重复绑定",c)
			return
		}
	}

	userReqToken.AccessToken = accessToken
	userReqToken.AccessSecret = accessSecret
	userReqToken.TwiUsername = resMe.Data.Username
	userReqToken.IsTwiAuth = &isTwiAuth
	userReqToken.TwiName = resMe.Data.Name
	userReqToken.TwiId = resMe.Data.Id
	userReqToken.TwiPhotoUrl = resMe.Data.ProfileImageUrl

	uid := utils.UniqueId(int64(userReqToken.ID))
	if userCache,err := jwtService.GetOauthInfo(uid);err == redis.Nil {
		if err := jwtService.SetOauthInfo(userReqToken,uid);err != nil {
			global.GVA_LOG.Error("SetAccessToken SetOauthInfo 失败!", zap.Error(err))
			response.FailWithMessage("设置user失败", c)
			return
		}
	} else if err != nil {
		global.GVA_LOG.Error("SetAccessToken GetOauthInfo 获取失败!", zap.Error(err))
		response.FailWithMessage("获取用户信息状态失败", c)
		return
	} else {
		userCache.AccessToken = accessToken
		userCache.AccessSecret = accessSecret
		userCache.TwiUsername = resMe.Data.Username
		userCache.IsTwiAuth = &isTwiAuth
		userCache.TwiName = resMe.Data.Name
		userCache.TwiId = resMe.Data.Id
		userCache.TwiPhotoUrl = resMe.Data.ProfileImageUrl
		if err := jwtService.SetOauthInfo(userCache,uid);err != nil {
			global.GVA_LOG.Error("SetOauthInfo 更新失败!", zap.Error(err))
			response.FailWithMessage("更新用户缓存信息失败", c)
			return
		}
	}

	err = global.GVA_REDIS.Set(context.Background(),token,nil,time.Second).Err()
	if err != nil {
		global.GVA_LOG.Error("设置过期失败",zap.Error(err))
		response.FailWithMessage("缓存设置过期 失败", c)
		return
	}

	if err := twiMetamaskService.SetUserBindTwi(userReqToken.Address,resMe.Data); err != nil {
		global.GVA_LOG.Error("绑定失败!", zap.Error(err))
		response.FailWithMessage("绑定失败", c)
	} else {
		response.OkWithMessage("绑定成功", c)
	}
}


// Auth metamask 等 验签登录
// @Tags TwiMetamask
// @Summary 验签登录
// @accept application/json
// @Produce application/json
// @Param data query twi.AuthLogin true "登录"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /twiMetamask/auth [get]
func (twiMetamaskApi *TwiMetamaskApi) Auth(c *gin.Context) {
	var pageInfo twi.AuthLogin
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	global.GVA_LOG.Info("params",zap.Any("KEY",pageInfo))
	if err = utils.Verify(pageInfo,utils.AuthVerify);err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	j := utils.NewJWT()
	// parseToken 解析token包含的信息
	claims, err := j.ParseToken(pageInfo.Token)
	if err != nil {
		global.GVA_LOG.Error("parse token",zap.Error(err))
		if err == utils.TokenExpired {
			response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c)
			c.Abort()
			return
		}
		response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
		c.Abort()
		return
	}
	if err := address.CheckAddress(claims.Username,-1);err != nil {
		response.FailWithDetailed(gin.H{"reload": true}, "非法地址或非法访问", c)
		c.Abort()
		return
	}

	user,err := twiMetamaskService.GetTwiMetamaskByAddr(claims.Username)
	if err != nil {
		global.GVA_LOG.Error("GetTwiMetamaskByAddr err",zap.Error(err))
		response.FailWithMessage(err.Error(), c)
		return
	}
	switch pageInfo.Type {
	case twi.AuthTypeTwitter:
		// 检查是否绑定 获取access token
		url,err := twiMetamaskApi.CheckTwiBind(user)
		if err != nil {
			global.GVA_LOG.Error("CheckTwiBind err",zap.Error(err))
			response.FailWithMessage(err.Error(), c)
			return
		}
		c.Redirect(http.StatusMovedPermanently,url.String())
	default:
		response.FailWithMessage("未知授权类型", c)
		return
	}

}

// GetTwiByAddr 用获取信息
// @Tags TwiMetamask
// @Summary 用获取信息
// @accept application/json
// @Produce application/json
// @Param data query twi.TwiMetamask true "获取信息"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /twiMetamask/twi [get]
func (twiMetamaskApi *TwiMetamaskApi) GetTwiByAddr(c *gin.Context) {
	var pageInfo twi.TwiMetamask
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if pageInfo.Address == "" {
		response.FailWithMessage("address empty", c)
		return
	}

	if user,err := twiMetamaskService.GetTwiMetamaskByAddr(pageInfo.Address);err != nil {
		global.GVA_LOG.Error("查询失败!", zap.Error(err))
		response.FailWithMessage(err.Error(), c)
	} else {
		response.OkWithData(twi.ConvertCommonInfo(user), c)
	}
}

// GetInfo 用获取信息
// @Tags TwiMetamask
// @Summary 用获取信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /twiMetamask/info [get]
func (twiMetamaskApi *TwiMetamaskApi) GetInfo(c *gin.Context) {
	addr := c.Request.Header.Get("address")
	//addr,exist := c.Get("address")
	if addr == "" {
		response.FailWithMessage("地址异常", c)
		return
	}

	if user,err := twiMetamaskService.GetTwiMetamaskByAddr(addr);err != nil {
		global.GVA_LOG.Error("查询失败!", zap.Error(err))
		response.FailWithMessage(err.Error(), c)
	} else {
		response.OkWithData(gin.H{"data": twi.ConvertCommonInfo(user)}, c)
	}
}

// TeleCallback 获取telegram信息
// @Tags TeleCallback
// @Summary 获取绑定telegram信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query twi.TelegramUserCallback true "获取telegram信息"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /twiMetamask/teleCallback [get]
func (twiMetamaskApi *TwiMetamaskApi) TeleCallback(c *gin.Context) {
	var pageInfo twi.TelegramUserCallback
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	global.GVA_LOG.Info("params",zap.Any("KEY",pageInfo))
	if err = utils.Verify(pageInfo,utils.AuthVerify);err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	j := utils.NewJWT()
	// parseToken 解析token包含的信息
	claims, err := j.ParseToken(pageInfo.Token)
	if err != nil {
		global.GVA_LOG.Error("parse token",zap.Error(err))
		if err == utils.TokenExpired {
			response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c)
			c.Abort()
			return
		}
		response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
		c.Abort()
		return
	}
	if err := address.CheckAddress(claims.Username,-1);err != nil {
		response.FailWithDetailed(gin.H{"reload": true}, "非法地址或非法访问", c)
		c.Abort()
		return
	}
	global.GVA_LOG.Info("TeleCallback",zap.Any("request",pageInfo))
	if pageInfo.Username == "" {
		pageInfo.Username = pageInfo.FirstName + " " + pageInfo.LastName
		if pageInfo.Username == "" {
			response.FailWithMessage("参数异常", c)
			return
		}
	}

	switch pageInfo.Type {
	case twi.AuthTypeTele:
		// 检查是否绑定 获取access token
		twiMetamaskApi.TeleBind(claims.Username,pageInfo,c)

	default:
		response.FailWithMessage("未知授权类型", c)
		return
	}


}

func (twiMetamaskApi *TwiMetamaskApi) TeleBind(addr string,callback twi.TelegramUserCallback,c *gin.Context) {
	user,err := twiMetamaskService.GetTwiMetamaskByAddr(addr)
	if err != nil {
		global.GVA_LOG.Error("GetTwiMetamaskByAddr err",zap.Error(err))
		response.FailWithMessage(err.Error(), c)
		return
	}
	if *user.IsTeleAuth == true {
		if user.TeleUsername != callback.Username {
			global.GVA_LOG.Error("addr already bind other telegram account",zap.String("bind",user.TeleUsername),zap.String("req",callback.Username))
			response.FailWithMessage("addr already bind telegram account "+user.TeleUsername, c)
			return
		} else {
			response.FailWithMessage("已绑定", c)
			return
		}
	}
	if user,err := twiMetamaskService.GetTelegramByName(callback.Username);err != nil {
		if err != gorm.ErrRecordNotFound {
			global.GVA_LOG.Error("查询失败!", zap.Error(err))
			response.FailWithMessage(err.Error(), c)
		}

	} else {
		if user.Address != addr {
			global.GVA_LOG.Error("推特已绑定其他地址",zap.String("bind",user.Address),zap.String("req",addr))
			response.FailWithMessage("telegram account already bind address "+user.Address, c)
			return
		} else {
			response.FailWithMessage("已绑定", c)
			return
		}

	}
	var isTeleAuth bool
	isTeleAuth = true
	user.IsTeleAuth = &isTeleAuth
	user.TeleUsername = callback.Username
	user.TeleFirstName = callback.FirstName
	user.TeleLastName = callback.LastName
	user.TelePhotoUrl = callback.PhotoUrl
	user.TeleId = strconv.FormatInt(callback.Id,10)
	if err := twiMetamaskService.UpdateTwiMetamask(user);err != nil {
		global.GVA_LOG.Error("UpdateTwiMetamask err!", zap.Error(err))
		response.FailWithMessage("绑定出错！", c)
	} else {

		uid := utils.UniqueId(int64(user.ID))
		if userCache,err := jwtService.GetOauthInfo(uid);err == redis.Nil {
			if err := jwtService.SetOauthInfo(user,uid);err != nil {
				global.GVA_LOG.Error("SetOauthInfo 失败!", zap.Error(err))
				response.FailWithMessage("设置user失败", c)
				return
			}
		} else if err != nil {
			global.GVA_LOG.Error("GetOauthInfo 获取失败!", zap.Error(err))
			response.FailWithMessage("获取用户信息状态失败", c)
			return
		} else {
			userCache.IsTeleAuth = &isTeleAuth
			userCache.TeleUsername = callback.Username
			userCache.TeleFirstName = callback.FirstName
			userCache.TeleLastName = callback.LastName
			userCache.TelePhotoUrl = callback.PhotoUrl
			userCache.TeleId = strconv.FormatInt(callback.Id,10)
			userCache.TeleHash = callback.Hash

			if err := jwtService.SetOauthInfo(userCache,uid);err != nil {
				global.GVA_LOG.Error("SetOauthInfo 更新失败!", zap.Error(err))
				response.FailWithMessage("更新用户缓存信息失败", c)
				return
			}
		}

		response.OkWithMessage("绑定成功", c)
	}

}

// UnbindTwitter 解绑twitter
// @Tags TwiMetamask
// @Summary 解绑twitter
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body twi.TwiMetamask true "解绑twitter"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /twiMetamask/unbindTwitter [put]
func (twiMetamaskApi *TwiMetamaskApi) UnbindTwitter(c *gin.Context) {
	var twiMetamask twi.TwiMetamask
	err := c.ShouldBindJSON(&twiMetamask)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	verify := utils.Rules{
		"ID":{utils.NotEmpty()},
	}
	if err := utils.Verify(twiMetamask, verify); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := twiMetamaskService.UnbindTwiMetamaskTwitter(twiMetamask.ID); err != nil {
		global.GVA_LOG.Error("解绑失败!", zap.Error(err))
		response.FailWithMessage("解绑失败", c)
	} else {
		// 解绑成功 更新redis信息
		uid := utils.UniqueId(int64(twiMetamask.ID))
		if userCache,err := jwtService.GetOauthInfo(uid);err == redis.Nil {

			// if err := jwtService.SetOauthInfo(user,uid);err != nil {
			// 	global.GVA_LOG.Error("SetOauthInfo 失败!", zap.Error(err))
			// 	response.FailWithMessage("设置user失败", c)
			// 	return
			// }
		} else if err != nil {
			global.GVA_LOG.Error("GetOauthInfo 获取失败!", zap.Error(err))
			response.FailWithMessage("获取用户信息状态失败", c)
			return
		} else {
			userCache.AccessToken = ""
			userCache.AccessSecret = ""
			userCache.TwiUsername = ""
			*userCache.IsTwiAuth = false
			userCache.TwiName = ""
			userCache.TwiId = ""
			userCache.TwiPhotoUrl = ""
			if err := jwtService.SetOauthInfo(userCache,uid);err != nil {
				global.GVA_LOG.Error("SetOauthInfo 更新失败!", zap.Error(err))
				response.FailWithMessage("更新用户缓存信息失败", c)
				return
			}
		}
		response.OkWithMessage("解绑成功", c)
	}
}

// UnbindTelegram 解绑telegram
// @Tags TwiMetamask
// @Summary 解绑twitter
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body twi.TwiMetamask true "解绑telegram"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"解绑成功"}"
// @Router /twiMetamask/unbindTelegram [put]
func (twiMetamaskApi *TwiMetamaskApi) UnbindTelegram(c *gin.Context) {
	var twiMetamask twi.TwiMetamask
	err := c.ShouldBindJSON(&twiMetamask)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	verify := utils.Rules{
		"ID":{utils.NotEmpty()},
	}
	if err := utils.Verify(twiMetamask, verify); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := twiMetamaskService.UnbindTwiMetamaskTelegram(twiMetamask.ID); err != nil {
		global.GVA_LOG.Error("解绑失败!", zap.Error(err))
		response.FailWithMessage("解绑失败", c)
	} else {
		// 解绑成功 更新redis信息
		uid := utils.UniqueId(int64(twiMetamask.ID))
		if userCache,err := jwtService.GetOauthInfo(uid);err == redis.Nil {

			// if err := jwtService.SetOauthInfo(user,uid);err != nil {
			// 	global.GVA_LOG.Error("SetOauthInfo 失败!", zap.Error(err))
			// 	response.FailWithMessage("设置user失败", c)
			// 	return
			// }
		} else if err != nil {
			global.GVA_LOG.Error("GetOauthInfo 获取失败!", zap.Error(err))
			response.FailWithMessage("获取用户信息状态失败", c)
			return
		} else {
			*userCache.IsTeleAuth = false
			userCache.TeleUsername = ""
			userCache.TeleFirstName = ""
			userCache.TeleLastName = ""
			userCache.TelePhotoUrl = ""
			userCache.TeleId = ""
			userCache.TeleHash = ""

			if err := jwtService.SetOauthInfo(userCache,uid);err != nil {
				global.GVA_LOG.Error("SetOauthInfo 更新失败!", zap.Error(err))
				response.FailWithMessage("更新用户缓存信息失败", c)
				return
			}
		}
		response.OkWithMessage("解绑成功", c)
	}
}