import type { VariantProps } from 'class-variance-authority'

import { MaterialIcon, MaterialIconSetIconProps } from '../Icons/MaterialIcon'
import { toastVariants } from './variants'

import { useIntl } from 'react-intl'
import { IconButton } from '../IconButton'
import { Typography } from '../Typography'
import styles from './toasts.module.css'

export type ToastsProps = VariantProps<typeof toastVariants> & {
  variant: NonNullable<VariantProps<typeof toastVariants>['variant']>
  onClose?: () => void
} & (
    | {
        children: React.ReactNode
        message?: never
      }
    | {
        children?: never
        message: React.ReactNode
      }
  )

export function Toast({ children, message, onClose, variant }: ToastsProps) {
  const className = toastVariants({ variant })
  const intl = useIntl()
  const Icon = <AlertIcon variant={variant} color="Icon/Inverted" />

  return (
    <div className={className} role={getRole(variant)} aria-atomic="true">
      <div className={styles.iconContainer}>{Icon && Icon}</div>
      {message ? (
        <Typography variant="Body/Paragraph/mdRegular">
          <p className={styles.message}>{message}</p>
        </Typography>
      ) : (
        <div className={styles.content}>{children}</div>
      )}
      {onClose ? (
        <IconButton
          onPress={onClose}
          aria-label={intl.formatMessage({
            id: 'toast.dismissNotification',
            defaultMessage: 'Dismiss notification',
          })}
          variant="Muted"
          emphasis
        >
          <MaterialIcon icon="close" />
        </IconButton>
      ) : null}
    </div>
  )
}

interface AlertIconProps {
  variant: ToastsProps['variant']
}
function AlertIcon({
  variant,
  ...props
}: AlertIconProps & MaterialIconSetIconProps) {
  switch (variant) {
    case 'error':
      return <MaterialIcon icon="cancel" {...props} />
    case 'info':
      return <MaterialIcon icon="info" {...props} />
    case 'success':
      return <MaterialIcon icon="check_circle" {...props} />
    case 'warning':
      return <MaterialIcon icon="warning" {...props} />
  }
}

function getRole(variant: ToastsProps['variant']) {
  switch (variant) {
    case 'error':
    case 'warning':
      return 'alert'
    case 'info':
    case 'success':
    default:
      return 'status'
  }
}
