import { describe, expect, it } from 'vitest'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { axe } from 'vitest-axe'
import { ToastProvider, useToast } from './Toast'

function ToastProbe() {
  const { toast } = useToast()
  return (
    <button type="button" onClick={() => toast({ title: 'Saved', tone: 'success' })}>
      Show toast
    </button>
  )
}

function DangerToastProbe() {
  const { toast } = useToast()
  return (
    <button type="button" onClick={() => toast({ title: 'Failed', tone: 'danger' })}>
      Show danger
    </button>
  )
}

function DismissProbe() {
  const { toast, dismiss } = useToast()
  return (
    <>
      <button type="button" onClick={() => toast({ title: 'Saved', tone: 'success' })}>
        Show toast
      </button>
      <button type="button" onClick={() => dismiss()}>
        Dismiss all
      </button>
    </>
  )
}

describe('Toast', () => {
  it('shows polite status toast via useToast (edge: success tone tokens)', async () => {
    render(
      <ToastProvider>
        <ToastProbe />
      </ToastProvider>,
    )
    fireEvent.click(screen.getByRole('button', { name: 'Show toast' }))
    const status = await waitFor(() => screen.getByRole('status'))
    expect(status).toHaveAttribute('aria-live', 'polite')
    const toast = screen.getByText('Saved').closest('li')
    expect(toast).toBeTruthy()
    expect(toast?.className).toContain('bg-success')
  })

  it('uses an assertive live region for danger tone', async () => {
    render(
      <ToastProvider>
        <DangerToastProbe />
      </ToastProvider>,
    )
    fireEvent.click(screen.getByRole('button', { name: 'Show danger' }))
    const status = await waitFor(() => screen.getByRole('status'))
    expect(status).toHaveAttribute('aria-live', 'assertive')
    expect(screen.getByText('Failed').closest('li')).toBeTruthy()
  })

  it('removes the toast when dismiss() is called (contract: dismiss)', async () => {
    render(
      <ToastProvider>
        <DismissProbe />
      </ToastProvider>,
    )
    fireEvent.click(screen.getByRole('button', { name: 'Show toast' }))
    await waitFor(() => screen.getByRole('status'))
    fireEvent.click(screen.getByRole('button', { name: 'Dismiss all' }))
    await waitFor(() => expect(screen.queryByText('Saved')).toBeNull(), { timeout: 1500 })
  })

  it('migrates toast chrome to token-backed shadow/focus classes', async () => {
    const { container } = render(
      <ToastProvider>
        <ToastProbe />
      </ToastProvider>,
    )
    fireEvent.click(screen.getByRole('button', { name: 'Show toast' }))
    const status = await waitFor(() => screen.getByRole('status'))
    expect(status).toHaveAttribute('aria-live', 'polite')
    expect(screen.getByText('Saved').closest('li')?.className).toContain('shadow-[var(--mod-shadow-sm)]')
    expect(screen.getByRole('button', { name: 'Dismiss notification' }).className).toContain(
      'focus-visible:outline-[var(--mod-focus-ring-color)]',
    )
    await expect(axe(container)).resolves.toHaveNoViolations()
  })
})
