import { DeleteOutlined, EyeOutlined, PlusOutlined } from '@ant-design/icons';
import { Upload, Modal, notification } from 'antd';
import React from 'react';
import { ReactSortable } from 'react-sortablejs';
import lodash from 'lodash';
import { uploadImg } from '../../GoodsManage/service';
import styles from './styles.less';

const DETAIL_IMG_MAX_WIDTH = 800;
const LOOP_IMG_WIDTH_HEIGHT = 1200;

const cleanArray = actual => {
  const newArray = [];
  // eslint-disable-next-line no-plusplus
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
};

const warningTip = description => {
  notification.warning({
    // duration: null,
    message: '图片上传失败',
    description,
  });
};

const getBase64 = (img, callback) => {
  const reader = new FileReader();
  reader.addEventListener('load', () => callback(reader.result));
  reader.readAsDataURL(img);
};
const ImageInfo = file =>
  new Promise((resolve, reject) => {
    const LtMB = file.size / 1024 / 1024;
    if (LtMB > 2) {
      warningTip(`[${file.name}] 图片不可以大于2MB`);
      resolve(null);
    }
    getBase64(file, url => {
      const image = new Image();
      image.addEventListener('load', () => {
        const { width } = image;
        const { height } = image;
        file.width = width;
        file.height = height;
        file.LtMB = LtMB;
        resolve(file);
      });
      image.addEventListener('error', () => {
        warningTip(`${file.name}图片上传失败！`);
        resolve(null);
      });
      image.src = url;
    });
  });

const CheckImageInfoList = async files => {
  const promiseImage = files.map(file => ImageInfo(file));
  const clearImage = await Promise.all(promiseImage);
  return cleanArray(clearImage);
};

const isUploadNext = async (imgFileList, id) => {
  const filterImage = imgFileList.filter(({ width, height, name }) => {
    if (id === 'detailImageList') {
      if (width > DETAIL_IMG_MAX_WIDTH) {
        warningTip(`[${name}] 详情图宽度不可大于${DETAIL_IMG_MAX_WIDTH}`);
        return false;
      }
      return true;
    }
    if (width > LOOP_IMG_WIDTH_HEIGHT || height > LOOP_IMG_WIDTH_HEIGHT) {
      warningTip(`[${name}] 滑动图尺寸不可大于 ${LOOP_IMG_WIDTH_HEIGHT}*${LOOP_IMG_WIDTH_HEIGHT}`);
      return false;
    }
    return true;
  });
  return filterImage;
};
class PicturesWall extends React.Component {
  state = {
    previewVisible: false,
    previewImage: '',
    fileList: [],
    newFile: [],
    activeImgIndex: null,
  };

  async componentDidMount() {
    this.initFileList(this.props.fileList || []);
  }

  componentWillReceiveProps(nextProps) {
    this.initFileList(nextProps.fileList || []);
  }

  initFileList = fileList => {
    const fileLists =
      fileList.map((item, index) => ({
        url: item,
        name: index,
        uid: index,
        status: 'done',
      })) || [];
    this.setState({ fileList: fileLists });
  };

  handleCancel = () => this.setState({ previewVisible: false });

  handlePreview = async img => {
    this.setState({
      previewImage: img.url,
      previewVisible: true,
    });
  };

  clearFileList = () => {
    this.setState({
      fileList: [],
    });
  };

  sortChange = list => {
    this.setState({ fileList: list });
    const urlList = list.map(item => item.url);
    this.props.onChange(urlList);
  };

  onRemoveImg = file => {
    this.setState(
      state => {
        const index = state.fileList.indexOf(file);
        const newFileList = state.fileList.slice();
        newFileList.splice(index, 1);
        return {
          fileList: newFileList,
        };
      },
      () => {
        const urlList = this.state.fileList.map(item => item.url);
        this.props.onChange(urlList);
      },
    );
  };

  render() {
    // TODO 图片限制大小
    const { previewVisible, previewImage, fileList } = this.state;
    const uploadButton = (
      <div>
        <PlusOutlined />
        <div className="ant-upload-text">上传图片</div>
      </div>
    );
    const { max, isDisabled } = this.props;
    const that = this;
    const uploadProps = {
      accept: '.jpg,.png,.jpeg',
      beforeUpload: lodash.debounce(async (file, files) => {
        const optionsArray = await CheckImageInfoList(files);
        const onRightImgList = await isUploadNext(optionsArray, that.props.id);
        if (!onRightImgList.length) {
          return;
        }
        this.setState(
          state => ({
            newFile: [...state.newFile, ...onRightImgList],
          }),
          async () => {
            const data = await uploadImg(that.state.newFile);
            this.setState({ newFile: [] });
            if (!data || !data.data) return;
            const { length } = this.state.fileList;
            const list = data.data.map((img, index) => ({
              url: img,
              uid: index + length,
              name: index + length,
              status: 'done',
            }));
            this.setState(
              state => ({ fileList: [...state.fileList, ...list] }),
              () => {
                const urlList = this.state.fileList.map(item => item.url);
                this.props.onChange(urlList);
              },
            );
          },
        );
        // eslint-disable-next-line consistent-return
        return false;
      }, 500),
      listType: 'picture-card',
    };
    return (
      <div className={styles.clearfix}>
        <div className={styles.imgContent}>
          {fileList.length > 0 && (
            <ReactSortable list={fileList} setList={list => this.sortChange(list)}>
              {fileList.map((item, index) => (
                <div
                  // eslint-disable-next-line react/no-array-index-key
                  key={index}
                  className={styles.sortImg}
                  onMouseEnter={() => this.setState({ activeImgIndex: index })}
                  onMouseLeave={() => this.setState({ activeImgIndex: null })}
                >
                  <div style={{ width: '100%', height: '100%', overflow: 'hidden' }}>
                    <img width="100%" key={item.uid} src={item.url} alt="" />
                  </div>
                  {this.state.activeImgIndex === index && (
                    <div className={styles.mask}>
                      <EyeOutlined
                        className={styles.maskIcon}
                        onClick={() => this.handlePreview(item)}
                      />
                      <DeleteOutlined
                        className={styles.maskIcon}
                        onClick={() => this.onRemoveImg(item)}
                      />
                    </div>
                  )}
                </div>
              ))}
            </ReactSortable>
          )}
        </div>
        <Upload
          multiple
          {...uploadProps}
          fileList={fileList}
          showUploadList={false}
          disabled={isDisabled}
        >
          {max && fileList.length >= max ? null : uploadButton}
        </Upload>
        <Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
          <img alt="example" style={{ width: '100%' }} src={previewImage} />
        </Modal>
      </div>
    );
  }
}
export default PicturesWall;
