import { OpenInNewRounded } from '@mui/icons-material';
import {
  Avatar,
  Box,
  Link,
  ListItemAvatar,
  ListItemText,
  Skeleton,
  Slide,
  Typography,
  styled,
} from '@mui/material';
import type { MouseEventHandler } from 'react';
import { useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { formatUnits } from 'viem';
import { useExplorer } from '../../hooks/useExplorer.js';
import { formatTokenAmount, formatTokenPrice } from '../../utils/format.js';
import { shortenAddress } from '../../utils/wallet.js';
import { ListItemButton } from '../ListItem/ListItemButton.js';
import { IconButton, ListItem } from './TokenList.style.js';
import type { TokenListItemButtonProps, TokenListItemProps } from './types.js';

export const TokenListItem: React.FC<TokenListItemProps> = ({
  onClick,
  size,
  start,
  token,
  chain,
  showBalance,
  isBalanceLoading,
  startAdornment,
  endAdornment,
}) => {
  const handleClick: MouseEventHandler<HTMLDivElement> = (e) => {
    e.stopPropagation();
    onClick?.(token.address);
  };
  return (
    <ListItem
      style={{
        height: `${size}px`,
        transform: `translateY(${start}px)`,
      }}
    >
      {startAdornment}
      <TokenListItemButton
        token={token}
        chain={chain}
        showBalance={showBalance}
        isBalanceLoading={isBalanceLoading}
        onClick={handleClick}
      />
      {endAdornment}
    </ListItem>
  );
};

export const TokenListItemButton: React.FC<TokenListItemButtonProps> = ({
  onClick,
  token,
  chain,
  showBalance,
  isBalanceLoading,
}) => {
  const { t } = useTranslation();
  const { getAddressLink } = useExplorer();

  const tokenPrice = token.amount
    ? formatTokenPrice(
        formatUnits(token.amount, token.decimals),
        token.priceUSD,
      )
    : undefined;
  const container = useRef(null);
  const timeoutId = useRef<ReturnType<typeof setTimeout>>();
  const [showAddress, setShowAddress] = useState(false);

  const onMouseEnter = () => {
    timeoutId.current = setTimeout(() => setShowAddress(true), 350);
  };

  const onMouseLeave = () => {
    clearTimeout(timeoutId.current);
    if (showAddress) {
      setShowAddress(false);
    }
  };

  const VerifiedIcon = styled(Box)(({ theme }) => {
    return {
      background: theme.palette.mode === 'light' ? '#fff' : '#121212',
      width: '20px',
      height: '20px',
      borderRadius: '100%',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
    };
  });

  return (
    <ListItemButton
      onClick={onClick}
      onMouseEnter={onMouseEnter}
      onMouseLeave={onMouseLeave}
      dense
    >
      <ListItemAvatar style={{ position: 'relative' }}>
        {token?.isVerified ? (
          <div
            style={{
              position: 'absolute',
              bottom: '-4px',
              right: '12px',
              zIndex: 1,
            }}
          >
            <VerifiedIcon>
              <svg
                width="20"
                height="20"
                viewBox="0 0 22 22"
                fill="#1890ff"
                xmlns="http://www.w3.org/2000/svg"
              >
                <g id="CircleWavyCheck">
                  <path
                    id="Vector"
                    d="M4.68023 17.3198C3.88926 16.5288 4.41388 14.8682 4.01128 13.8952C3.59394 12.8865 2.0625 12.0746 2.0625 11C2.0625 9.92531 3.59395 9.1135 4.01129 8.10483C4.41389 7.1318 3.88927 5.4712 4.68023 4.68023C5.4712 3.88926 7.13181 4.41388 8.10484 4.01128C9.11353 3.59394 9.92536 2.0625 11 2.0625C12.0747 2.0625 12.8865 3.59395 13.8952 4.01129C14.8682 4.41389 16.5288 3.88927 17.3198 4.68023C18.1107 5.4712 17.5861 7.13181 17.9887 8.10484C18.4061 9.11353 19.9375 9.92536 19.9375 11C19.9375 12.0747 18.4061 12.8865 17.9887 13.8952C17.5861 14.8682 18.1107 16.5288 17.3198 17.3198C16.5288 18.1107 14.8682 17.5861 13.8952 17.9887C12.8865 18.4061 12.0746 19.9375 11 19.9375C9.92531 19.9375 9.1135 18.4061 8.10483 17.9887C7.1318 17.5861 5.4712 18.1107 4.68023 17.3198Z"
                    fill="#1890ff"
                    stroke="#1890ff"
                    strokeWidth="1.5"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  ></path>
                  <path
                    id="Vector_2"
                    d="M14.7812 8.9375L9.73955 13.75L7.21875 11.3438"
                    stroke="#fff"
                    strokeWidth="1.5"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  ></path>
                </g>
              </svg>
            </VerifiedIcon>
          </div>
        ) : null}
        <Avatar src={token.logoURI} alt={token.symbol}>
          {token.symbol?.[0]}
        </Avatar>
      </ListItemAvatar>

      <ListItemText
        primary={token.symbol}
        secondaryTypographyProps={{
          component: 'div',
        }}
        secondary={
          <Box position="relative" height={20} ref={container}>
            <Slide
              direction="down"
              in={!showAddress}
              container={container.current}
              style={{
                position: 'absolute',
              }}
              appear={false}
            >
              <Box pt={0.25}>{token.name}</Box>
            </Slide>
            <Slide
              direction="up"
              in={showAddress}
              container={container.current}
              style={{
                position: 'absolute',
              }}
              appear={false}
              mountOnEnter
            >
              <Box display="flex">
                <Box display="flex" alignItems="center" pt={0.125}>
                  {shortenAddress(token.address)}
                </Box>
                <IconButton
                  size="small"
                  LinkComponent={Link}
                  href={getAddressLink(token.address, chain)}
                  target="_blank"
                  rel="nofollow noreferrer"
                  onClick={(e) => e.stopPropagation()}
                >
                  <OpenInNewRounded />
                </IconButton>
              </Box>
            </Slide>
          </Box>
        }
      />
      {showBalance ? (
        isBalanceLoading ? (
          <TokenAmountSkeleton />
        ) : (
          <Box sx={{ textAlign: 'right' }}>
            {token.amount ? (
              <Typography fontWeight={600} noWrap>
                {t('format.number', {
                  value: formatTokenAmount(token.amount, token.decimals),
                })}
              </Typography>
            ) : null}
            {tokenPrice ? (
              <Typography
                fontWeight={500}
                fontSize={12}
                color="text.secondary"
                data-price={token.priceUSD}
              >
                {t(`format.currency`, {
                  value: tokenPrice,
                })}
              </Typography>
            ) : null}
          </Box>
        )
      ) : null}
    </ListItemButton>
  );
};

export const TokenListItemSkeleton = () => {
  return (
    <ListItem
      secondaryAction={<TokenAmountSkeleton />}
      disablePadding
      sx={{ position: 'relative', flexDirection: 'row', alignItems: 'center' }}
    >
      <ListItemAvatar>
        <Skeleton
          variant="circular"
          width={40}
          height={40}
          sx={{ marginLeft: 1.5, marginRight: 2 }}
        />
      </ListItemAvatar>
      <ListItemText
        primary={<Skeleton variant="text" width={56} height={24} />}
        secondary={<Skeleton variant="text" width={96} height={16} />}
      />
    </ListItem>
  );
};

export const TokenAmountSkeleton: React.FC = () => {
  return (
    <Box
      sx={{
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'flex-end',
      }}
    >
      <Skeleton variant="text" width={56} height={24} />
      <Skeleton variant="text" width={48} height={16} />
    </Box>
  );
};
