package store

import (
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"sync"
	"time"
)

// RedirectTrack represents a single redirect attempt tracking entry
type RedirectTrack struct {
	IP        string    // Client IP (X-Forwarded-For aware)
	UserAgent string    // Full User-Agent string for debugging
	Path      string    // Request path (without query params)
	Attempts  int       // Number of redirect attempts
	FirstSeen time.Time // When first redirect was tracked
	ExpiresAt time.Time // When to clean up this entry
}

type Store struct {
	sessions       sync.Map // key: string, value: *RegistrationSession
	redirectTracks sync.Map // key: string, value: *RedirectTrack
	cleanup        *time.Ticker
}

func NewStore() *Store {
	s := &Store{
		cleanup: time.NewTicker(1 * time.Minute),
	}

	// Background cleanup of expired sessions
	go func() {
		for range s.cleanup.C {
			s.cleanupExpired()
		}
	}()

	return s
}

func (s *Store) Delete(id string) {
	s.sessions.Delete(id)
}
func (s *Store) cleanupExpired() {
	now := time.Now()

	// Clean up expired registration sessions
	s.sessions.Range(func(key, value any) bool {
		session := value.(*RegistrationSession)
		if now.After(session.ExpiresAt) {
			s.sessions.Delete(key)
		}
		return true
	})

	// Clean up expired redirect tracks
	s.redirectTracks.Range(func(key, value any) bool {
		track := value.(*RedirectTrack)
		if now.After(track.ExpiresAt) {
			s.redirectTracks.Delete(key)
		}
		return true
	})
}
func generateID() string {
	b := make([]byte, 32)
	rand.Read(b)
	return base64.RawURLEncoding.EncodeToString(b)
}

// redirectKey generates a unique key for tracking redirects
// Uses IP + first 100 chars of UA + path as key (not hashed for debugging)
func redirectKey(ip, userAgent, path string) string {
	ua := userAgent
	if len(ua) > 100 {
		ua = ua[:100]
	}
	return fmt.Sprintf("%s:%s:%s", ip, ua, path)
}
