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

test.group('SearchAction', () => {
  test('initializes with default values', ({ assert }) => {
    const action = new SearchAction()
    assert.equal(action.kind, 'search')
    assert.deepEqual(action.fields, [])
    assert.isEmpty(action.accessRule)
  }).tags(['@modeling', '@action', '@search-action'])

  test('initializes with provided values', ({ assert }) => {
    const fields = ['name', 'description']
    const action = new SearchAction({
      fields,
    })

    assert.equal(action.kind, 'search')
    assert.deepEqual(action.fields, fields)
  }).tags(['@modeling', '@action', '@search-action'])

  test('constructor copies arrays (immutability)', ({ assert }) => {
    const fields = ['name']

    const action = new SearchAction({
      fields,
    })

    // Modify original source
    fields.push('age')

    assert.deepEqual(action.fields, ['name'])
  }).tags(['@modeling', '@action', '@search-action', '@immutability'])

  test('toJSON returns valid schema', ({ assert }) => {
    const action = new SearchAction({
      fields: ['name'],
    })

    const json = action.toJSON()

    // Modify JSON
    json.fields.push('new')

    assert.equal(json.kind, 'search')
    assert.lengthOf(action.fields, 1) // Ensure immutability
    assert.equal(action.fields[0], 'name')
  }).tags(['@modeling', '@action', '@search-action', '@serialization', '@immutability'])

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

    action.fields = ['name']
    await Promise.resolve()
    assert.isTrue(notified)
  }).tags(['@modeling', '@action', '@search-action', '@observed'])

  test('notifies change when fields value change', async ({ assert }) => {
    const action = new SearchAction()
    let notified = false
    action.addEventListener('change', () => {
      notified = true
    })

    action.fields.push('name')
    await Promise.resolve()
    assert.isTrue(notified)
  }).tags(['@modeling', '@action', '@search-action', '@observed'])
})
