import { describe, it, expect, beforeEach } from 'vitest'
import { checkRateLimit, enforceUserRateLimit, _resetRateLimit } from '@/lib/rate-limit'

beforeEach(() => {
  _resetRateLimit()
})

describe('checkRateLimit (legacy auth-keys)', () => {
  it('staat de eerste request toe', () => {
    expect(checkRateLimit('login:1.2.3.4')).toBe(true)
  })

  it('blokkeert na exceeding max (login: 10/min)', () => {
    for (let i = 0; i < 10; i++) checkRateLimit('login:1.2.3.4')
    expect(checkRateLimit('login:1.2.3.4')).toBe(false)
  })

  it('register heeft eigen lagere limiet (5/uur)', () => {
    for (let i = 0; i < 5; i++) checkRateLimit('register:9.9.9.9')
    expect(checkRateLimit('register:9.9.9.9')).toBe(false)
  })

  it('verschillende keys hebben hun eigen counter', () => {
    for (let i = 0; i < 10; i++) checkRateLimit('login:1.1.1.1')
    expect(checkRateLimit('login:1.1.1.1')).toBe(false)
    expect(checkRateLimit('login:2.2.2.2')).toBe(true)
  })
})

describe('enforceUserRateLimit (v1-readiness #3 mutation-scopes)', () => {
  it('returnt null bij eerste call', () => {
    expect(enforceUserRateLimit('create-pbi', 'user-1')).toBeNull()
  })

  it('returnt 429-shape na exceeding limiet', () => {
    // create-product limiet = 5/min
    for (let i = 0; i < 5; i++) enforceUserRateLimit('create-product', 'user-1')
    const result = enforceUserRateLimit('create-product', 'user-1')
    expect(result).not.toBeNull()
    expect(result?.code).toBe(429)
    expect(result?.error).toContain('Te veel acties')
  })

  it('scope is per (action, user) — andere user heeft eigen quota', () => {
    for (let i = 0; i < 5; i++) enforceUserRateLimit('create-product', 'user-A')
    expect(enforceUserRateLimit('create-product', 'user-A')).not.toBeNull()
    expect(enforceUserRateLimit('create-product', 'user-B')).toBeNull()
  })

  it('verschillende scopes voor dezelfde user vullen apart', () => {
    for (let i = 0; i < 5; i++) enforceUserRateLimit('create-product', 'user-1')
    expect(enforceUserRateLimit('create-product', 'user-1')).not.toBeNull()
    // create-task heeft eigen counter
    expect(enforceUserRateLimit('create-task', 'user-1')).toBeNull()
  })

  it('create-task limiet (100) is hoger dan create-pbi (30)', () => {
    for (let i = 0; i < 30; i++) enforceUserRateLimit('create-pbi', 'u')
    expect(enforceUserRateLimit('create-pbi', 'u')).not.toBeNull()
    // create-task is nog niet hit
    for (let i = 0; i < 30; i++) enforceUserRateLimit('create-task', 'u')
    expect(enforceUserRateLimit('create-task', 'u')).toBeNull()
  })
})
