import { describe, it, expect, beforeEach, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { setActivePinia, createPinia } from 'pinia'

import { useUiStore } from '@/stores/ui'
import ToastContainer from './ToastContainer.vue'

describe('ToastContainer', () => {
  beforeEach(() => {
    setActivePinia(createPinia())
    // Clear any teleported content from previous tests
    document.body.innerHTML = ''
    vi.useFakeTimers()
  })

  describe('toast display', () => {
    it('is empty when no toasts', () => {
      /**
       * Test that container has no toasts by default.
       *
       * The container should be present but empty when
       * no notifications have been triggered.
       */
      mount(ToastContainer)
      const ui = useUiStore()

      expect(ui.toasts).toHaveLength(0)
    })

    it('shows toast when added', async () => {
      /**
       * Test that toasts appear when triggered.
       *
       * The toast should be visible with its message and
       * appropriate styling for the toast type.
       */
      mount(ToastContainer)
      const ui = useUiStore()

      ui.showSuccess('Operation completed!')

      // Wait for render
      await vi.advanceTimersByTimeAsync(50)

      expect(ui.toasts).toHaveLength(1)
      expect(document.body.textContent).toContain('Operation completed!')
    })

    it('shows multiple toasts', async () => {
      /**
       * Test that multiple toasts can be displayed.
       *
       * Users may trigger several notifications in quick succession,
       * all should be visible simultaneously.
       */
      mount(ToastContainer)
      const ui = useUiStore()

      ui.showSuccess('First message')
      ui.showError('Second message')
      ui.showWarning('Third message')

      await vi.advanceTimersByTimeAsync(50)

      expect(ui.toasts).toHaveLength(3)
      expect(document.body.textContent).toContain('First message')
      expect(document.body.textContent).toContain('Second message')
      expect(document.body.textContent).toContain('Third message')
    })
  })

  describe('auto-dismiss', () => {
    it('auto-dismisses after duration', async () => {
      /**
       * Test that toasts auto-dismiss after their duration.
       *
       * Toasts should disappear automatically so users don't
       * need to manually close them.
       */
      mount(ToastContainer)
      const ui = useUiStore()

      ui.showSuccess('Auto dismiss me', 1000) // 1 second duration

      expect(ui.toasts).toHaveLength(1)

      await vi.advanceTimersByTimeAsync(1100) // Past the duration

      expect(ui.toasts).toHaveLength(0)
    })

    it('does not auto-dismiss with zero duration', async () => {
      /**
       * Test that persistent toasts remain visible.
       *
       * Some notifications may be important enough to require
       * manual dismissal by the user.
       */
      mount(ToastContainer)
      const ui = useUiStore()

      ui.showError('Persistent error', 0) // No auto-dismiss

      await vi.advanceTimersByTimeAsync(10000) // Long time passes

      expect(ui.toasts).toHaveLength(1)
    })
  })

  describe('manual dismiss', () => {
    it('dismisses toast by id', async () => {
      /**
       * Test that individual toasts can be dismissed.
       *
       * Users should be able to close toasts they've read
       * without waiting for the timeout.
       */
      mount(ToastContainer)
      const ui = useUiStore()

      const id = ui.showSuccess('Dismiss me', 0)

      expect(ui.toasts).toHaveLength(1)

      ui.dismissToast(id)

      expect(ui.toasts).toHaveLength(0)
    })

    it('dismisses all toasts', async () => {
      /**
       * Test that all toasts can be cleared at once.
       *
       * Useful for cleaning up notifications when navigating
       * away or when user wants to clear all messages.
       */
      mount(ToastContainer)
      const ui = useUiStore()

      ui.showSuccess('One', 0)
      ui.showError('Two', 0)
      ui.showInfo('Three', 0)

      expect(ui.toasts).toHaveLength(3)

      ui.dismissAllToasts()

      expect(ui.toasts).toHaveLength(0)
    })
  })

  describe('toast types', () => {
    it('has convenience methods for all types', () => {
      /**
       * Test that all toast type helpers exist.
       *
       * The store should provide typed methods for common
       * notification types.
       */
      const ui = useUiStore()

      expect(typeof ui.showSuccess).toBe('function')
      expect(typeof ui.showError).toBe('function')
      expect(typeof ui.showWarning).toBe('function')
      expect(typeof ui.showInfo).toBe('function')
    })
  })
})
