import React from 'react'
import PropTypes from 'prop-types'
import {
  applyTextStyles,
  selectSystemProps,
  useCopy,
  useThemeTokens,
  variantProp
} from '@telus-uds/components-base'
import styled from 'styled-components'
import dictionary from './dictionary'
import { htmlAttrs } from '../utils'

const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])

const StyledSup = styled.sup(
  ({ fontSize, lineHeight, paddingLeft, paddingRight, ...fontNameAndWeight }) => {
    return {
      border: 0,
      color: 'inherit',
      cursor: 'pointer',
      // we want to fallback on 'smaller' but have a valid size when a custom font size is provided.
      fontSize: fontSize ? `${fontSize}px` : 'smaller',
      lineHeight: lineHeight ?? `${fontSize * 2}px`,
      margin: 0,
      paddingVertical: 0,
      paddingLeft,
      paddingRight,
      textDecoration: 'underline',
      // apply font family
      ...applyTextStyles(fontNameAndWeight)
    }
  }
)

/**
 * Use `FootnoteLink` to open `Footnote` component and display related legal content.
 *
 * ## Usage Criteria
 *
 * - Use FootnoteLink to open a Footnote component and display related legal content.
 * - Avoid using FootnoteLink if there is only one annotation on a page. Consider including
 *   the annotation as part of the content whenever possible.
 */
const FootnoteLink = React.forwardRef(
  ({ copy = 'en', number = [], onClick, fontSize, tokens, variant = {}, ...rest }, ref) => {
    const themeTokens = useThemeTokens('FootnoteLink', tokens, variant)
    const numbers = Array.isArray(number) ? number : [number]
    const refs = numbers.map(() => React.createRef())
    const handleClick = (index) => {
      onClick(numbers[index], refs[index])
    }
    const getCopy = useCopy({ dictionary, copy })

    const handleOnClick = (event, index) => {
      event.preventDefault()
      event.stopPropagation()
      handleClick(index)
    }

    const handleOnKeyDown = (event, index) => {
      if (event.key === 'Enter' || event.key === 13) {
        handleClick(index)
      }
    }

    return (
      <span ref={ref}>
        {numbers.map((num, index) => (
          <StyledSup
            onKeyDown={(event) => handleOnKeyDown(event, index)}
            role="button"
            aria-label={getCopy('a11yLabel')}
            key={num}
            ref={refs[index]}
            onClick={(event) => handleOnClick(event, index)}
            tabIndex={0}
            {...selectProps(rest)}
            {...themeTokens}
            fontSize={fontSize ?? themeTokens.fontSize}
          >
            {`${num}${index !== numbers.length - 1 ? ',' : ''}`}
          </StyledSup>
        ))}
      </span>
    )
  }
)

FootnoteLink.displayName = 'FootnoteLink'

const copyShape = PropTypes.shape({
  a11yLabel: PropTypes.string.isRequired
})

FootnoteLink.propTypes = {
  ...selectedSystemPropTypes,
  variant: variantProp.propType,
  /**
   * Use the `copy` prop to either select provided English or French copy by passing 'en' or 'fr' respectively.
   * To provide your own, pass a JSON object with the key `a11yLabel`.
   */
  copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr']), copyShape]),
  /**
   * The footnote number, or multiple numbers if passed as an array.
   * If using an array, a comma-separated group of numbers will be rendered as superscript.
   */
  number: PropTypes.oneOfType([
    PropTypes.number,
    PropTypes.arrayOf(PropTypes.number),
    PropTypes.string,
    PropTypes.arrayOf(PropTypes.string)
  ]).isRequired,
  /**
   * A callback function to handle the click of a FootnoteLink.
   */
  onClick: PropTypes.func.isRequired,
  /**
   * Override default `fontSize` to set specific font size value
   */
  fontSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
}

export default FootnoteLink
