package httpapi

import (
	"context"
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"strings"
	"unicode"

	"github.com/google/uuid"
)

// slugify follows the spirit of backend/src/lib/slugify.ts: lowercase,
// ASCII-fold common Spanish characters, dashes for everything else.
func slugify(s string) string {
	replacer := strings.NewReplacer(
		"á", "a", "é", "e", "í", "i", "ó", "o", "ú", "u", "ü", "u", "ñ", "n",
		"Á", "a", "É", "e", "Í", "i", "Ó", "o", "Ú", "u", "Ü", "u", "Ñ", "n")
	s = replacer.Replace(strings.ToLower(strings.TrimSpace(s)))
	var b strings.Builder
	prevDash := true // avoids a leading dash
	for _, r := range s {
		switch {
		case unicode.IsLetter(r) && r < 128, unicode.IsDigit(r):
			b.WriteRune(r)
			prevDash = false
		default:
			if !prevDash {
				b.WriteByte('-')
				prevDash = true
			}
		}
	}
	out := strings.Trim(b.String(), "-")
	if len(out) > 140 {
		out = strings.Trim(out[:140], "-")
	}
	if out == "" {
		out = "gallery"
	}
	return out
}

// uniqueSlug appends -2, -3, ... until the slug is free.
func (s *Server) uniqueSlug(ctx context.Context, title string) (string, error) {
	base := slugify(title)
	slug := base
	for i := 2; ; i++ {
		exists, err := s.db.SlugExists(ctx, slug)
		if err != nil {
			return "", err
		}
		if !exists {
			return slug, nil
		}
		slug = fmt.Sprintf("%s-%d", base, i)
	}
}

func newID() string {
	return uuid.NewString()
}

// newShareToken returns 32 random bytes, base64url (43 chars, no padding).
func newShareToken() string {
	buf := make([]byte, 32)
	if _, err := rand.Read(buf); err != nil {
		panic(err) // crypto/rand failure is unrecoverable
	}
	return base64.RawURLEncoding.EncodeToString(buf)
}
