package auth

import (
	"context"
	"strings"

	"gateway/internal/svc"
	"gateway/internal/types"

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

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

func NewTokenExchangeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TokenExchangeLogic {
	return &TokenExchangeLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *TokenExchangeLogic) TokenExchange(req *types.TokenExchangeReq) (*types.AuthTokenData, error) {
	if err := requireLoginDeps(l.svcCtx); err != nil {
		return nil, err
	}

	tenant, err := resolveTenant(l.ctx, l.svcCtx, req.TenantSlug)
	if err != nil {
		return nil, err
	}

	claims, err := l.svcCtx.Zitadel.VerifyIDToken(l.ctx, strings.TrimSpace(req.IDToken))
	if err != nil {
		return nil, wrapZitadelErr(err)
	}

	member, err := memberForLogin(l.ctx, l.svcCtx, tenant.TenantID, claims.Sub)
	if err != nil {
		return nil, err
	}
	if claims.Email != "" && !strings.EqualFold(strings.TrimSpace(member.ZitadelEmail), claims.Email) {
		logx.WithContext(l.ctx).Infof("token exchange: zitadel email mismatch for uid=%s", member.UID)
	}

	return issueAuthToken(l.ctx, l.svcCtx, tenant.TenantID, member.UID)
}
