package handlers

import (
	"crypto/rand"
	"crypto/sha256"
	"crypto/subtle"
	"encoding/hex"
	"fmt"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"

	"sproutgate-backend/internal/models"
)

func bearerToken(header string) string {
	if header == "" {
		return ""
	}
	if strings.HasPrefix(strings.ToLower(header), "bearer ") {
		return strings.TrimSpace(header[7:])
	}
	return ""
}

func adminTokenFromRequest(c *gin.Context) string {
	if token := strings.TrimSpace(c.Query("token")); token != "" {
		return token
	}
	if token := strings.TrimSpace(c.GetHeader("X-Admin-Token")); token != "" {
		return token
	}
	authHeader := strings.TrimSpace(c.GetHeader("Authorization"))
	return bearerToken(authHeader)
}

func generateVerificationCode() (string, error) {
	randomBytes := make([]byte, 3)
	if _, err := rand.Read(randomBytes); err != nil {
		return "", err
	}
	number := int(randomBytes[0])<<16 | int(randomBytes[1])<<8 | int(randomBytes[2])
	return fmt.Sprintf("%06d", number%1000000), nil
}

func hashCode(code string) string {
	sum := sha256.Sum256([]byte(code))
	return hex.EncodeToString(sum[:])
}

func verifyCode(code string, hash string) bool {
	return subtle.ConstantTimeCompare([]byte(hashCode(code)), []byte(hash)) == 1
}

func writeBanJSON(c *gin.Context, reason string) {
	h := gin.H{"error": "account is banned"}
	if r := strings.TrimSpace(reason); r != "" {
		h["banReason"] = r
	}
	c.JSON(http.StatusForbidden, h)
}

func abortIfUserBanned(c *gin.Context, u models.UserRecord) bool {
	if !u.Banned {
		return false
	}
	writeBanJSON(c, u.BanReason)
	return true
}
