/**
 * @file 照片上传弹窗组件
 * @author luozhengxuan <51071534@qq.com>
 * */
import React, { useCallback, useMemo, useState } from 'react';
import Axios from 'axios';
import { FormOutlined, DeleteOutlined } from '@ant-design/icons';
import { message, Modal, Upload } from 'antd';
import { RcFile } from 'antd/es/upload';
import 'antd/es/modal/style/index';
import { compressImage } from '@jy-fe/utils';
import modalOpen from '../common/modal-open';
import PNGPhotoUpload from '../assets/photo-upload.png';
import PNGPhotoCase1 from '../assets/photo-case-1.png';
import PNGPhotoCase2 from '../assets/photo-case-2.png';
import PNGPhotoCase3 from '../assets/photo-case-3.png';
import PNGShowcaseSuccess from '../assets/showcase-success.png';
import PNGShowcaseFail from '../assets/showcase-fail.png';

import { OpenConfig, XuiModalPhotoProps } from './xui-modal-photo.d';

interface FileData {
  url: string;
  list: RcFile[];
}

export const XuiModalPhoto: React.FC<XuiModalPhotoProps> & {
  open: (c: OpenConfig) => Record<never, unknown>;
} = ({ uploadURL, uploadExtraConf = {}, success, fail, ...props }) => {
  const classname = 'xui-ant__modal-photo';
  const imgSize = 3;
  const accept = useMemo(
    () => ({
      type: ['jpg', 'png', 'jpeg'],
      mime: ['image/jpeg', 'image/png'],
    }),
    [],
  );
  const [fileList, setFileList] = useState<FileData>({ url: '', list: [] });
  const [loading, setLoading] = useState(false);

  const internalBeforeUpload = file => {
    if (!accept.mime.includes(file.type)) {
      message.error(`只支持${accept.type.join('、')}格式`);
      return false;
    }

    if (file.size / 1024 / 1024 > imgSize) {
      message.error(`图片大于${imgSize}M`);
      return false;
    }

    setFileList({
      url: URL.createObjectURL(file),
      list: [file],
    });

    return false;
  };

  const handleDelete = useCallback(() => {
    setFileList({ url: '', list: [] });
  }, []);

  // eslint-disable-next-line consistent-return
  const fetchCreate = async (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
    try {
      if (!fileList.list.length) {
        return message.warn('请上传生活照');
      }

      const { data: extraData, ...otherExtraConf } = uploadExtraConf;
      const formData = new FormData();
      if (extraData instanceof Object) {
        Object.entries(extraData).forEach(entry => {
          formData.append(entry[0], entry[1]);
        });
      }
      const maxSize = 2000000;
      let compressFilePhoto;
      if (fileList.list[0].size > maxSize) {
        compressFilePhoto = await compressImage(fileList.url, 0.5);
      }
      const file = compressFilePhoto || fileList.list[0];
      formData.append('file', file);

      setLoading(true);
      const { data } = await Axios({
        url: uploadURL,
        method: 'POST',
        data: formData,
        ...(otherExtraConf || {}),
      });
      // 这里如果使用 return Promise.reject 会进入到 axios 的捕获里
      // TODO: 待优化
      if (data.status) throw data;
      message.success('上传成功');
      if (props.onCancel) {
        props.onCancel(e);
      }
      if (success) success(data.data);
      return data;
    } catch (err) {
      if (err.msg) {
        message.warn(err.msg);
      } else {
        message.error('网络异常');
      }
      if (fail) fail(err);
    } finally {
      setLoading(false);
      handleDelete();
    }
  };

  return (
    <Modal
      title='上传生活照'
      {...props}
      width={560}
      maskClosable={false}
      onOk={fetchCreate}
      confirmLoading={loading}
      okText='保存'
      cancelText='取消'
    >
      <div className={`${classname}--showcase-wrap`}>
        <div className={`${classname}--showcase-item`}>
          {fileList.list.length ? (
            [
              <img key={1} className={`${classname}--showcase-img`} src={fileList.url} alt='' />,
              <div key={2} className={`${classname}--showcase-mask`}>
                <Upload
                  beforeUpload={internalBeforeUpload}
                  fileList={fileList.list}
                  accept={accept.mime.join(',')}
                >
                  <FormOutlined className={`${classname}--showcase-icon`} />
                </Upload>
                &nbsp;&nbsp;
                <DeleteOutlined className={`${classname}--showcase-icon`} onClick={handleDelete} />
              </div>,
            ]
          ) : (
            <Upload
              beforeUpload={internalBeforeUpload}
              fileList={fileList.list}
              accept={accept.mime.join(',')}
            >
              <img className={`${classname}--showcase-img`} src={PNGPhotoUpload} alt='' />
            </Upload>
          )}
        </div>
      </div>

      <div className={`${classname}--rules-wrap`}>
        <div className={`${classname}--rules-title`}>拍摄要求</div>
        <div className={`${classname}--rules-detail`}>
          照片高清、完整，{imgSize}M以内的jpg/png/jpeg格式
        </div>

        <div className={`${classname}--cases-wrap`}>
          <div className={`${classname}--cases-item`}>
            <img className={`${classname}--cases-img`} src={PNGPhotoCase1} alt='' />
            <div className={`${classname}--cases-text`}>
              <img src={PNGShowcaseSuccess} alt='' />
              标准拍摄
            </div>
          </div>
          <div className={`${classname}--cases-item`}>
            <img className={`${classname}--cases-img`} src={PNGPhotoCase3} alt='' />
            <div className={`${classname}--cases-text`}>
              <img src={PNGShowcaseFail} alt='' />
              照片模糊
            </div>
          </div>
          <div className={`${classname}--cases-item`}>
            <img className={`${classname}--cases-img`} src={PNGPhotoCase2} alt='' />
            <div className={`${classname}--cases-text`}>
              <img src={PNGShowcaseFail} alt='' />
              成像错误
            </div>
          </div>
        </div>
      </div>
    </Modal>
  );
};

XuiModalPhoto.open = (config: OpenConfig) => modalOpen(config, XuiModalPhoto);

export default XuiModalPhoto;
