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

describe('Calendar', () => {
  it('exposes grid role and fires onSelect when a day is clicked', () => {
    const onSelect = vi.fn()
    render(<Calendar mode="single" month={new Date(2025, 5, 1)} onSelect={onSelect} />)
    expect(screen.getByRole('grid')).toBeTruthy()
    const day = screen.getByRole('button', { name: /June 15/ })
    fireEvent.click(day)
    expect(onSelect).toHaveBeenCalled()
    const selected = onSelect.mock.calls[0]![0] as Date
    expect(selected).toBeInstanceOf(Date)
    expect(selected.getDate()).toBe(15)
    expect(selected.getMonth()).toBe(5)
    expect(selected.getFullYear()).toBe(2025)
  })

  it('fires onMonthChange with the adjacent month when a nav button is clicked (controlled month)', () => {
    const onMonthChange = vi.fn()
    render(<Calendar mode="single" month={new Date(2025, 5, 1)} onMonthChange={onMonthChange} />)
    fireEvent.click(screen.getByRole('button', { name: /Previous Month/i }))
    expect(onMonthChange).toHaveBeenCalledTimes(1)
    const arg = onMonthChange.mock.calls[0]![0] as Date
    expect(arg).toBeInstanceOf(Date)
    expect(arg.getMonth()).toBe(4)
    expect(arg.getFullYear()).toBe(2025)
  })

  it('uses token-backed day/nav states and stays axe-clean', async () => {
    const { container } = render(<Calendar mode="single" month={new Date(2025, 5, 1)} />)
    expect(screen.getByRole('button', { name: /Previous Month/i }).className).toContain(
      'hover:bg-[var(--mod-color-accent-a3)]',
    )
    expect(screen.getByRole('button', { name: /June 15/ }).className).toContain(
      'focus-visible:outline-[var(--mod-focus-ring-color)]',
    )
    await expect(axe(container)).resolves.toHaveNoViolations()
  })
})
