package keycloak

import (
	"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/auth"
	"github.com/golang-jwt/jwt/v5"
	"time"
)

type TokenManager interface {
	GetUserInfoFromToken(token string) (*auth.UserInfoFromToken, error)
	VerifyEmailToken(token string, expectedUserID string) error
}

type tokenManager struct {
	parser *jwt.Parser
}

func NewJWTManager() TokenManager {
	return &tokenManager{
		parser: jwt.NewParser(),
	}
}

func (t *tokenManager) GetUserInfoFromToken(token string) (*auth.UserInfoFromToken, error) {
	userToken, _, err := t.parser.ParseUnverified(token, jwt.MapClaims{})
	if err != nil {
		return nil, ErrInvalidToken
	}

	if claims, ok := userToken.Claims.(jwt.MapClaims); ok {
		resp := auth.UserInfoFromToken{}

		resp.UserId, ok = claims["sub"].(string)
		if !ok {
			return nil, ErrInvalidToken
		}

		return &resp, nil
	}

	return nil, ErrInvalidToken
}

func (t *tokenManager) VerifyEmailToken(token string, expectedUserID string) error {
	// Parse token without verification (we'll verify signature manually)
	parsedToken, _, err := t.parser.ParseUnverified(token, jwt.MapClaims{})
	if err != nil {
		return ErrInvalidToken
	}

	// Extract claims
	claims, ok := parsedToken.Claims.(jwt.MapClaims)
	if !ok {
		return ErrInvalidToken
	}

	// Check if token is for email verification
	purpose, ok := claims["purpose"].(string)
	if !ok || purpose != "email_verification" {
		return ErrInvalidToken
	}

	// Check if subject matches expected user ID
	sub, ok := claims["sub"].(string)
	if !ok || sub != expectedUserID {
		return ErrInvalidToken
	}

	// Check expiration
	exp, ok := claims["exp"].(float64)
	if !ok || float64(time.Now().Unix()) > exp {
		return ErrInvalidToken
	}

	return nil
}
