package infra

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"errors"
	"time"
)

// JWTGenerate codifica un JWT firmado con HMAC-SHA256 (alg: HS256).
// Si claims.IssuedAt viene en cero se setea a time.Now().Unix().
// Retorna el token en formato "header.payload.signature" con los tres segmentos
// codificados en base64url sin padding.
func JWTGenerate(claims JWTClaims, secret string) (string, error) {
	if secret == "" {
		return "", errors.New("jwt_generate: secret vacio")
	}
	if claims.IssuedAt == 0 {
		claims.IssuedAt = time.Now().Unix()
	}

	header := map[string]string{"alg": "HS256", "typ": "JWT"}
	headerJSON, err := json.Marshal(header)
	if err != nil {
		return "", err
	}
	payloadJSON, err := json.Marshal(claims)
	if err != nil {
		return "", err
	}

	enc := base64.RawURLEncoding
	headerPart := enc.EncodeToString(headerJSON)
	payloadPart := enc.EncodeToString(payloadJSON)
	signingInput := headerPart + "." + payloadPart

	mac := hmac.New(sha256.New, []byte(secret))
	mac.Write([]byte(signingInput))
	sigPart := enc.EncodeToString(mac.Sum(nil))

	return signingInput + "." + sigPart, nil
}
