package auth

import (
	errs "backend/pkg/library/errors"
	memberD "backend/pkg/member/domain/member"
	member "backend/pkg/member/domain/usecase"
	"context"

	"backend/internal/svc"
	"backend/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type LoginLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// NewLoginLogic 使用者登入
func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
	return &LoginLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *LoginLogic) Login(req *types.LoginReq) (resp *types.LoginResp, err error) {
	//var result member.VerifyAuthResultResponse
	switch req.AuthMethod {
	case "credentials":
		cr, err := l.svcCtx.AccountUC.VerifyPlatformAuthResult(l.ctx, member.VerifyAuthResultRequest{
			Account: req.LoginID,
			Token:   req.Credentials.Password,
		})
		if err != nil {
			return nil, err
		}

		if !cr.Status {
			return nil, errs.AuthUnauthorizedError("failed to verify password")
		}
	case "platform":
		switch req.Platform.Provider {
		case memberD.Google.ToString():
			_, err := l.svcCtx.AccountUC.VerifyGoogleAuthResult(l.ctx, member.VerifyAuthResultRequest{
				Account: req.LoginID,
				Token:   req.Platform.Token,
			})
			if err != nil {
				return nil, err
			}
		case memberD.Line.ToString():
			// 原始平台驗證
			accessToken, err := l.svcCtx.AccountUC.LineCodeToAccessToken(l.ctx, req.LoginID)
			if err != nil {
				return nil, err
			}
			// 換資料
			userInfo, err := l.svcCtx.AccountUC.LineGetProfileByAccessToken(l.ctx, accessToken.AccessToken)
			if err != nil {
				return nil, err
			}
			req.LoginID = userInfo.UserID
		default:
			return nil, errs.InputInvalidFormatError("unsupported 3 party platform")
		}
	default:
		return nil, errs.InputInvalidFormatError("failed to get correct auth method")
	}

	account, err := l.svcCtx.AccountUC.GetUIDByAccount(l.ctx, member.GetUIDByAccountRequest{
		Account: req.LoginID,
	})
	if err != nil {
		return nil, err
	}

	userRole, err := l.svcCtx.UserRoleUC.Get(l.ctx, account.UID)
	if err != nil {
		return nil, err
	}

	tk, err := generateToken(l.svcCtx, l.ctx, req, account.UID, userRole.RoleUID)
	if err != nil {
		return nil, err
	}

	return &types.LoginResp{
		UID:          account.UID,
		AccessToken:  tk.AccessToken,
		RefreshToken: tk.RefreshToken,
		TokenType:    tk.TokenType,
	}, nil
}
