import React from 'react'
import PropTypes from 'prop-types'
import {
  ChevronLink,
  selectSystemProps,
  useThemeTokens,
  Typography,
  withLinkRouter,
  Spacer,
  useViewport,
  getTokensPropType
} from '@telus-uds/components-base'
import styled, { css, keyframes } from 'styled-components'
import { htmlAttrs } from '../utils'

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

const transform = (property) => (from, to) =>
  keyframes`
  from {
    ${property}: ${from};
  }
  to {
    ${property}: ${to};
  }
`

const slideDown =
  (property) =>
  (from, to, end = to) =>
    keyframes`
  0% {
    ${property}: ${from};
  }
  99% {
    ${property}: ${to};
  }
  100% {
    ${property}: ${end};
  }
`

const animation = (props) => css`
  ${slideDown('height')(
    `${props.animationHeightBefore}px`,
    `${props.animationHeightAfter}px`,
    'auto'
  )} 1s ease-in-out 2s forwards,
    ${transform('padding-bottom')(
    `${props.animationPaddingBottomBefore}px`,
    `${props.animationPaddingBottomAfter}px`
  )} 1s ease-in-out 2s forwards,
    ${transform('padding-top')(
    `${props.animationPaddingTopBefore}px`,
    `${props.animationPaddingTopAfter}px`
  )} 1s ease-in-out 2s forwards,
    ${transform('background')(
    props.animationBackgroundColorBefore,
    props.animationBackgroundColorAfter
  )} 1s ease-in-out 3.2s forwards;
  & * {
    animation: ${transform('color')(props.animationColorBefore, props.animationColorAfter)} 1s
      ease-in-out 3s forwards;
  }
  & > a div {
    animation: ${transform('color')(props.animationDivColorBefore, props.animationDivColorAfter)} 1s
      ease-in-out 3s forwards;
  }
  & > a svg {
    animation: ${transform('fill')(props.animationFillColorBefore, props.animationFillColorAfter)}
      1s ease-in-out 3s forwards;
  }
  & > a div {
    animation: ${transform('color')(props.animationFillColorBefore, props.animationFillColorAfter)}
      1s ease-in-out 3s forwards;
  }
`

const ToastContainer = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  padding-left: ${({ padding }) => padding}px;
  padding-right: ${({ padding }) => padding}px;
  background: ${({ containerBackgroundColor }) => containerBackgroundColor};
  gap: ${({ containerGap }) => containerGap};
  height: 0;
  overflow: hidden;
  animation: ${animation};
`

const Toast = React.forwardRef(
  ({ toast, copy, headline, link, tokens, variant = {}, ...rest }, ref) => {
    // viewport hook added to work adjust the padding to different sizes
    const viewport = useViewport()

    const {
      containerBackgroundColor,
      containerGap,
      animationHeightBefore,
      animationHeightAfter,
      animationPaddingBottomBefore,
      animationPaddingBottomAfter,
      animationPaddingTopBefore,
      animationPaddingTopAfter,
      animationBackgroundColorBefore,
      animationBackgroundColorAfter,
      animationColorBefore,
      animationColorAfter,
      chevronlinkFontWeight,
      ...extraTokens
    } = useThemeTokens('Toast', tokens, variant, { viewport })

    // inherit ChevronLink tokens for animation colors
    const { color: chevronDefaultColor } = useThemeTokens('ChevronLink', {}, {})
    const { color: chevronInverseColor } = useThemeTokens('ChevronLink', {}, { inverse: true })

    if (!toast) {
      return null
    }

    return (
      <ToastContainer
        containerBackgroundColor={containerBackgroundColor}
        containerGap={containerGap}
        animationHeightBefore={animationHeightBefore}
        animationHeightAfter={animationHeightAfter}
        animationPaddingBottomBefore={animationPaddingBottomBefore}
        animationPaddingBottomAfter={animationPaddingBottomAfter}
        animationPaddingTopBefore={animationPaddingTopBefore}
        animationPaddingTopAfter={animationPaddingTopAfter}
        animationBackgroundColorBefore={animationBackgroundColorBefore}
        animationBackgroundColorAfter={animationBackgroundColorAfter}
        animationColorBefore={animationColorBefore}
        animationColorAfter={animationColorAfter}
        animationFillColorBefore={chevronInverseColor}
        animationFillColorAfter={chevronDefaultColor}
        ref={ref}
        {...extraTokens}
        {...selectProps(rest)}
      >
        {headline && <Typography variant={{ bold: true, inverse: true }}>{headline}</Typography>}
        <Spacer space={2} direction="row" />
        <Typography variant={{ inverse: true }}>{copy}</Typography>
        <Spacer space={2} direction="row" />
        {link && (
          <ChevronLink
            variant={{
              inverse: true
            }}
            tokens={{ blockFontWeight: chevronlinkFontWeight }}
            href={link.href}
            LinkRouter={link.LinkRouter}
            linkRouterProps={link.linkRouterProps}
          >
            {link.text}
          </ChevronLink>
        )}
      </ToastContainer>
    )
  }
)

Toast.displayName = 'Toast'

Toast.propTypes = {
  ...selectedSystemPropTypes,
  tokens: getTokensPropType('Toast'),
  /**
   * If true, the toast will be displayed
   */
  toast: PropTypes.bool,
  /**
   * The copy to display in the toast
   */
  copy: PropTypes.string.isRequired,
  /**
   * The headline to display in the toast (before copy)
   */
  headline: PropTypes.string,
  /**
   * The link to display in the toast (after copy)
   */
  link: PropTypes.shape({
    href: PropTypes.string.isRequired,
    text: PropTypes.string.isRequired,
    LinkRouter: withLinkRouter.propTypes?.LinkRouter,
    linkRouterProps: withLinkRouter.propTypes?.linkRouterProps
  })
}

export default Toast
