import { render, screen } from '@testing-library/react'

import { PktLink } from './Link'

describe('PktLink', () => {
  it('should render with children element', () => {
    render(
      <PktLink href="/test">
        Test <strong>Link</strong>
      </PktLink>,
    )
    const link = screen.getByRole('link')
    expect(link.innerHTML).toEqual('Test <strong>Link</strong>')
  })

  it('should apply href attribute', () => {
    render(<PktLink href="/test-url">Test Link</PktLink>)
    const link = screen.getByText('Test Link')
    expect(link).toHaveAttribute('href', '/test-url')
  })

  it('should apply base pkt-link class', () => {
    render(<PktLink href="/test">Test Link</PktLink>)
    const link = screen.getByText('Test Link')
    expect(link).toHaveClass('pkt-link')
  })

  it('should apply custom className in addition to base class', () => {
    render(
      <PktLink href="/test" className="custom-class">
        Test Link
      </PktLink>,
    )
    const link = screen.getByText('Test Link')
    expect(link).toHaveClass('pkt-link')
    expect(link).toHaveClass('custom-class')
  })

  it.each`
    description                                            | iconName     | iconPosition | expectedClasses             | notExpectedClasses
    ${'icon-left class when iconName and no iconPosition'} | ${'arrow'}   | ${undefined} | ${['pkt-link--icon-left']}  | ${['pkt-link--icon-right']}
    ${'icon-left class when iconPosition is "left"'}       | ${'arrow'}   | ${'left'}    | ${['pkt-link--icon-left']}  | ${['pkt-link--icon-right']}
    ${'icon-right class when iconPosition is "right"'}     | ${'arrow'}   | ${'right'}   | ${['pkt-link--icon-right']} | ${['pkt-link--icon-left']}
    ${'no icon classes when iconName is not provided'}     | ${undefined} | ${undefined} | ${[]}                       | ${['pkt-link--icon-left', 'pkt-link--icon-right']}
    ${'no icon classes when iconName is not provided'}     | ${undefined} | ${'left'}    | ${[]}                       | ${['pkt-link--icon-left', 'pkt-link--icon-right']}
  `('should apply $description', ({ iconName, iconPosition, expectedClasses, notExpectedClasses }) => {
    render(
      <PktLink href="/test" iconName={iconName} iconPosition={iconPosition}>
        Test Link
      </PktLink>,
    )
    const link = screen.getByText('Test Link')
    expectedClasses.forEach((className: string) => {
      expect(link).toHaveClass(className)
    })
    notExpectedClasses.forEach((className: string) => {
      expect(link).not.toHaveClass(className)
    })
    const icon = document.querySelector('.pkt-link__icon')
    if (iconName) {
      expect(icon).toBeInTheDocument();
    } else {
      expect(icon).not.toBeInTheDocument();
    }
  })

  it.each`
    description                                              | external     | hasExternalClass | relAttribute
    ${'external class and rel when external is true'}        | ${true}      | ${true}          | ${'noopener noreferrer'}
    ${'no external class or rel when external is false'}     | ${false}     | ${false}         | ${null}
    ${'no external class or rel when external is undefined'} | ${undefined} | ${false}         | ${null}
  `('should apply $description', ({ external, hasExternalClass, relAttribute }) => {
    render(
      <PktLink href="/test" external={external}>
        Test Link
      </PktLink>,
    )
    const link = screen.getByText('Test Link')

    if (hasExternalClass) {
      expect(link).toHaveClass('pkt-link--external')
    } else {
      expect(link).not.toHaveClass('pkt-link--external')
    }

    if (relAttribute) {
      expect(link).toHaveAttribute('rel', relAttribute)
    } else {
      expect(link).not.toHaveAttribute('rel')
    }
  })

  it('should apply target attribute', () => {
    render(
      <PktLink href="/test" target="_blank">
        Test Link
      </PktLink>,
    )
    const link = screen.getByText('Test Link')
    expect(link).toHaveAttribute('target', '_blank')
  })

  it('should spread additional props to anchor element', () => {
    render(
      <PktLink href="/test" data-testid="custom-link" aria-label="Custom label">
        Test Link
      </PktLink>,
    )
    const link = screen.getByTestId('custom-link')
    expect(link).toHaveAttribute('aria-label', 'Custom label')
  })
})
