package webhook

import (
	"sync"
	"time"
)

const defaultDedupeTTL = 10 * time.Minute

type dedupeEntry struct {
	expiresAt time.Time
}

// Dedupe suppresses duplicate webhook processing for the same repo and commit within a TTL window.
type Dedupe struct {
	ttl time.Duration
	mu  sync.Mutex
	entries map[string]dedupeEntry
}

// NewDedupe creates a dedupe cache with the given TTL.
func NewDedupe(ttl time.Duration) *Dedupe {
	if ttl <= 0 {
		ttl = defaultDedupeTTL
	}
	return &Dedupe{
		ttl:     ttl,
		entries: make(map[string]dedupeEntry),
	}
}

// TryRecord returns false if the key was seen recently and is still within TTL.
func (d *Dedupe) TryRecord(repoID, commitSHA string) bool {
	key := repoID + ":" + commitSHA
	now := time.Now()

	d.mu.Lock()
	defer d.mu.Unlock()

	d.purgeExpired(now)

	if entry, ok := d.entries[key]; ok && now.Before(entry.expiresAt) {
		return false
	}

	d.entries[key] = dedupeEntry{expiresAt: now.Add(d.ttl)}
	return true
}

func (d *Dedupe) purgeExpired(now time.Time) {
	for key, entry := range d.entries {
		if !now.Before(entry.expiresAt) {
			delete(d.entries, key)
		}
	}
}
