import { useMemo } from 'react'

import { styled, useStyleConfig, vui, VuiComponent } from '../core'
import T from '../t'
import { cs, filterUndefined, isReactText, isString } from '../utils'
import { LinkProvider } from './context'
import { LinkProps } from './link.types'
import LinkIcon from './linkIcon'
import LinkText from './linkText'

const linkSwipeAnimation = `
  @keyframes linkSwipe {
    from {
      background-size: 0 1px;
    }
    to {
      background-size: 100% 1px;
    }
  }
`

export const LinkBase = styled.aBox.attrs((props: LinkProps) => ({
  isUnderlined: props.isUnderlined || false,
}))`
  ${linkSwipeAnimation}
  display: inline;
  cursor: pointer;
  position: relative;
  line-height: 1.5;
  outline: none;
  width: fit-content;
  text-decoration: none;

  &:not(.vui-linkNoUnderline) span {
    position: relative;
    background: linear-gradient(to right, currentcolor, currentcolor);
    background-size: ${({ isUnderlined }) => (isUnderlined ? '100% 1px' : '0 1px')};
    background-position: 0 100%;
    background-repeat: no-repeat;
    text-decoration: none;
    padding-bottom: 2px;
    line-height: 1;
  }

  &:hover span {
    animation: linkSwipe 0.3s ease forwards;
    background-size: 100% 1px;
  }
`

export const Link = vui<'a', LinkProps>((props, ref) => {
  const {
    children,
    className,
    fontWeight,
    iconLeft,
    iconRight,
    isExternal,
    isUnderlined,
    size,
    text,
    variant,
    weight,
    ...rest
  } = props

  const styles = useStyleConfig('Link', props)
  const context = useMemo(() => filterUndefined({ size, variant }), [size, variant])

  const aliasedProps = filterUndefined({
    fontWeight: weight || fontWeight,
    rel: isExternal ? 'noopener' : undefined,
    target: isExternal ? '_blank' : undefined,
  })

  return (
    <LinkProvider value={context}>
      <LinkBase
        alignItems={iconLeft || iconRight ? 'center' : undefined}
        className={cs('vui-link', className)}
        display={iconLeft || iconRight ? 'inline-flex' : 'inline'}
        focusRing={2}
        isUnderlined={isUnderlined}
        ref={ref}
        {...styles.container}
        {...aliasedProps}
        {...rest}
      >
        {isString(iconLeft) ? <LinkIcon mr={1} name={iconLeft} /> : iconLeft}
        <T>{children ?? (isReactText(text) ? <LinkText text={text} /> : text)}</T>
        {isString(iconRight) ? <LinkIcon ml={1} name={iconRight} /> : iconRight}
      </LinkBase>
    </LinkProvider>
  )
}) as VuiComponent<'a', LinkProps> & {
  Icon: typeof LinkIcon
  Text: typeof LinkText
}

Link.Icon = LinkIcon
Link.Text = LinkText
Link.displayName = 'Link'

export default Link
