package sys_auth

import (
	"context"
	"kami/internal/errHandler"
	"kami/internal/model"
	"kami/utility/token"
	"kami/utility/verify"

	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/frame/g"

	"kami/internal/model/entity"
	"kami/internal/service"

	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
)

func init() {
	service.RegisterSysAuth(New())
}

func New() *sSysAuth {
	return &sSysAuth{}
}

type sSysAuth struct{}

// LoginWithIFrameAndLogin Iframe和账号可以同时登陆
func (a *sSysAuth) LoginWithIFrameAndLogin(ctx context.Context) (userInfo *entity.V1SysUser, err error) {
	needAuth, userInfo, err := service.SysUser().GetUserFromToken(ctx)
	if err != nil {
		return
	}
	if needAuth && (userInfo == nil || userInfo.Id == "") {
		err = gerror.NewCode(gcode.CodeNotAuthorized, "权限不足")
		return
	}
	if userInfo == nil {
		userInfo = &entity.V1SysUser{}
	}
	return
}

func (a *sSysAuth) LoginWithEverything(ctx context.Context) (output *model.SysAuthLoginWithEverythingOutput, err error) {
	tokenFrom := g.RequestFromCtx(ctx).Request.Header.Get("tokenFrom")
	if tokenFrom == "" {
		err = gerror.NewCode(errHandler.ErrTokenExpired, "token失效")
		return
	}
	tokenStr := token.GetTokenFromCtx(ctx)
	if tokenFrom != "iframe" {
		userToken, err2 := token.ParseUserToken(ctx, tokenStr)
		if err2 != nil {
			return output, err2
		}
		output = &model.SysAuthLoginWithEverythingOutput{
			LoginType: model.LoginTypeAuth,
			UserId:    userToken.UserID,
		}
		return
	}
	frontendModel, err := service.SysConfigDict().GetAESKeyBytes(ctx)
	if err != nil {
		err = gerror.NewCode(errHandler.ErrTokenExpired, "刷新 token 失败")
		return
	}
	tokenByte, err := verify.AesCBCURLDecryptWithBase64(tokenStr, frontendModel.Key, frontendModel.IV)
	if err != nil {
		return
	}
	tokenStruct := struct {
		UserId   string `json:"userId"`
		UserAuth string `json:"userAuth"`
	}{}
	if err = gjson.DecodeTo(tokenByte, &tokenStruct); err != nil {
		err = gerror.NewCode(errHandler.ErrTokenError, "Token格式错误!")
		return
	}
	output = &model.SysAuthLoginWithEverythingOutput{
		LoginType: model.LoginType(tokenStruct.UserAuth),
		UserId:    tokenStruct.UserId,
	}
	return
}

// LoginOnlyIFrame 只能IFrame登录
func (a *sSysAuth) LoginOnlyIFrame(ctx context.Context) (userInfo *entity.V1SysUser, err error) {
	needAuth, userInfo, err := service.SysUser().GetUserFromToken(ctx)
	if err != nil {
		return
	}
	if needAuth {
		err = gerror.NewCode(gcode.CodeNotAuthorized, "权限不足")
		return
	}
	userInfo = &entity.V1SysUser{}
	return
}

// LoginOnlyLogin 只能登录
func (a *sSysAuth) LoginOnlyLogin(ctx context.Context) (userInfo *entity.V1SysUser, err error) {
	needAuth, userInfo, err := service.SysUser().GetUserFromToken(ctx)
	if err != nil {
		return
	}
	if !needAuth {
		err = gerror.NewCode(gcode.CodeNotAuthorized, "权限不足")
	}
	if userInfo == nil || userInfo.Id == "" {
		err = gerror.NewCode(gcode.CodeNotAuthorized, "权限不足")
		return
	}
	return
}
