package auth

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"time"

	"gitea.local/admin/hspguard/internal/types"
	"gitea.local/admin/hspguard/internal/util"
	"gitea.local/admin/hspguard/internal/web"
	"github.com/google/uuid"
)

func (h *AuthHandler) refreshToken(w http.ResponseWriter, r *http.Request) {
	authHeader := r.Header.Get("Authorization")
	if authHeader == "" {
		web.Error(w, "unauthorized", http.StatusUnauthorized)
		return
	}

	parts := strings.Split(authHeader, "Bearer ")
	if len(parts) != 2 {
		web.Error(w, "invalid auth header format", http.StatusUnauthorized)
		return
	}

	tokenStr := parts[1]
	var userClaims types.UserClaims

	token, err := util.VerifyToken(tokenStr, h.cfg.Jwt.PublicKey, &userClaims)
	if err != nil || !token.Valid {
		http.Error(w, fmt.Sprintf("invalid token: %v", err), http.StatusUnauthorized)
		return
	}

	expire, err := userClaims.GetExpirationTime()
	if err != nil {
		web.Error(w, "failed to retrieve enough info from the token", http.StatusInternalServerError)
		return
	}

	if time.Now().After(expire.Time) {
		web.Error(w, "token is expired", http.StatusUnauthorized)
		return
	}

	userId, err := uuid.Parse(userClaims.Subject)
	if err != nil {
		web.Error(w, "failed to parsej user id from token", http.StatusInternalServerError)
		return
	}

	user, err := h.repo.FindUserId(r.Context(), userId)
	if err != nil {
		web.Error(w, "user with provided email does not exists", http.StatusBadRequest)
		return
	}

	access, refresh, err := h.signTokens(&user)
	if err != nil {
		web.Error(w, "failed to generate tokens", http.StatusInternalServerError)
		return
	}

	type Response struct {
		AccessToken  string `json:"access"`
		RefreshToken string `json:"refresh"`
	}

	encoder := json.NewEncoder(w)

	w.Header().Set("Content-Type", "application/json")

	if err := encoder.Encode(Response{
		AccessToken:  access,
		RefreshToken: refresh,
	}); err != nil {
		web.Error(w, "failed to encode response", http.StatusInternalServerError)
	}
}
