import { test } from '@japa/runner'
import { DeleteAction } from '../../../../src/modeling/actions/DeleteAction.js'

test.group('DeleteAction', () => {
  test('initializes with default values', ({ assert }) => {
    const action = new DeleteAction()
    assert.equal(action.kind, 'delete')
    assert.equal(action.strategy, 'soft')
    assert.equal(action.retentionPeriod, 30)
    assert.isEmpty(action.accessRule) // Inherited from Action
  }).tags(['@modeling', '@action', '@delete-action'])

  test('initializes with provided values', ({ assert }) => {
    const action = new DeleteAction({
      strategy: 'hard',
      retentionPeriod: 0,
      accessRule: [{ type: 'allowPublic' }],
    })

    assert.equal(action.kind, 'delete')
    assert.equal(action.strategy, 'hard')
    assert.equal(action.retentionPeriod, 0)
    assert.lengthOf(action.accessRule, 1)
    assert.equal(action.accessRule[0].type, 'allowPublic')
  }).tags(['@modeling', '@action', '@delete-action'])

  test('constructor copies arrays (immutability)', ({ assert }) => {
    const rules = [{ type: 'allowPublic' }]

    const action = new DeleteAction({
      accessRule: rules,
    })

    // Modify original source
    rules.push({ type: 'other' })
    rules[0].type = 'changed'

    assert.lengthOf(action.accessRule, 1)
    assert.equal(action.accessRule[0].type, 'allowPublic')
  }).tags(['@modeling', '@action', '@delete-action', '@immutability'])

  test('toJSON returns valid schema', ({ assert }) => {
    const action = new DeleteAction({
      strategy: 'hard',
      retentionPeriod: 0,
    })

    const json = action.toJSON()

    assert.equal(json.kind, 'delete')
    assert.equal(json.strategy, 'hard')
    assert.equal(json.retentionPeriod, 0)
  }).tags(['@modeling', '@action', '@delete-action', '@serialization'])

  test('notifies change when strategy changes', async ({ assert }) => {
    const action = new DeleteAction()
    let notified = false
    action.addEventListener('change', () => {
      notified = true
    })

    action.strategy = 'hard'
    await Promise.resolve()
    assert.isTrue(notified)
  }).tags(['@modeling', '@action', '@delete-action', '@observed'])

  test('notifies change when retentionPeriod changes', async ({ assert }) => {
    const action = new DeleteAction()
    let notified = false
    action.addEventListener('change', () => {
      notified = true
    })

    action.retentionPeriod = 60
    await Promise.resolve()
    assert.isTrue(notified)
  }).tags(['@modeling', '@action', '@delete-action', '@observed'])
})
