import { useEffect } from 'react'
import styled from 'styled-components'
import { IconName, iconsMap } from './icons'
import { deprecationWarning } from '@navinc/utils'

const bifilter = <T,>(filter: (item: T) => boolean, arr: T[]): [T[], T[]] => {
  const truthy: T[] = []
  const falsey: T[] = []

  arr.forEach((item) => {
    if (filter(item)) {
      truthy.push(item)
    } else {
      falsey.push(item)
    }
  })

  return [truthy, falsey]
}

const handlerRegExp = /^on[A-Z]/
const partitionHandlerProps = <T extends object>(props: T): [T, T] => {
  const [handlers, nonHandlers] = bifilter(([propName]) => handlerRegExp.test(propName), Object.entries(props))

  return [Object.fromEntries(handlers) as T, Object.fromEntries(nonHandlers) as T]
}

type IconProps = {
  name: IconName
  size?: string
} & JSX.IntrinsicElements['svg']
export const Icon = ({ name, size = '24', ...props }: IconProps) => {
  const IconComponent = iconsMap[name]

  return IconComponent ? (
    <IconComponent width={size} height={size} viewBox="0 0 24 24" data-testid={`icon:${name}`} {...props} />
  ) : null
}

const NoStyleButton = styled.button`
  background: none;
  color: inherit;
  border: none;
  padding: 0;
  font: inherit;
  cursor: inherit;
  outline: inherit;
  line-height: 0;
`

/** Pass all event handler props to a wrapper button to avoid rerendering the icon and causing flicker */
const InteractiveIconInternal = (props: IconProps) => {
  useEffect(
    () =>
      deprecationWarning(
        true,
        `The \`InteractiveIcon\` component from Base React Component is deprecated and support will be removed in a future version. Please use \`IconButton\` instead.`
      ),
    []
  )
  const [handlers, nonHandlers] = partitionHandlerProps(props)

  return (
    <NoStyleButton {...(handlers as any)}>
      <Icon {...nonHandlers} />
    </NoStyleButton>
  )
}

export const InteractiveIcon = styled(InteractiveIconInternal)``

export default styled(Icon)``
