import { memo } from 'react';
import type { ReactNode } from 'react';

import Badge from '@mui/material/Badge';
import type { BadgeProps } from '@mui/material/Badge';
import Grid from '@mui/material/Grid';
import type { GridProps as MuiGridProps } from '@mui/material/Grid';
import { styled } from '@mui/material/styles';

import clsx from 'clsx';
import isEmpty from 'lodash/isEmpty';

import { Avatar } from '../avatar';
import type { AvatarProps } from '../avatar';
import { TextWithTooltip } from '../text-with-tooltip';
import type { Theme } from '../@styles/theme-provider';

const StyledContainer = styled(Grid)(({ theme }: { theme: Theme }) => ({
  '& .MuiBadge-dot': {
    maxWidth: theme.spacing(1),
    height: theme.spacing(1),
    '&.MuiBadge-colorPrimary': {
      backgroundColor: theme.palette.success[500]
    },
    '&.MuiBadge-colorSecondary': {
      backgroundColor: theme.palette.success[500],
      boxShadow: `0 0 0 1px ${theme.palette.common.white}`,
      color: theme.palette.success[500],
      '&::after': {
        position: 'absolute',
        top: 0,
        left: 0,
        width: '100%',
        height: '100%',
        borderRadius: '50%',
        animation: 'rippleEffect 1.2s infinite ease-in-out',
        border: `1px solid currentColor`,
        content: '""'
      }
    },
    '&.MuiBadge-colorError': {
      backgroundColor: theme.palette.error[500]
    }
  },
  '& .groupContainer': {
    '&.withAvatar': {
      marginLeft: theme.spacing(1),
      width: 'auto'
    },
    '&.noSubtitle': {
      justifyContent: 'center'
    },
    '& .groupTitle': {
      ...theme.typography.body2,
      color: theme.palette.primary[500],
      textAlign: 'start'
    },
    '& .groupAfterTitle': {
      marginLeft: theme.spacing(1)
    },
    '& .groupSubtitle': {
      ...theme.typography.caption1,
      color: theme.palette.primary[400],
      textAlign: 'start'
    }
  },
  '@keyframes rippleEffect': {
    '0%': {
      transform: 'scale(.8)',
      opacity: 1
    },
    '100%': {
      transform: 'scale(2.4)',
      opacity: 0
    }
  }
}));

export interface TableTextGroupProps extends MuiGridProps {
  /**
   * The title to be displayed.
   */
  title: string;
  /**
   * The content to be displayed right after the title.
   */
  afterTitle?: ReactNode;
  /**
   * The subtitle to be displayed.
   * @default ""
   */
  subtitle?: ReactNode;
  /**
   * Avatar props which will be passed to the avatar component.
   */
  avatarProps?: AvatarProps;
  /**
   * Props to be supplied directly into the Badge component (set `color` prop to render status with badge dot).
   */
  badgeProps?: BadgeProps;
  /**
   * Flag for truncating the text (using TextWithTooltip).
   */
  truncateText?: boolean;
}

const TableTextGroup = (props: TableTextGroupProps) => {
  const {
    title,
    afterTitle,
    subtitle = '',
    avatarProps,
    badgeProps,
    truncateText,
    ...otherProps
  } = props;

  return (
    <StyledContainer container alignItems="center" wrap="nowrap" {...otherProps}>
      {!isEmpty(avatarProps) &&
        (badgeProps ? (
          <Badge
            anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
            color="primary"
            overlap="circular"
            variant="dot"
            {...badgeProps}
          >
            <Avatar {...avatarProps} />
          </Badge>
        ) : (
          <Avatar {...avatarProps} />
        ))}
      <Grid
        container
        direction="column"
        className={clsx('groupContainer', avatarProps && 'withAvatar', !subtitle && 'noSubtitle')}
      >
        <Grid container alignItems="center" flexWrap="nowrap" className="groupTitleContainer">
          {truncateText ? (
            <TextWithTooltip
              disableInteractive={false}
              text={title}
              numOfLines={1}
              textClassName="groupTitle"
            />
          ) : (
            <span className="groupTitle">{title}</span>
          )}
          {afterTitle && <span className="groupAfterTitle">{afterTitle}</span>}
        </Grid>
        {subtitle &&
          (typeof subtitle !== 'string' ? (
            subtitle
          ) : truncateText ? (
            <TextWithTooltip
              disableInteractive={false}
              text={subtitle}
              numOfLines={2}
              textClassName="groupSubtitle"
            />
          ) : (
            <span className="groupSubtitle">{subtitle}</span>
          ))}
      </Grid>
    </StyledContainer>
  );
};

const m = memo(TableTextGroup);
export { m as TableTextGroup };
