/* eslint-disable react/no-danger */
import { isValidElement } from 'react';
import PropTypes from 'prop-types';
import { CircularProgress, Typography, useMediaQuery } from '@mui/material';

import Avatar from '../Avatar';
import Button from '../Button';
import Img from '../Img';
import { useTheme, styled } from '../Theme';
import { strippedString } from './utils';

const Div = styled('div')`
  &.arcblock-blocklet {
    padding: ${(props) => props.theme.spacing(2)} ${(props) => props.theme.spacing(2)} 0
      ${(props) => props.theme.spacing(2)};
  }
  .arcblock-blocklet__content {
    cursor: pointer;
    display: flex;
    ${(props) => props.theme.breakpoints.up('sm')} {
      align-items: center;
    }
  }
  .arcblock-blocklet__cover {
    width: 64px;
    height: 64px;
    margin-right: ${(props) => props.theme.spacing(2)};
    overflow: hidden;
    border-radius: 12px;
    /* see: https://stackoverflow.com/questions/49066011/overflow-hidden-with-border-radius-not-working-on-safari */
    transform: translateZ(0);
    ${(props) => props.theme.breakpoints.up('sm')} {
      width: 80px;
      height: 80px;
      margin-bottom: 12px;
    }
  }
  .arcblock-blocklet__button--hover {
    &:not(.Mui-disabled) {
      position: relative;
      z-index: 1;
      &::before {
        content: '';
        position: absolute;
        height: 100%;
        width: 100%;
        left: 0;
        top: 0;
        transition: opacity 0.3s;
      }
      &:hover::before {
        opacity: 0;
      }
      &::after {
        content: '';
        position: absolute;
        height: 100%;
        width: 100%;
        background-color: ${(props) => props.theme.palette.primary.main};
        transform: scale(0.1);
        opacity: 0;
        z-index: -1;
        transition:
          transform 0.3s,
          opacity 0.3s,
          background-color 0.3s;
      }
      &:hover::after {
        opacity: 1;
        transform-origin: center;
        transform: scale(1);
      }
    }

    &:not(.Mui-disabled) {
      background-color: transparent !important;
      color: ${(props) => props.theme.palette.primary.main};
    }
    &:not(.Mui-disabled) {
      &:hover {
        color: ${(props) => props.theme.palette.common.white};
      }
    }
  }
  .arcblock-blocklet__info {
    flex: 1;
    overflow: hidden;
    border-bottom: 1px solid ${(props) => props.theme.palette.divider};
    padding-bottom: ${(props) => props.theme.spacing(2)};
  }
  .arcblock-blocklet__text {
    height: 65px;
    overflow: hidden;
  }
  /* 设置多行文本溢出显示省略号 兼容fireFox、safari */
  .arcblock-blocklet__title {
    margin: 0;
    font-size: 16px;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .arcblock-blocklet__describe {
    margin-top: ${(props) => props.theme.spacing(0.5)};
    color: ${(props) => props.theme.palette.grey[600]};
    font-size: 14px;
    font-weight: 500;
    line-height: 17px;
    max-height: 34px;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    word-break: break-word;
  }
  .arcblock-blocklet__version {
    color: ${(props) => props.theme.palette.grey[600]};
    font-size: 12px;
  }
`;

/**
 * BlockletStore component
 * @typedef {{
 *  title?: string | JSX.Element;
 *  did?: string;
 *  description?: string | JSX.Element;
 *  cover?: string;
 *  version?: string;
 *  buttonText?: string;
 *  buttonDisabled?: false | true;
 *  buttonLoading?: false | true;
 *  button?: JSX.Element;
 *  onButtonClick?: Function;
 *  onMainClick?: Function;
 *  className?: string;
 * } & import('react').ComponentPropsWithoutRef<"div"> } BlockletStoreProps
 */

/**
 * BlockletStore component
 * @param {BlockletStoreProps} props
 * @returns {JSX.Element}
 */
export default function BlockletStore({
  title = '',
  did = null,
  description = '',
  cover = null,
  version = null,
  button = null,
  buttonText = 'Install',
  buttonDisabled = false,
  buttonLoading = false,
  onButtonClick = null,
  onMainClick = null,
  className = null,
  ...rest
}) {
  const wrapHandler =
    (handler, stopFn = () => false) =>
    (e, ...args) => {
      if (stopFn()) {
        e.preventDefault();
        e.stopPropagation();
      } else if (handler instanceof Function) {
        e.preventDefault();
        e.stopPropagation();
        handler(...args);
      }
    };
  const _onButtonClick = wrapHandler(onButtonClick, () => {
    // stop click while custom button or buttonDisabled or buttondLoading
    if (button || buttonDisabled || buttonLoading) {
      return true;
    }
    return false;
  });
  const theme = useTheme();
  const isUpSm = useMediaQuery(theme.breakpoints.up('sm'));
  const _onMainClick = wrapHandler(onMainClick);
  const didAvatarSize = isUpSm ? 80 : 64;
  return (
    <Div className={`${className} arcblock-blocklet`} {...rest}>
      <div className="arcblock-blocklet__content" onClick={_onMainClick}>
        {cover ? (
          <div className="arcblock-blocklet__cover">
            <Img src={cover} />
          </div>
        ) : (
          did && (
            <div className="arcblock-blocklet__cover">
              <Avatar did={did} size={didAvatarSize} />
            </div>
          )
        )}
        <div className="arcblock-blocklet__info">
          <div className="arcblock-blocklet__text">
            {isValidElement(title) ? (
              <Typography component="h3" variant="h3" className="arcblock-blocklet__title">
                {title}
              </Typography>
            ) : (
              <Typography
                component="h3"
                variant="h3"
                className="arcblock-blocklet__title"
                title={strippedString(title)}
                dangerouslySetInnerHTML={{ __html: title }}
              />
            )}

            {isValidElement(description) ? (
              <Typography component="div" variant="body2" className="arcblock-blocklet__describe">
                {description}
              </Typography>
            ) : (
              <Typography
                component="div"
                variant="body2"
                className="arcblock-blocklet__describe"
                title={strippedString(description)}
                dangerouslySetInnerHTML={{ __html: description }}
              />
            )}
          </div>
          <div
            style={{
              display: 'flex',
              alignItems: 'center',
              marginTop: '10px',
              flexFlow: 'wrap',
            }}>
            <div onClick={_onButtonClick} style={{ marginRight: '12px' }}>
              {button ||
                (onButtonClick && (
                  <Button
                    className="arcblock-blocklet__button--hover"
                    variant="outlined"
                    color="primary"
                    size="small"
                    disabled={buttonDisabled || buttonLoading}
                    style={{
                      padding: '3px 6px',
                      fontSize: '14px',
                      minWidth: '92px',
                      textAlign: 'center',
                    }}>
                    {buttonLoading && <CircularProgress size={15} style={{ marginRight: 3, color: 'inherit' }} />}
                    {buttonText}
                  </Button>
                ))}
            </div>
            <div className="arcblock-blocklet__version">{version && `v${version}`}</div>
          </div>
        </div>
      </div>
    </Div>
  );
}
BlockletStore.propTypes = {
  title: PropTypes.string || PropTypes.node,
  did: PropTypes.string,
  description: PropTypes.string || PropTypes.node,
  cover: PropTypes.string,
  buttonText: PropTypes.string,
  buttonDisabled: PropTypes.bool,
  buttonLoading: PropTypes.bool,
  button: PropTypes.element,
  version: PropTypes.string,
  onButtonClick: PropTypes.func,
  onMainClick: PropTypes.func,
  className: PropTypes.string,
};
