import { HTMLAttributes, ImgHTMLAttributes } from 'react'
import styled from 'styled-components'

import { Copy } from './copy'
import { Icon } from './icon'
import { IconName } from './icons'
import type { SizeKey } from './copy'

const sizeMap = {
  medium: '32px',
  large: '50px',
}

type Size = keyof typeof sizeMap
type AvatarProps = {
  /** Image url for the avatar */
  src?: string
  /** Always provide an accessibility alt for images. Be descriptive, ie: "Jim Beam\'s profile photo" */
  alt?: string
  /** Size of the avatar image/icon container */
  size?: Size
  /** String value next to image. Used as a text abbreviation for the avatar if no image or icon is provided. */
  label?: string
  /** Fallback icon if no image `src` or label provided */
  defaultIcon?: IconName
  /** Passed as `size` prop to the `<Copy>` component */
  labelSize?: SizeKey
} & HTMLAttributes<HTMLDivElement>

const getSize = (size?: Size) => {
  if (!size) return sizeMap.medium
  return sizeMap[size]
}

const getDefaultText = (text = '') => {
  const initials = text.match(/\b\w/g)?.join('').toUpperCase()

  if (!initials) return ''

  if (initials.length > 1) return initials[0] + initials.slice(-1)

  return text.substring(0, 2).toUpperCase()
}

const ImgContainer = styled.div<AvatarProps>(
  ({ size, src, label, theme }) => `{
    border-radius: 10px;
    background-color: ${src ? 'transparent' : theme.navNeutral100};
    height: ${getSize(size)};
    width: ${getSize(size)};
    min-width: ${getSize(size)};
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: ${label ? '16px' : 0};
    overflow: hidden;
  }`
)

const Img = styled.img<ImgHTMLAttributes<HTMLImageElement>>`
  width: 100%;
`

const AvatarImage = ({ alt, src, size, label, defaultIcon = 'people/profile' }: AvatarProps) => (
  <ImgContainer size={size} src={src} label={label}>
    {src && <Img alt={alt || 'avatar image'} src={src} data-testid="avatar:image" />}
    {!src && label && <Copy data-testid="avatar:abbr">{getDefaultText(label)}</Copy>}
    {!src && !label && <Icon data-testid={`avatar:icon ${defaultIcon}`} name={defaultIcon} />}
  </ImgContainer>
)

const AvatarContainer = styled.div`
  display: flex;
  align-items: center;

  ${Copy} {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
`

export const Avatar = ({ className, label, size, alt, src, defaultIcon, labelSize = 'md', ...rest }: AvatarProps) => (
  <AvatarContainer className={className} data-testid="avatar" {...rest}>
    <AvatarImage size={size} alt={alt} src={src} label={label} defaultIcon={defaultIcon} />
    {label && (
      <Copy data-testid="avatar:label" size={labelSize}>
        {label}
      </Copy>
    )}
  </AvatarContainer>
)
