import * as React from 'react';
import classnames from 'classnames';
import jsbarcode from 'jsbarcode';
import { expandObj } from 'src/types';
import OPButton from '../op-button';
import OPTag from '../op-tag';
import event from '../event';
import './index.scss';

type fitEnum = 'contain-in' | 'contain-out' | 'width' | 'height';
type backgroundColorEnum = 'primary' | 'pm' | 'protection';
type iconTypeMap = 'check-circle' | 'warning' | 'cancel';

interface CardProps {
  /** 自定义样式类 */
  className?: string;
  /** 卡片最大高 */
  maxHeight?: boolean | string;
  /** 卡片标题 */
  title?: string | React.ReactNode;
  /** 卡片内容 */
  content?: string | Array<string | number> | React.ReactNode;
  /** 卡片背景颜色 */
  backgroundColor?: backgroundColorEnum | string;
  /** 图片列表 */
  imgList?: Array<ImageProps>;
  /** 条码 */
  barcode?: BarcodeProps;
  /** 操作配置 */
  action?: ActionProps;
  /** 卡片状态 */
  status?: string;
  /** 卡片tag */
  tag?: expandObj;
  /** 提示-类型 */
  infoType?: iconTypeMap;
  /** 提示-标题 */
  infoTitle?: string;
  /** 提示-标签 */
  infoTags?: Array<string>;
  /** 提示-内容 */
  infoMessage?: string;
  /** 标题自定义内联样式 */
  titleStyle?: React.CSSProperties;
  /** 内容自定义内联样式 */
  contentStyle?: React.CSSProperties;
}

interface ImageProps {
  url: string;
  fit?: fitEnum;
}

interface BarcodeProps {
  id: string;
  value: string;
  [propsName: string]: string | number | boolean;
}

interface ActionProps {
  name: string;
  hotkey?: string;
  onAction?: () => void;
}

const Card: React.FC<CardProps> = ({
  className = '',
  maxHeight = '',
  title = '',
  content = '',
  backgroundColor = '',
  imgList = [],
  action = {},
  barcode = {},
  status = '',
  tag = {},
  infoType = 'warning',
  infoTitle = '',
  infoTags = [],
  infoMessage = '',
  titleStyle = {},
  contentStyle = {},
}) => {
  const defaultBarcodeId = `barcode-${Math.random().toString().slice(-10)}`;
  const { name: actionName, hotkey, onAction } = action as ActionProps;
  const {
    id: barcodeId = defaultBarcodeId,
    value: barcodeValue,
    ...barcodeRest
  } = barcode as BarcodeProps;

  // 卡片状态 enable
  const enable = React.useMemo(() => {
    return title || content || imgList?.length || barcodeValue;
  }, [title, content, imgList, barcodeValue]);

  const cardStyle = React.useMemo(() => {
    const newCardStyle = {
      backgroundColor: '',
      maxHeight: '',
    };
    // 卡片背景色
    if (backgroundColor) {
      let bgColor = '';
      switch (backgroundColor) {
        case 'primary': // 重点信息 - 黄色
          bgColor = '#FFD119';
          break;
        case 'pm': // 包材信息 - 淡蓝色
          bgColor = '#D7EAFC';
          break;
        case 'protection': // 防护信息 - 淡绿色
          bgColor = '#DAF2DE';
          break;
        default:
          bgColor = backgroundColor;
          break;
      }
      newCardStyle.backgroundColor = bgColor;
    }
    // 卡片最大高
    if (typeof maxHeight === 'string' && maxHeight) {
      newCardStyle.maxHeight = maxHeight;
    }

    return newCardStyle;
  }, [backgroundColor, maxHeight]);

  React.useEffect(() => {
    // 条形码初始化
    if (barcodeValue) {
      document.getElementById(barcodeId) &&
        jsbarcode(`#${barcodeId}`, barcodeValue, {
          ...barcodeRest,
        });
    }
  }, [barcodeId, barcodeValue, barcodeRest]);

  React.useEffect(() => {
    hotkey && onAction && event.bind(hotkey, onAction);
    return () => {
      hotkey && onAction && event.unbind(hotkey, onAction);
    };
  }, [hotkey, onAction]);

  return enable ? (
    <div
      className={classnames(
        'op-card',
        status && `op-card-${status}`,
        {
          'op-card-image': imgList.length || barcodeValue,
          'op-card-max-height': maxHeight,
        },
        className,
      )}
      style={cardStyle}
    >
      {title ? (
        <div className='op-card-title' style={titleStyle}>
          {title}
          {tag?.children ? <OPTag {...tag}>{tag.children}</OPTag> : ''}
        </div>
      ) : null}
      {content ? (
        <div
          className={classnames('op-card-content', {
            'op-card-scroll': maxHeight,
          })}
          style={contentStyle}
        >
          {Array.isArray(content)
            ? content.map((item) => <div>{item}</div>)
            : content}
        </div>
      ) : null}
      {imgList?.length ? (
        <div className='op-card-image-content'>
          {imgList.map((item) => {
            const { url = '', fit = 'contain-out' } = item;
            return (
              <div className={classnames('image-item', `fit-${fit}`)}>
                <img alt='' src={url} />
              </div>
            );
          })}
        </div>
      ) : null}
      {barcodeValue ? (
        <div className='op-card-barcode-content'>
          <svg id={barcodeId} />
        </div>
      ) : null}
      {infoTitle && (
        <div className={`op-card-info op-card-info-${infoType}`}>
          <div className='op-card-info-title'>
            <span>{infoTitle}</span>
          </div>
          <div className='op-card-info-tags'>
            {infoTags.map((infoTag) => (
              <div className='op-card-info-tag'>{infoTag}</div>
            ))}
          </div>
          <div className='op-card-info-message'>{infoMessage}</div>
        </div>
      )}
      {actionName ? (
        <OPButton
          data-hottag='cn-op.card-action'
          className='op-card-action'
          type='text'
          hotkey={hotkey}
          onClick={onAction}
        >
          {actionName}
        </OPButton>
      ) : null}
    </div>
  ) : null;
};

export default Card;
