import '@testing-library/jest-dom'

import { render, screen, waitFor } from '../../utils/test-utils'
import { PktIcon } from './Icon'

declare global {
  interface Window {
    pktFetch: () => Promise<{ ok: boolean; text: () => Promise<string> }>
    pktIconPath: string
  }
}

describe('PktIcon', () => {
  window.pktFetch = (file = 'filnavn.svg') =>
    Promise.resolve({
      ok: true,
      text: () => Promise.resolve(`<svg role="img" data-testid="icon" data-filename=${file}>Her er SVGen</svg>`),
    })
  window.pktIconPath = 'sti'

  describe('with default fetcher', () => {
    test('fetches SVG with default fetcher', async () => {
      await render(<PktIcon name="arrow" />)

      const icon = await screen.findByTestId('icon')
      expect(icon).toMatchInlineSnapshot(`
        <svg
          aria-hidden="true"
          data-filename="stiarrow.svg"
          data-testid="icon"
          role="img"
        >
          Her er SVGen
        </svg>
      `)
    })

    test('fetches SVG', async () => {
      const { container } = await render(
        <div className="root">
          <PktIcon name={'some-icon'} />
          <PktIcon name={'some-other-icon'} />
          <PktIcon name={'some-icon'} />
        </div>,
      )

      await waitFor(async () => {
        const icons = await screen.findAllByTestId('icon')
        expect(icons).toHaveLength(3)
      })
    })
  })

  describe('aria-hidden', () => {
    test('defaults to true on the SVG', async () => {
      await render(<PktIcon name="arrow" />)
      const svg = await screen.findByTestId('icon')

      expect(svg).toHaveAttribute('aria-hidden', 'true')
      expect(svg).not.toHaveAttribute('aria-label')
    })

    test('ariaHidden={false} sets aria-hidden="false" and aria-label fallback to name', async () => {
      await render(<PktIcon name="arrow" ariaHidden={false} />)
      const svg = await screen.findByTestId('icon')

      expect(svg).toHaveAttribute('aria-hidden', 'false')
      expect(svg).toHaveAttribute('aria-label', 'arrow')
    })

    test('ariaHidden="false" string is treated as boolean false', async () => {
      await render(<PktIcon name="arrow" ariaHidden="false" />)
      const svg = await screen.findByTestId('icon')

      expect(svg).toHaveAttribute('aria-hidden', 'false')
    })

    test('ariaHidden="true" string is treated as boolean true', async () => {
      await render(<PktIcon name="arrow" ariaHidden="true" />)
      const svg = await screen.findByTestId('icon')

      expect(svg).toHaveAttribute('aria-hidden', 'true')
    })

    test('back-compat: aria-hidden kebab attribute still routes to the SVG', async () => {
      const { container } = await render(<PktIcon name="arrow" aria-hidden={false} />)
      const svg = await screen.findByTestId('icon')

      expect(svg).toHaveAttribute('aria-hidden', 'false')
      // Wrapper span itself should not carry aria-hidden
      expect(container.querySelector('.pkt-icon')).not.toHaveAttribute('aria-hidden')
    })
  })

  describe('aria-label', () => {
    test('ariaLabel alone makes aria-hidden default to false', async () => {
      await render(<PktIcon name="arrow" ariaLabel="Gå til forsiden" />)
      const svg = await screen.findByTestId('icon')

      expect(svg).toHaveAttribute('aria-hidden', 'false')
      expect(svg).toHaveAttribute('aria-label', 'Gå til forsiden')
    })

    test('ariaLabel + ariaHidden={true} keeps aria-hidden="true" and omits aria-label', async () => {
      await render(<PktIcon name="arrow" ariaLabel="Lukk" ariaHidden={true} />)
      const svg = await screen.findByTestId('icon')

      expect(svg).toHaveAttribute('aria-hidden', 'true')
      expect(svg).not.toHaveAttribute('aria-label')
    })

    test('ariaHidden={false} without ariaLabel falls back to the icon name', async () => {
      await render(<PktIcon name="chevron-right" ariaHidden={false} />)
      const svg = await screen.findByTestId('icon')

      expect(svg).toHaveAttribute('aria-label', 'chevron-right')
    })
  })
})
