import { describe, expect, it, vi } from 'vitest'
import { render, screen, fireEvent } from '@testing-library/react'
import { axe } from 'vitest-axe'
import { Button } from './Button'

describe('Button', () => {
  it('renders its children as a button', () => {
    render(<Button>Click</Button>)
    expect(screen.getByRole('button', { name: 'Click' })).toBeDefined()
  })
  it('applies token classes from props (no raw values)', () => {
    render(<Button tone="accent" radius="lg">Go</Button>)
    const btn = screen.getByRole('button', { name: 'Go' })
    expect(btn.className).toContain('bg-[var(--mod-color-accent-9)]')
    expect(btn.className).toContain('hover:bg-[var(--mod-color-accent-10)]')
    expect(btn.className).toContain('focus-visible:outline-[var(--mod-focus-ring-color)]')
    expect(btn.className).toContain('rounded-lg')
    // no inline style escape hatch
    expect(btn.getAttribute('style')).toBeNull()
  })
  it('forwards click + native button attrs', () => {
    const onClick = vi.fn()
    render(<Button onClick={onClick} disabled>X</Button>)
    const btn = screen.getByRole('button', { name: 'X' }) as HTMLButtonElement
    expect(btn.disabled).toBe(true)
    fireEvent.click(btn)
    // disabled buttons don't fire click
    expect(onClick).not.toHaveBeenCalled()
  })
  it('defaults to type="button" so it cannot submit a form implicitly', () => {
    render(<Button>Safe</Button>)
    const btn = screen.getByRole('button', { name: 'Safe' }) as HTMLButtonElement
    expect(btn.type).toBe('button')
  })
  it('respects an explicit type="submit"', () => {
    render(<Button type="submit">Send</Button>)
    const btn = screen.getByRole('button', { name: 'Send' }) as HTMLButtonElement
    expect(btn.type).toBe('submit')
  })
  it('does not force a type attribute onto asChild elements', () => {
    render(<Button asChild><a href="/x">Nav</a></Button>)
    expect(screen.getByRole('link', { name: 'Nav' }).getAttribute('type')).toBeNull()
  })
  it('renders asChild via Slot', () => {
    render(<Button asChild><a href="/x">Link</a></Button>)
    const link = screen.getByRole('link', { name: 'Link' })
    expect(link.className).toContain('rounded')
  })

  it('stays axe-clean for button markup', async () => {
    const { container } = render(<Button>Ship</Button>)
    await expect(axe(container)).resolves.toHaveNoViolations()
  })
})
