package middleware

import (
	"errors"
	"fmt"
	"net/http"
	"strings"

	config "learnsteam/learsteam-quiz-api/configs"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
)

func Auth() gin.HandlerFunc {
	return func(c *gin.Context) {
		sub, err := UserID(c.Request)
		if err != nil {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
			c.Abort()
			return
		}

		fmt.Println("token", extract(c.Request))
		fmt.Println("sub", *sub)

		c.Set("token", extract(c.Request))
		c.Set("sub", *sub)
		c.Next()
	}
}

func extract(r *http.Request) string {
	authorization := r.Header.Get("Authorization")
	strArr := strings.Split(authorization, " ")
	if len(strArr) == 2 {
		return strArr[1]
	}
	return ""
}

func verify(r *http.Request) (*jwt.Token, error) {
	tokenString := extract(r)
	jwtToken, err := jwt.Parse(tokenString, func(jwtToken *jwt.Token) (interface{}, error) {
		if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
		}
		return []byte(config.SECRET_KEY), nil
	})

	return jwtToken, err
}

func UserID(r *http.Request) (*string, error) {
	jwtToken, err := verify(r)
	if err != nil {
		return nil, err
	}

	claims, ok := jwtToken.Claims.(jwt.MapClaims)
	if !ok || !jwtToken.Valid {
		return nil, errors.New("refresh token is invalid")
	}

	sub := claims["sub"].(string)

	return &sub, nil
}
