package setup

import (
	"crypto/rand"
	"encoding/hex"
	"net/http"
)

const csrfCookieName = "felhom_csrf"
const csrfFormField = "_csrf"

// generateCSRFToken creates a random 32-byte hex token.
func generateCSRFToken() string {
	b := make([]byte, 32)
	if _, err := rand.Read(b); err != nil {
		panic("crypto/rand.Read failed: " + err.Error())
	}
	return hex.EncodeToString(b)
}

// setCSRFCookie sets the CSRF cookie on the response.
func setCSRFCookie(w http.ResponseWriter, token string) {
	http.SetCookie(w, &http.Cookie{
		Name:     csrfCookieName,
		Value:    token,
		Path:     "/",
		SameSite: http.SameSiteStrictMode,
		HttpOnly: false, // JavaScript needs to read it for AJAX if needed
	})
}

// validateCSRF checks that the form field matches the cookie.
func validateCSRF(r *http.Request) bool {
	cookie, err := r.Cookie(csrfCookieName)
	if err != nil || cookie.Value == "" {
		return false
	}
	formToken := r.FormValue(csrfFormField)
	if formToken == "" {
		return false
	}
	return cookie.Value == formToken
}

// ensureCSRFToken returns the existing CSRF token from the cookie, or generates a new one.
func ensureCSRFToken(w http.ResponseWriter, r *http.Request) string {
	if cookie, err := r.Cookie(csrfCookieName); err == nil && cookie.Value != "" {
		return cookie.Value
	}
	token := generateCSRFToken()
	setCSRFCookie(w, token)
	return token
}
