package oauth_provider

import (
	"context"
	"git.noahlan.cn/n-admin/n-admin-server/dal/errx"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/ent"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/ent/oauthprovider"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/internal/utils/entx"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/internal/utils/hander"
	"git.noahlan.cn/noahlan/ntool-biz/core/nstatus"
	"git.noahlan.cn/noahlan/ntool-biz/core/nstatus/code"
	"git.noahlan.cn/noahlan/ntool-biz/core/nstatus/msg"

	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/internal/svc"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/types/core"
)

type CreateOauthProviderLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewCreateOauthProviderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateOauthProviderLogic {
	return &CreateOauthProviderLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

// OauthProvider management
func (l *CreateOauthProviderLogic) CreateOauthProvider(in *core.OauthProviderInfo) (*core.BaseIDResp, error) {
	var dbData *ent.OauthProvider
	if err := entx.WithTx(l.ctx, l.svcCtx.DB, func(tx *ent.Tx) error {
		var err error
		if err := l.preCheck(tx, in); err != nil {
			return err
		}
		create := tx.OauthProvider.Create().
			SetName(in.Name).
			SetClientID(in.ClientId).
			SetClientSecret(in.ClientSecret).
			SetRedirectURL(in.RedirectUrl).
			SetScopes(in.Scopes).
			SetAuthURL(in.AuthUrl).
			SetTokenURL(in.TokenUrl).
			SetInfoURL(in.InfoUrl).
			SetDescription(in.Description).
			SetSystem(in.System)
		if in.ClientId != "" && in.ClientSecret != "" {
			create.SetInit(true)
		}
		dbData, err = create.Save(l.ctx)
		if err != nil {
			return hander.HandleEntErr(err, in)
		}
		return nil
	}); err != nil {
		return nil, err
	}

	return &core.BaseIDResp{
		ID:   dbData.ID,
		Code: code.StatusOK,
		Msg:  msg.CreateSuccess,
	}, nil
}

func (l *CreateOauthProviderLogic) preCheck(tx *ent.Tx, in *core.OauthProviderInfo) error {
	if in.Name == "" {
		return nstatus.NewBizErrWithCode(errx.OAuthProviderNameNotEmpty)
	} else {
		exist, err := tx.OauthProvider.Query().Where(oauthprovider.NameEQ(in.Name)).Exist(l.ctx)
		if err != nil {
			return hander.HandleEntErr(err, in)
		}
		if exist {
			return nstatus.NewBizErrWithCode(errx.OAuthProviderNameInUsed)
		}
	}
	return nil
}
