import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Switch } from './switch'

describe('Switch', () => {
  const mockOnChange = vi.fn()

  beforeEach(() => {
    vi.clearAllMocks()
  })

  it('should render unchecked by default', () => {
    render(
      <Switch
        checked={false}
        onCheckedChange={mockOnChange}
      />
    )

    const switchButton = screen.getByRole('switch')
    expect(switchButton).toHaveAttribute('aria-checked', 'false')
  })

  it('should render checked when checked prop is true', () => {
    render(
      <Switch
        checked={true}
        onCheckedChange={mockOnChange}
      />
    )

    const switchButton = screen.getByRole('switch')
    expect(switchButton).toHaveAttribute('aria-checked', 'true')
  })

  it('should toggle on click', async () => {
    const user = userEvent.setup()
    
    render(
      <Switch
        checked={false}
        onCheckedChange={mockOnChange}
      />
    )

    const switchButton = screen.getByRole('switch')
    await user.click(switchButton)

    expect(mockOnChange).toHaveBeenCalledWith(true)
  })

  it('should toggle off when clicked while checked', async () => {
    const user = userEvent.setup()
    
    render(
      <Switch
        checked={true}
        onCheckedChange={mockOnChange}
      />
    )

    const switchButton = screen.getByRole('switch')
    await user.click(switchButton)

    expect(mockOnChange).toHaveBeenCalledWith(false)
  })

  it('should be disabled when disabled prop is true', () => {
    render(
      <Switch
        checked={false}
        onCheckedChange={mockOnChange}
        disabled
      />
    )

    expect(screen.getByRole('switch')).toBeDisabled()
  })

  it('should not call onChange when disabled', async () => {
    const user = userEvent.setup()
    
    render(
      <Switch
        checked={false}
        onCheckedChange={mockOnChange}
        disabled
      />
    )

    const switchButton = screen.getByRole('switch')
    await user.click(switchButton)

    expect(mockOnChange).not.toHaveBeenCalled()
  })

  it('should have correct id attribute', () => {
    render(
      <Switch
        id="test-switch"
        checked={false}
        onCheckedChange={mockOnChange}
      />
    )

    expect(screen.getByRole('switch')).toHaveAttribute('id', 'test-switch')
  })

  it('should apply custom className', () => {
    render(
      <Switch
        checked={false}
        onCheckedChange={mockOnChange}
        className="custom-class"
      />
    )

    expect(screen.getByRole('switch')).toHaveClass('custom-class')
  })
})
