package jxcontext

import (
	"errors"
	"net/http"

	"git.rosy.net.cn/jx-callback/business/auth2"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/model/dao"
	"git.rosy.net.cn/jx-callback/globals"
)

type IAuther interface {
	GetAuthID() string
	GetAuthType() string
	GetUserTag() string
}

type Context struct {
	*auth2.Context
	token    string
	userInfo IAuther //*auth.LoginInfo
}

const (
	MaxUserNameLen = 30
)

var (
	AdminCtx *Context
)

func init() {
	AdminCtx = NewWithUserName(nil, model.AdminName, nil, nil)
}

func NewWithOnlyUserName(userName string) (ctx *Context) {
	return NewWithUserName(nil, userName, nil, nil)
}

func NewWithUserName(notUsed interface{}, userName string, w http.ResponseWriter, r *http.Request) (ctx *Context) {
	ctx = &Context{
		token:   userName,
		Context: auth2.NewContext(w, r),
	}
	return ctx
}

func New(notUsed interface{}, token string, w http.ResponseWriter, r *http.Request) (ctx *Context, errCode string, err error) {
	ctx = &Context{
		token:   token,
		Context: auth2.NewContext(w, r),
	}
	if auth2.IsV2Token(token) {
		authInfo, err2 := auth2.GetTokenInfo(token)
		if err = err2; err == nil {
			ctx.userInfo = authInfo
			if authInfo.TokenType != auth2.TokenTypeNormal {
				err = errors.New("需要正式TOKEN")
			}
		}
	} else {
		errCode = model.ErrCodeTokenIsInvalid
		// userInfo, err2 := auth.GetUserInfo(token)
		// if err = err2; err == nil {
		// 	ctx.userInfo = userInfo
		// }
	}
	if err == model.ErrTokenIsInvalid {
		if !globals.IsProductEnv() {
			err = nil
		} else {
			errCode = model.ErrCodeTokenIsInvalid
		}
	}
	if err == model.ErrTokenIsInvalid {
		globals.SugarLogger.Debugf("token is invalid, token:%s", token)
	}
	return ctx, errCode, err
}

func (ctx *Context) GetUserName() string {
	userName := ctx.token
	if ctx.userInfo != nil {
		userName = ctx.userInfo.GetUserTag()
	} else if userName == "" {
		userName = ctx.GetRealRemoteIP()
	}
	if len(userName) > MaxUserNameLen {
		userName = userName[:MaxUserNameLen]
	}
	return userName
}

func (ctx *Context) GetLoginID() string {
	if ctx.userInfo != nil {
		return ctx.userInfo.GetAuthID()
	}
	return ""

}

func (ctx *Context) GetLoginType() string {
	if ctx.userInfo != nil {
		return ctx.userInfo.GetAuthType()
	}
	return ""
}

func (ctx *Context) GetToken() string {
	return ctx.token
}

func (ctx *Context) GetLoginInfo() IAuther {
	return ctx.userInfo
}

func (ctx *Context) GetV2AuthInfo() (authInfo *auth2.AuthInfo, err error) {
	authInfo, ok := ctx.userInfo.(*auth2.AuthInfo)
	if ok {
		return authInfo, nil
	}
	return nil, auth2.ErrNeedV2Token
}

func (ctx *Context) GetTrackInfo() string {
	return ctx.Context.GetTrackInfo() + "," + ctx.GetUserName()
}

func (ctx *Context) GetMobileAndUserID() (mobile, userID string) {
	token := ctx.GetToken()
	if auth2.IsV2Token(token) {
		authInfo, err2 := auth2.GetTokenInfo(token)
		if err2 == nil {
			if authInfo.TokenType == auth2.TokenTypeNormal {
				mobile = authInfo.GetMobile()
				userID = authInfo.GetID()
			}
		}
	} else {
	}
	return mobile, userID
}

func (ctx *Context) GetUserID() (userID string) {
	token := ctx.GetToken()
	authInfo, err2 := auth2.GetTokenInfo(token)
	if err2 == nil {
		if authInfo.TokenType == auth2.TokenTypeNormal {
			userID = authInfo.GetID()
		}
	}
	return userID
}

func (ctx *Context) GetFullUser() (user *model.User) {
	token := ctx.GetToken()
	authInfo, err2 := auth2.GetTokenInfo(token)
	if err2 == nil {
		if authInfo.TokenType == auth2.TokenTypeNormal {
			user, _ = dao.GetUserByID(dao.GetDB(), "user_id", authInfo.GetID())
		}
	}
	return user
}
