import React, { isValidElement } from 'react';

import Download from '@iconify-icons/tabler/cloud-download';
import { Icon } from '@iconify/react';
import { Verified as VerifiedIcon } from '@mui/icons-material';
import { Box, Card, CardProps, CircularProgress, Stack, SxProps, Typography } from '@mui/material';
import Avatar from '../Avatar';
import Button from '../Button';
import { useTheme } from '../Theme';
import IconText from './components/icon-text';
import TooltipIcon from './components/tooltip-icon';
import { formatDownloadCount, strippedString } from './utils';

export interface IBlockletStore extends CardProps {
  did?: string;
  title: string;
  description?: string;
  cover?: string;
  avatar?: string;
  author?: string;
  download?: string;
  official?: {
    tooltip: React.ReactNode;
    size?: number;
    color?: string;
  };
  button?: React.ReactNode;
  buttonText?: string;
  buttonDisabled?: boolean;
  buttonLoading?: boolean;
  onButtonClick?: Function;
  onMainClick?: Function;
  className?: string;
  status?: {
    key: string;
    icon: React.ReactNode;
    text: React.ReactNode;
    title?: React.ReactNode;
    maxWidth?: number;
    color?: string;
    align?: 'left' | 'right';
  }[];
  icons?: {
    key: string;
    icon: string | React.ReactElement<any>;
    title: React.ReactNode;
    color?: string;
  }[];
}

export default function BlockletStore({ ...props }: IBlockletStore) {
  const {
    title,
    description = '',
    cover = '',
    avatar,
    author,
    download,
    did,
    official,
    buttonText = 'Install',
    buttonDisabled,
    buttonLoading,
    button,
    onButtonClick = () => {},
    onMainClick,
    className,
    ref,
    icons,
    status,
    ...rest
  } = props;

  const theme = useTheme();

  const wrapHandler =
    (handler: Function, stopFn = () => false) =>
    (e: React.MouseEvent<HTMLElement>, ...args: any[]) => {
      const isFunction = handler instanceof Function;
      if (stopFn() || isFunction) {
        e.preventDefault();
        e.stopPropagation();
        if (isFunction) {
          handler(...args);
        }
      }
    };

  const handleMainClick = onMainClick && wrapHandler(onMainClick);
  const handleButtonClick = wrapHandler(onButtonClick, () => {
    // stop click while custom button or buttonDisabled or buttonLoading
    return !!(button || buttonDisabled || buttonLoading);
  });

  const titleProps: {
    children?: React.ReactNode;
    title?: string;
    dangerouslySetInnerHTML?: { __html: string };
    sx?: SxProps;
  } = isValidElement(title)
    ? { children: title }
    : { title: strippedString(title), dangerouslySetInnerHTML: { __html: title } };

  const descriptionProps: {
    children?: React.ReactNode;
    title?: string;
    dangerouslySetInnerHTML?: { __html: string };
    sx?: SxProps;
  } = isValidElement(description)
    ? { children: description }
    : { title: strippedString(description), dangerouslySetInnerHTML: { __html: description } };

  return (
    <Card
      variant="outlined"
      onClick={handleMainClick}
      {...rest}
      sx={{ p: { xs: 2, md: 3 }, borderRadius: 1, ...rest.sx }}>
      <Stack
        direction="row"
        sx={{
          flex: 1,
          gap: 1,
          alignItems: 'center',
          overflow: 'hidden',
          '& > *': { flexShrink: 0 },
        }}>
        <Avatar src={cover} did={did} size={48} variant="rounded" style={{ borderRadius: '8px', overflow: 'hidden' }} />
        <Typography
          className="blocklet-title"
          {...titleProps}
          sx={[
            {
              fontWeight: 'fontWeightMedium',
              fontSize: 16,
              textOverflow: 'ellipsis',
              whiteSpace: 'nowrap',
              overflow: 'hidden',
              cursor: 'default',
              pl: 0.5,
              '&&': { flexShrink: 1 },
            },
            ...(Array.isArray(titleProps.sx) ? titleProps.sx : [titleProps.sx]),
          ]}
        />
        <Box
          sx={{
            flex: 1,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'flex-start',
            gap: 1,
          }}>
          {official && (
            <TooltipIcon title={official.tooltip}>
              <VerifiedIcon sx={{ color: official.color || '#D97706', fontSize: official.size || 18 }} />
            </TooltipIcon>
          )}
          {icons?.map((item) => (
            <TooltipIcon key={item.key} title={item.title}>
              {typeof item.icon === 'string' ? <Icon icon={item.icon} style={{ color: item.color }} /> : item.icon}
            </TooltipIcon>
          ))}
        </Box>
        {onButtonClick && (
          <Button
            variant="outlined"
            size="small"
            disabled={buttonDisabled || buttonLoading}
            style={{
              color: theme.palette.text.primary,
              borderColor: theme.palette.grey[300],
              borderRadius: 8,
              fontSize: 13,
              fontWeight: theme.typography.fontWeightMedium,
            }}
            onClick={handleButtonClick}>
            {buttonLoading && <CircularProgress size={15} style={{ marginRight: 3, color: 'inherit' }} />}
            {buttonText}
          </Button>
        )}
        {button}
      </Stack>
      <Stack
        sx={{
          py: 2,
        }}>
        <Typography
          className="blocklet-description"
          variant="body2"
          {...descriptionProps}
          sx={[
            {
              color: 'text.secondary',
              display: '-webkit-box',
              lineClamp: 2,
              WebkitLineClamp: 2,
              WebkitBoxOrient: 'vertical',
              overflow: 'hidden',
              cursor: 'default',
              height: 40,
            },
            ...(Array.isArray(descriptionProps.sx) ? descriptionProps.sx : [descriptionProps.sx]),
          ]}
        />
      </Stack>
      <Stack
        direction="row"
        sx={{
          alignItems: 'center',
          gap: 2,
          color: 'text.secondary',
        }}>
        <IconText icon={<Avatar src={avatar} did={did} size={20} variant="circle" />} maxWidth={200}>
          {author}
        </IconText>
        <IconText icon={<Icon icon={Download} />} title={download}>
          {formatDownloadCount(download)}
        </IconText>
        {status
          ?.filter((item) => item.align !== 'right')
          .map((item) => (
            <IconText
              key={item.key}
              icon={typeof item.icon === 'string' ? <Icon icon={item.icon} /> : item.icon}
              title={item.title}
              maxWidth={item.maxWidth}>
              {item.text}
            </IconText>
          ))}
        <Box sx={{ flex: 1 }} />
        {status
          ?.filter((item) => item.align === 'right')
          .map((item) => (
            <IconText
              key={item.key}
              icon={typeof item.icon === 'string' ? <Icon icon={item.icon} /> : item.icon}
              title={item.title}
              maxWidth={item.maxWidth}
              sx={{ color: item.color }}>
              {item.text}
            </IconText>
          ))}
      </Stack>
    </Card>
  );
}
