package jwtauth

import (
	"context"
	"log/slog"
	"time"

	"commilitia.net/cdrop/internal/db"
)

// DeviceSweepInterval is how often the device sweeper wakes up.
const DeviceSweepInterval = 1 * time.Hour

// RunDeviceSweeper prunes the devices table on a timer so it stays aligned with
// the session list (AUTH.md §4): it drops (1) devices whose last_seen is older
// than ttl — registration must not outlive the longest valid refresh_token
// (brief §2: 196h sliding window) — and (2) browser devices whose web_session is
// gone (revoked or expired), which would otherwise linger until the stale cutoff
// now that users can no longer remove devices by hand. Native and shortcut
// devices keep no web_session and are pruned by the stale cutoff only. ttl ≤ 0
// disables the sweeper.
func RunDeviceSweeper(ctx context.Context, queries *db.Queries, ttl time.Duration) {
	if ttl <= 0 {
		slog.Info("device sweeper disabled (ttl <= 0)")
		return
	}
	slog.Info("device sweeper running", "ttl", ttl, "interval", DeviceSweepInterval)

	t := time.NewTicker(DeviceSweepInterval)
	defer t.Stop()
	for {
		select {
		case <-ctx.Done():
			return
		case <-t.C:
			now := time.Now()
			cutoff := now.Add(-ttl).Unix()
			if err := queries.DeleteStaleDevices(ctx, cutoff); err != nil {
				slog.Error("device sweeper failed", "err", err)
			}
			if _, err := queries.DeleteOrphanBrowserDevices(ctx, now.Unix()); err != nil {
				slog.Error("device sweeper: orphan browser cleanup failed", "err", err)
			}
		}
	}
}
