import { allSettled, fork } from 'effector'
import { describe, it, expect } from 'vitest'
import { $notifications, addNotification, dismissNotification, dismissAll } from '../notification'

describe('notification store', () => {
  it('starts empty', () => {
    const scope = fork()
    expect(scope.getState($notifications)).toEqual([])
  })

  it('adds a notification with generated id', async () => {
    const scope = fork()
    await allSettled(addNotification, {
      scope,
      params: { type: 'info', message: 'test' },
    })
    const list = scope.getState($notifications)
    expect(list).toHaveLength(1)
    expect(list[0].id).toEqual(expect.any(String))
    expect(list[0].message).toBe('test')
    expect(list[0].type).toBe('info')
  })

  it('caps at 3 visible notifications', async () => {
    const scope = fork()
    for (let i = 0; i < 5; i++) {
      await allSettled(addNotification, {
        scope,
        params: { type: 'info', message: `msg-${i}` },
      })
    }
    const list = scope.getState($notifications)
    expect(list).toHaveLength(3)
    expect(list[0].message).toBe('msg-2')
    expect(list[2].message).toBe('msg-4')
  })

  it('dismisses notification by id', async () => {
    const scope = fork()
    await allSettled(addNotification, {
      scope,
      params: { type: 'info', message: 'test' },
    })
    const [{ id }] = scope.getState($notifications)
    await allSettled(dismissNotification, {
      scope,
      params: id,
    })
    expect(scope.getState($notifications)).toEqual([])
  })

  it('clears all on dismissAll', async () => {
    const scope = fork()
    await allSettled(addNotification, {
      scope,
      params: { type: 'info', message: 'test' },
    })
    await allSettled(dismissAll, { scope })
    expect(scope.getState($notifications)).toEqual([])
  })

  it('defaults autoHideDuration to 4000 for info', async () => {
    const scope = fork()
    await allSettled(addNotification, {
      scope,
      params: { type: 'info', message: 'test' },
    })
    expect(scope.getState($notifications)[0].autoHideDuration).toBe(4000)
  })

  it('defaults autoHideDuration to 4000 for success', async () => {
    const scope = fork()
    await allSettled(addNotification, {
      scope,
      params: { type: 'success', message: 'test' },
    })
    expect(scope.getState($notifications)[0].autoHideDuration).toBe(4000)
  })

  it('defaults autoHideDuration to 4000 for warning', async () => {
    const scope = fork()
    await allSettled(addNotification, {
      scope,
      params: { type: 'warning', message: 'test' },
    })
    expect(scope.getState($notifications)[0].autoHideDuration).toBe(4000)
  })

  it('defaults autoHideDuration to 6000 for error', async () => {
    const scope = fork()
    await allSettled(addNotification, {
      scope,
      params: { type: 'error', message: 'test' },
    })
    expect(scope.getState($notifications)[0].autoHideDuration).toBe(6000)
  })
})
