import { describe, it, expect } from 'vitest'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Accordion } from './Accordion'
import type { AccordionItem } from './Accordion'

const items: AccordionItem[] = [
  { id: 'a', title: 'Section A', content: 'Content A' },
  { id: 'b', title: 'Section B', content: 'Content B' },
  { id: 'c', title: 'Section C', content: 'Content C' },
]

describe('Accordion', () => {
  it('renders all item titles', () => {
    render(<Accordion items={items} />)
    expect(screen.getByText('Section A')).toBeInTheDocument()
    expect(screen.getByText('Section B')).toBeInTheDocument()
    expect(screen.getByText('Section C')).toBeInTheDocument()
  })

  it('does not show content by default when no defaultOpen', () => {
    render(<Accordion items={items} />)
    expect(screen.queryByText('Content A')).not.toBeVisible()
    expect(screen.queryByText('Content B')).not.toBeVisible()
  })

  it('shows content for defaultOpen items', () => {
    const withDefault: AccordionItem[] = [
      { id: 'a', title: 'Section A', content: 'Content A', defaultOpen: true },
      { id: 'b', title: 'Section B', content: 'Content B' },
    ]
    render(<Accordion items={withDefault} />)
    expect(screen.getByText('Content A')).toBeVisible()
    expect(screen.queryByText('Content B')).not.toBeVisible()
  })

  describe('single mode (default)', () => {
    it('opens a section when its trigger is clicked', async () => {
      const user = userEvent.setup()
      render(<Accordion items={items} />)
      await user.click(screen.getByText('Section A'))
      expect(screen.getByText('Content A')).toBeVisible()
    })

    it('closes other sections when a new one is opened', async () => {
      const user = userEvent.setup()
      render(<Accordion items={items} />)
      await user.click(screen.getByText('Section A'))
      expect(screen.getByText('Content A')).toBeVisible()
      await user.click(screen.getByText('Section B'))
      expect(screen.getByText('Content B')).toBeVisible()
      expect(screen.queryByText('Content A')).not.toBeVisible()
    })

    it('closes the open section when clicking it again', async () => {
      const user = userEvent.setup()
      render(<Accordion items={items} />)
      await user.click(screen.getByText('Section A'))
      expect(screen.getByText('Content A')).toBeVisible()
      await user.click(screen.getByText('Section A'))
      expect(screen.queryByText('Content A')).not.toBeVisible()
    })

    it('only keeps first defaultOpen in single mode when multiple defaultOpen set', () => {
      const withMultiDefault: AccordionItem[] = [
        { id: 'a', title: 'Section A', content: 'Content A', defaultOpen: true },
        { id: 'b', title: 'Section B', content: 'Content B', defaultOpen: true },
      ]
      render(<Accordion items={withMultiDefault} />)
      expect(screen.getByText('Content A')).toBeVisible()
      expect(screen.queryByText('Content B')).not.toBeVisible()
    })
  })

  describe('multiple mode', () => {
    it('allows multiple sections to be open simultaneously', async () => {
      const user = userEvent.setup()
      render(<Accordion items={items} multiple />)
      await user.click(screen.getByText('Section A'))
      await user.click(screen.getByText('Section B'))
      expect(screen.getByText('Content A')).toBeVisible()
      expect(screen.getByText('Content B')).toBeVisible()
    })

    it('toggles individual sections independently', async () => {
      const user = userEvent.setup()
      render(<Accordion items={items} multiple />)
      await user.click(screen.getByText('Section A'))
      await user.click(screen.getByText('Section B'))
      await user.click(screen.getByText('Section A'))
      expect(screen.queryByText('Content A')).not.toBeVisible()
      expect(screen.getByText('Content B')).toBeVisible()
    })

    it('respects multiple defaultOpen items in multiple mode', () => {
      const withMultiDefault: AccordionItem[] = [
        { id: 'a', title: 'Section A', content: 'Content A', defaultOpen: true },
        { id: 'b', title: 'Section B', content: 'Content B', defaultOpen: true },
      ]
      render(<Accordion items={withMultiDefault} multiple />)
      expect(screen.getByText('Content A')).toBeVisible()
      expect(screen.getByText('Content B')).toBeVisible()
    })
  })
})
