import * as React from 'react'
import * as FeatherIcon from 'react-feather'
import styled from 'styled-components'
import { pascalCase, pascalCaseTransformMerge } from 'pascal-case'
import splitValueAndUnit from '../../utilities/splitValueAndUnit'

const Label = styled('span')({
  position: 'absolute',
  left: -999999,
  width: 1,
  height: 1,
  ':empty': {
    display: 'none',
  },
})

const StyledIcon = styled('svg')({
  stroke: 'currentColor',
  strokeLinecap: 'round',
  display: 'inline-block',
  verticalAlign: 'middle',
})

export type Props = {
  /**
   * Name of the icon to display.
   */
  name: string,
  /**
   * Width of the icon's strokes.
   */
  weight?: string | number,
  /**
   * Size of the icon. This controls both the width and the height.
   */
  size?: string | number,
  /**
   * Description of what the component represents.
   */
  label?: string,
}

/**
 * Component for displaying simple graphics.
 *
 * @see {@link https://feathericons.com|Feather Icons} for a list of icon names.
 */
export const Icon: React.FC<Props> = ({ name, weight = '0.125rem', size = '1.5rem', label = name }) => {
  const iconName = pascalCase(name, { transform: pascalCaseTransformMerge })
  const { [iconName as keyof typeof FeatherIcon]: TheIcon = null } = FeatherIcon
  const { magnitude: sizeValue, unit: sizeUnit } = splitValueAndUnit(size)
  const { magnitude: weightValue } = splitValueAndUnit(weight)
  const factor = weightValue * (3 / 2)

  if (TheIcon !== null) {
    return (
      <span>
        <StyledIcon
          as={TheIcon}
          size={undefined}
          color={undefined}
          strokeLinecap={undefined}
          strokeWidth={undefined}
          style={{
            width: size!,
            height: size!,
            strokeWidth: `${factor / sizeValue}${sizeUnit}`,
          }}
          aria-label={label!}
        />
        <Label aria-hidden="true">{label}</Label>
      </span>
    )
  }

  return null
}

Icon.displayName = 'Icon'

export default Icon
