import '@testing-library/jest-dom'
import { axe, toHaveNoViolations } from 'jest-axe'
import { PktAccordion } from './Accordion'
import { PktAccordionItem } from './AccordionItem'
import { render, screen, waitFor } from '@testing-library/react'
import React, { createRef } from 'react'

expect.extend(toHaveNoViolations)

describe('PktAccordion', () => {
  test('renders without errors', async () => {
    render(
      <PktAccordion>
        <PktAccordionItem id="render-id" title="test">
          content
        </PktAccordionItem>
      </PktAccordion>,
    )
    await window.customElements.whenDefined('pkt-icon')
    // Assert that the Accordion component renders without throwing any errors
  })

  test('renders children', async () => {
    const mockToggleOpen = jest.fn()
    render(
      <PktAccordion>
        <PktAccordionItem title="Title 1" id="item1" onClick={mockToggleOpen}>
          Content 1
        </PktAccordionItem>
        <PktAccordionItem title="Title 2" id="item2" onClick={mockToggleOpen}>
          Content 2
        </PktAccordionItem>
      </PktAccordion>,
    )
    await window.customElements.whenDefined('pkt-icon')

    // Assert that the Accordion component renders its children correctly
    expect(screen.getByText('Title 1')).toBeInTheDocument()
    expect(screen.getByText('Content 1')).toBeInTheDocument()
    expect(screen.getByText('Title 2')).toBeInTheDocument()
    expect(screen.getByText('Content 2')).toBeInTheDocument()
  })

  test('applies compact and skin', async () => {
    const ref = createRef<any>()
    const { container } = render(
      <>
        <h3 id="accordion-heading">Accordion Heading</h3>
        <PktAccordion ref={ref}>
          <PktAccordionItem title="Title" id="item1">
            Content
          </PktAccordionItem>
        </PktAccordion>
      </>,
    )

    // Wait for the element to be defined
    await window.customElements.whenDefined('pkt-accordion')
    await window.customElements.whenDefined('pkt-accordion-item')

    // Now manually set properties on the element
    if (ref.current) {
      ref.current.skin = 'blue'
      ref.current.compact = true
      await ref.current.updateComplete // Wait for Lit to update
    }

    const accordion = container.querySelector('pkt-accordion')!
    expect(accordion).toBeInTheDocument()
    expect(accordion).toHaveAttribute('compact') // compact reflected as boolean attribute
    expect(accordion).toHaveAttribute('skin', 'blue')
  })
})

describe('PktAccordionItem', () => {
  test('applies compact and skin', async () => {
    const ref = createRef<any>()
    const { container } = render(
      <>
        <PktAccordionItem ref={ref} title="Title" id="item1" skin="blue" compact>
          Content
        </PktAccordionItem>
      </>,
    )

    // Wait for the element to be defined
    await window.customElements.whenDefined('pkt-accordion-item')

    // Now manually set properties on the element
    if (ref.current) {
      ref.current.skin = 'blue'
      ref.current.compact = true
      ref.current.requestUpdate()
      await ref.current.updateComplete
    }

    const details = container.querySelector('details')!
    expect(details.classList.contains('pkt-accordion-item--blue')).toBe(true)
  })
})

describe('accessibility', () => {
  it('renders with no wcag errors with axe', async () => {
    const { container } = render(
      <PktAccordion>
        <PktAccordionItem title="Title 1" id="item1">
          Content 1
        </PktAccordionItem>
        <PktAccordionItem title="Title 2" id="item2">
          Content 2
        </PktAccordionItem>
      </PktAccordion>,
    )
    await window.customElements.whenDefined('pkt-icon')
    const results = await axe(container)
    expect(results).toHaveNoViolations()
  })
})
