import React, { createRef } from 'react'
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
import { axe, toHaveNoViolations } from 'jest-axe'
import { PktProgressbar } from './Progressbar'
import exp from 'constants'

expect.extend(toHaveNoViolations)

describe('PktProgressbar', () => {
  describe('rendering', () => {
    test('renders with default props', async () => {
      const { container } = render(<PktProgressbar id="progress1" valueCurrent={50} />)
      await window.customElements.whenDefined('pkt-progressbar')

      const progressbar = container.querySelector('pkt-progressbar')

      expect(progressbar).toBeInTheDocument()
      expect(progressbar).toHaveAttribute('id', 'progress1')
      expect(progressbar).toHaveAttribute('aria-valuemin', '0')
      expect(progressbar).toHaveAttribute('aria-valuemax', '100')
      expect(progressbar).toHaveAttribute('aria-valuenow', '50')

      const bar = progressbar?.querySelector('.pkt-progressbar__bar--dark-blue')
      expect(bar).toBeInTheDocument()
    })

    test('renders with custom skin', async () => {
      const { container } = render(<PktProgressbar id="progress2" valueCurrent={50} skin="red" />)
      await window.customElements.whenDefined('pkt-progressbar')

      const progressbar = container.querySelector('pkt-progressbar')
      const bar = progressbar?.querySelector('.pkt-progressbar__bar--red')
      expect(bar).toBeInTheDocument()
    })

    test('renders title correctly', async () => {
      const { container, getByText } = render(<PktProgressbar id="progress3" valueCurrent={50} title="Progress" />)
      await window.customElements.whenDefined('pkt-progressbar')

      const progressbar = container.querySelector('pkt-progressbar')

      // Select by class
      const title = progressbar?.querySelector('.pkt-progressbar__title')
      expect(title).toBeInTheDocument()

      // Select by text
      const titleText = getByText('Progress')
      expect(titleText).toBeInTheDocument()
    })

    test('renders title with center position', async () => {
      const { container } = render(
        <PktProgressbar id="progress4" valueCurrent={50} title="Progress" titlePosition="center" />,
      )
      await window.customElements.whenDefined('pkt-progressbar')
      const title = container.querySelector('.pkt-progressbar__title-center')
      expect(title).toBeInTheDocument()
    })

    test('renders status as percentage', async () => {
      const { container } = render(<PktProgressbar id="progress5" valueCurrent={50} statusType="percentage" />)
      await window.customElements.whenDefined('pkt-progressbar')
      const status = container.querySelector('.pkt-progressbar__status')
      expect(status).toBeInTheDocument()
      expect(status).toHaveTextContent('50%')
    })

    test('renders status as fraction', async () => {
      const { container } = render(
        <PktProgressbar id="progress6" valueCurrent={50} valueMax={200} statusType="fraction" />,
      )
      await window.customElements.whenDefined('pkt-progressbar')
      const status = container.querySelector('.pkt-progressbar__status')
      expect(status).toBeInTheDocument()
      expect(status).toHaveTextContent('50 av 200')
    })

    test('renders status with center placement', async () => {
      const { container } = render(
        <PktProgressbar id="progress7" valueCurrent={50} statusType="percentage" statusPlacement="center" />,
      )
      await window.customElements.whenDefined('pkt-progressbar')
      const status = container.querySelector('.pkt-progressbar__status--center')
      expect(status).toBeInTheDocument()
    })

    test('renders status with following placement', async () => {
      const { container } = render(
        <PktProgressbar id="progress8" valueCurrent={50} statusType="percentage" statusPlacement="following" />,
      )
      await window.customElements.whenDefined('pkt-progressbar')
      const status = container.querySelector('.pkt-progressbar__status-placement--following')
      expect(status).toBeInTheDocument()
    })

    test('handles aria-label correctly', async () => {
      const { container } = render(<PktProgressbar id="progress9" valueCurrent={50} ariaLabel="Progress bar" />)
      await window.customElements.whenDefined('pkt-progressbar')
      const progressbar = container.querySelector('pkt-progressbar')
      expect(progressbar).toHaveAttribute('aria-label', 'Progress bar')
      expect(progressbar).not.toHaveAttribute('aria-labelledby')
    })

    test('handles role meter correctly', async () => {
      const { container } = render(
        <PktProgressbar id="progress10" role="meter" valueCurrent={50} ariaLabel="Meter bar" />,
      )
      await window.customElements.whenDefined('pkt-progressbar')
      const progressbar = container.querySelector('pkt-progressbar')
      expect(progressbar).toHaveAttribute('role', 'meter')
    })

    test('handles id for title and aria-labelledby correctly', async () => {
      const { container } = render(<PktProgressbar valueCurrent={50} title="Progress" id="progressId" />)
      await window.customElements.whenDefined('pkt-progressbar')

      const progressbar = container.querySelector('pkt-progressbar')

      expect(progressbar).toBeInTheDocument()
      expect(progressbar).toHaveAttribute('aria-labelledby', 'progressId-title')
    })

    test('generates id if none is provided', async () => {
      const { container } = render(<PktProgressbar valueCurrent={50} />)
      await window.customElements.whenDefined('pkt-progressbar')

      const progressbar = container.querySelector('pkt-progressbar')

      const id = progressbar?.getAttribute('id')
      expect(id).toHaveLength(36)
    })

    test('sets ref correctly', async () => {
      const ref = createRef<HTMLElement>()
      const { unmount } = render(<PktProgressbar ref={ref} id="progress-ref" valueCurrent={50} title="Ref bar" />)

      await window.customElements.whenDefined('pkt-progressbar')

      expect(ref.current).toBeInstanceOf(HTMLElement)
      unmount()
      expect(ref.current).toBeNull()
    })
  })

  // ACCESSIBILITY TESTS

  describe('accessibility', () => {
    test('renders with no wcag errors with axe', async () => {
      const { container } = render(
        <PktProgressbar id="progress-axe" valueCurrent={50} title="Axe test" role="progressbar" />,
      )
      await window.customElements.whenDefined('pkt-progressbar')
      const results = await axe(container)
      expect(results).toHaveNoViolations()
    })
  })
})
