import { test } from '@japa/runner'
import { RateLimitingConfiguration } from '../../../../src/modeling/rules/RateLimitingConfiguration.js'
import { RateLimitRule } from '../../../../src/modeling/rules/RateLimitRule.js'

test.group('RateLimitingConfiguration', () => {
  test('initializes with default values', ({ assert }) => {
    const config = new RateLimitingConfiguration()
    assert.deepEqual(config.rules, [])
  }).tags(['@modeling', '@rule', '@rate-limiting-config'])

  test('initializes with provided rules', ({ assert }) => {
    const rule = { rate: 100, interval: 'minute' } as const
    const config = new RateLimitingConfiguration({
      rules: [rule],
    })

    assert.lengthOf(config.rules, 1)
    assert.instanceOf(config.rules[0], RateLimitRule)
    assert.equal(config.rules[0].rate, 100)
  }).tags(['@modeling', '@rule', '@rate-limiting-config'])

  test('toJSON returns valid schema', ({ assert }) => {
    const config = new RateLimitingConfiguration({
      rules: [{ rate: 100, interval: 'minute' }],
    })

    const json = config.toJSON()

    assert.lengthOf(json.rules, 1)
    assert.equal(json.rules[0].rate, 100)
    assert.equal(json.rules[0].interval, 'minute')
  }).tags(['@modeling', '@rule', '@rate-limiting-config', '@serialization'])

  test('notifies change when rules are added', async ({ assert }) => {
    const config = new RateLimitingConfiguration()
    let notified = false
    config.addEventListener('change', () => {
      notified = true
    })

    config.rules.push(new RateLimitRule({ rate: 10 }))
    await Promise.resolve()
    assert.isTrue(notified)
  }).tags(['@modeling', '@rule', '@rate-limiting-config', '@observed'])

  test('notifies change when nested rule changes', async ({ assert }) => {
    const rule = new RateLimitRule({ rate: 10 })
    const config = new RateLimitingConfiguration()
    config.rules.push(rule)
    await Promise.resolve() // Wait for push notification to settle

    let notified = false
    config.addEventListener('change', () => {
      notified = true
    })

    config.rules[0].rate = 20
    await Promise.resolve()
    assert.isTrue(notified)
  }).tags(['@modeling', '@rule', '@rate-limiting-config', '@observed'])
})
