import { useEffect, useState } from 'react';
import styled from '@emotion/styled';

import { amber, green, common } from '@mui/material/colors';
import { Box, IconButton, Typography } from '@mui/material';
import { useCreation } from 'ahooks';
import { Close as CloseIcon } from '@mui/icons-material';
import { Icon, IconifyIcon } from '@iconify/react';
import CheckIcon from '@iconify-icons/tabler/circle-check';
import WarningIcon from '@iconify-icons/tabler/exclamation-circle';
import InfoIcon from '@iconify-icons/tabler/info-circle';
import ErrorIcon from '@iconify-icons/tabler/xbox-x';

import { useSnackbar, SnackbarContent } from 'notistack';

import useWidth from './hooks/use-width';
import useActivityTitle from './hooks/use-title';
import { isIncludeActivity, toClickableSpan, sanitize } from './utils';

// Define type for breakpoints
type BreakpointType = 'xl' | 'lg' | 'md' | 'sm';

// Define types for notification component

const variants: Record<string, IconifyIcon> = {
  normal: InfoIcon,
  success: CheckIcon,
  info: InfoIcon,
  warning: WarningIcon,
  error: ErrorIcon,
};

// Styled components
const CloseIconStyled = styled(CloseIcon)`
  font-size: 20px;
`;

const MessageDiv = styled.div`
  display: flex;
  align-items: flex-start;
  gap: 8px;
  flex: 1;
  width: 0;
`;

const ActionDiv = styled.div`
  display: flex;
  align-items: center;
  margin-left: auto;
  margin-right: -8px;
  width: 44px;
`;

// Define breakpoints map
const breakpointsMap: Record<BreakpointType, string> = {
  xl: '400px',
  lg: '400px',
  md: '400px',
  sm: '300px',
};

const StyledSnackbarContent = styled(SnackbarContent)<{ severity?: string; breakpoint: string }>`
  display: flex;
  color: #fff;
  align-items: center;
  padding: 12px 16px;
  border-radius: 4px;
  box-shadow:
    0px 3px 5px -1px rgba(0, 0, 0, 0.2),
    0px 6px 10px 0px rgba(0, 0, 0, 0.14),
    0px 1px 18px 0px rgba(0, 0, 0, 0.12);

  ${({ severity, breakpoint }) => {
    const width = breakpointsMap[breakpoint as BreakpointType] || '400px';

    if (severity === 'success') {
      return `
        background-color: ${green[600]} !important;
        width: ${width};
      `;
    }

    if (severity === 'error') {
      return `
        background-color: #d32f2f !important;
        width: ${width};
      `;
    }

    if (severity === 'info') {
      return `
        background-color: #1976d2 !important;
        width: ${width};
      `;
    }

    if (severity === 'warning') {
      return `
        background-color: ${amber[700]} !important;
        width: ${width};
      `;
    }

    return `
      background-color: #333;
      width: ${width};
    `;
  }}
`;

const ClickableDiv = styled.div`
  cursor: pointer;
  display: flex;
  flex-direction: column;
  .title {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    font-weight: bold;
  }
  .desc {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    word-break: break-word;
    line-height: 1.2;
    .link,
    .dapp,
    .common {
      color: ${common.white};
    }
  }
`;

interface NotificationComponentProps {
  viewAllUrl: string;
  keyId: number;
  notification?: {
    severity?: string;
    title?: string;
    description?: string;
    activity?: any;
    actorInfo?: any;
  };
  // eslint-disable-next-line react/require-default-props
  content?: React.ReactNode;
}

export default function NotificationComponent({
  ref = undefined,
  keyId: key,
  notification = {},
  viewAllUrl,
  content = null,
}: NotificationComponentProps & {
  ref?: React.Ref<unknown>;
}) {
  const breakpoint = useWidth();
  const [description, setDescription] = useState(notification.description || '');
  const icon = variants[notification.severity || ''];

  const { closeSnackbar } = useSnackbar();
  const onClickDismiss = () => closeSnackbar(key);

  useEffect(() => {
    toClickableSpan(notification.description || '', 'en').then((res) => {
      setDescription(res);
    });
  }, [notification.description]);

  const onGoNotification = (e: any) => {
    e.stopPropagation();
    closeSnackbar(key);

    // 已确认 viewAllUrl都是本地的相对地址
    if (!e?.customPreventRedirect) {
      window.open(viewAllUrl, '_blank');
    }
  };

  const includeActivity = useCreation(() => {
    return isIncludeActivity(notification);
  }, [notification]);
  const activity = useCreation(() => {
    return notification?.activity;
  }, [notification]);

  const activityMeta = useCreation(() => {
    if (!activity || activity.type === 'tips') {
      return null;
    }

    return activity?.meta;
  }, [activity]);

  const activityTitle = useActivityTitle({
    activity,
    users: [notification?.actorInfo],
    actors: [notification?.activity?.actor],
    extra: {
      linkColor: common.white,
    },
  });

  return (
    <StyledSnackbarContent
      ref={ref as React.Ref<HTMLDivElement>}
      severity={notification.severity}
      breakpoint={breakpoint}>
      <MessageDiv>
        {icon ? <Icon icon={icon} fontSize={24} /> : null}
        <ClickableDiv onClick={onGoNotification} style={{ width: 'calc(100% - 30px)' }}>
          <Box>
            {includeActivity ? (
              <>
                <span className="title">{activityTitle}</span>
                {activityMeta ? (
                  <Typography
                    variant="subtitle2"
                    component="p"
                    sx={{
                      fontSize: 16,
                      display: '-webkit-box',
                      overflow: 'hidden',
                      textOverflow: 'ellipsis',
                      WebkitLineClamp: 3,
                      WebkitBoxOrient: 'vertical',
                      color: common.white,
                      lineHeight: 1.2,
                    }}>
                    {activityMeta?.content}
                  </Typography>
                ) : null}
              </>
            ) : (
              <>
                <span className="title">{notification.title}</span>
                {content || (
                  <Typography
                    component="span"
                    className="desc"
                    dangerouslySetInnerHTML={{ __html: sanitize(description) }}
                  />
                )}
              </>
            )}
          </Box>
        </ClickableDiv>
      </MessageDiv>
      <ActionDiv>
        <IconButton key="close" aria-label="close" color="inherit" onClick={onClickDismiss} size="large">
          <CloseIconStyled />
        </IconButton>
      </ActionDiv>
    </StyledSnackbarContent>
  );
}
