package auth

import (
	"sort"
	"sync"
	"time"
)

type AccessSnapshot struct {
	KeyID          string    `json:"key_id"`
	LastPath       string    `json:"last_path"`
	RemoteAddr     string    `json:"remote_addr"`
	UserAgent      string    `json:"user_agent"`
	RequestCount   int       `json:"request_count"`
	LastAccessedAt time.Time `json:"last_accessed_at"`
}

type AccessTracker struct {
	mu      sync.RWMutex
	entries map[string]AccessSnapshot
}

func NewAccessTracker() *AccessTracker {
	return &AccessTracker{entries: make(map[string]AccessSnapshot)}
}

func (t *AccessTracker) Record(keyID, path, remoteAddr, userAgent string, now time.Time) {
	if t == nil || keyID == "" {
		return
	}

	t.mu.Lock()
	defer t.mu.Unlock()

	entry := t.entries[keyID]
	entry.KeyID = keyID
	entry.LastPath = path
	entry.RemoteAddr = remoteAddr
	entry.UserAgent = userAgent
	entry.LastAccessedAt = now.UTC()
	entry.RequestCount++
	t.entries[keyID] = entry
}

func (t *AccessTracker) Snapshot() []AccessSnapshot {
	if t == nil {
		return nil
	}

	t.mu.RLock()
	defer t.mu.RUnlock()

	items := make([]AccessSnapshot, 0, len(t.entries))
	for _, entry := range t.entries {
		items = append(items, entry)
	}

	sort.Slice(items, func(i, j int) bool {
		return items[i].LastAccessedAt.After(items[j].LastAccessedAt)
	})

	return items
}

func (t *AccessTracker) ConnectedCount(now time.Time, window time.Duration) int {
	if t == nil {
		return 0
	}

	cutoff := now.UTC().Add(-window)
	t.mu.RLock()
	defer t.mu.RUnlock()

	count := 0
	for _, entry := range t.entries {
		if !entry.LastAccessedAt.Before(cutoff) {
			count++
		}
	}
	return count
}
