/**
 * Tests for the Alert variant migration helper.
 *
 * The Alert primitive's variant set switched from
 *   v0.2.0  →  'default' | 'destructive'
 *   v0.3.0+ →  'info' | 'success' | 'warning' | 'error'
 *
 * To keep older call-sites working while consumers migrate, the v0.4.0
 * Alert auto-maps the legacy values and emits a one-time dev-mode
 * console.warn so the migration is discoverable via the codemod hint
 * embedded in the message.
 */

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render } from '@testing-library/react'

import { Alert, _resetAlertLegacyWarnings } from '../alert'

describe('Alert legacy variant migration', () => {
  beforeEach(() => {
    _resetAlertLegacyWarnings()
  })

  it('renders variant="destructive" with the same classes as variant="error"', () => {
    const { container: aContainer } = render(<Alert variant="destructive">Boom</Alert>)
    const { container: bContainer } = render(<Alert variant="error">Boom</Alert>)

    const a = aContainer.querySelector('[data-slot="alert"]')
    const b = bContainer.querySelector('[data-slot="alert"]')
    expect(a).toBeTruthy()
    expect(b).toBeTruthy()

    // The rendered class list should be identical post-resolution.
    expect(a?.className).toBe(b?.className)
    // Resolved variant is exposed as a data attribute for ergonomic testing.
    expect(a?.getAttribute('data-variant')).toBe('error')
    expect(b?.getAttribute('data-variant')).toBe('error')
  })

  it('renders variant="default" with the same classes as variant="info"', () => {
    const { container: aContainer } = render(<Alert variant="default">Hi</Alert>)
    const { container: bContainer } = render(<Alert variant="info">Hi</Alert>)

    const a = aContainer.querySelector('[data-slot="alert"]')
    const b = bContainer.querySelector('[data-slot="alert"]')
    expect(a?.className).toBe(b?.className)
    expect(a?.getAttribute('data-variant')).toBe('info')
  })

  it('emits a dev-mode console.warn the first time variant="destructive" is rendered', () => {
    const spy = vi.spyOn(console, 'warn').mockImplementation(() => {})
    try {
      render(<Alert variant="destructive">First</Alert>)
      expect(spy).toHaveBeenCalledTimes(1)
      const msg = String(spy.mock.calls[0]?.[0] ?? '')
      expect(msg).toContain('deprecated')
      expect(msg).toContain('variant="error"')

      // Repeat renders of the same legacy variant don't re-warn — the
      // helper de-dupes per legacy value.
      render(<Alert variant="destructive">Second</Alert>)
      expect(spy).toHaveBeenCalledTimes(1)

      // A different legacy variant warns on its own.
      render(<Alert variant="default">Third</Alert>)
      expect(spy).toHaveBeenCalledTimes(2)
    } finally {
      spy.mockRestore()
    }
  })

  it('does not warn for current variants', () => {
    const spy = vi.spyOn(console, 'warn').mockImplementation(() => {})
    try {
      render(<Alert variant="error">x</Alert>)
      render(<Alert variant="success">x</Alert>)
      render(<Alert variant="warning">x</Alert>)
      render(<Alert variant="info">x</Alert>)
      render(<Alert>x</Alert>)
      expect(spy).not.toHaveBeenCalled()
    } finally {
      spy.mockRestore()
    }
  })

  it('does not warn in production (NODE_ENV=production)', () => {
    const original = process.env.NODE_ENV
    process.env.NODE_ENV = 'production'
    const spy = vi.spyOn(console, 'warn').mockImplementation(() => {})
    try {
      render(<Alert variant="destructive">Boom</Alert>)
      expect(spy).not.toHaveBeenCalled()
    } finally {
      spy.mockRestore()
      process.env.NODE_ENV = original
    }
  })
})
