/**
 * @file 身份证上传弹窗组件
 * @author luozhengxuan <51071534@qq.com>
 * */
import React, { useState, useMemo, useCallback } from 'react';
import Axios from 'axios';
import { FormOutlined, DeleteOutlined } from '@ant-design/icons';
import message from 'antd/es/message';
import 'antd/es/message/style/index';
import Modal from 'antd/es/modal';
import 'antd/es/modal/style/index';
import Upload, { RcFile } from 'antd/es/upload';
import 'antd/es/upload/style/index';
import { compressImage } from '@jy-fe/utils';
import modalOpen from '../common/modal-open';
import PNGIdcardPortrait from '../assets/idcard-2.png';
import PNGIdcardEmblem from '../assets/idcard-1.png';
import PNGIdcardCase1 from '../assets/idcard-case-1.png';
import PNGIdcardCase2 from '../assets/idcard-case-2.png';
import PNGIdcardCase3 from '../assets/idcard-case-3.png';
import PNGIdcardCase4 from '../assets/idcard-case-4.png';
import PNGShowcaseSuccess from '../assets/showcase-success.png';
import PNGShowcaseFail from '../assets/showcase-fail.png';

import { OpenConfig, XuiModalIdcardProps } from './xui-modal-idcard.d';

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

export const XuiModalIdcard: React.FC<XuiModalIdcardProps> & {
  open: (c: OpenConfig) => Record<never, unknown>;
} = ({ name, idcard, uploadURL, uploadExtraConf = {}, success, fail, ...props }) => {
  const classname = 'xui-ant__modal-idcard';
  const imgSize = 5;
  const accept = useMemo(
    () => ({
      type: ['jpg', 'png', 'jpeg'],
      mime: ['image/jpeg', 'image/png'],
    }),
    [],
  );
  const [filePortrait, setFilePortrait] = useState<FileData>({ url: '', list: [] });
  const [fileEmblem, setFileEmblem] = useState<FileData>({ url: '', list: [] });
  const [loading, setLoading] = useState(false);

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

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

    return false;
  };

  const internalBeforeUploadPortrait = file => {
    if (internalVerifyFile(file)) return false;
    setFilePortrait({
      url: URL.createObjectURL(file),
      list: [file],
    });

    return false;
  };
  const internalBeforeUploadEmblem = file => {
    if (internalVerifyFile(file)) return false;
    setFileEmblem({
      url: URL.createObjectURL(file),
      list: [file],
    });

    return false;
  };

  const handleDeletePortrait = useCallback(() => {
    setFilePortrait({ url: '', list: [] });
  }, []);
  const handleDeleteEmblem = useCallback(() => {
    setFileEmblem({ url: '', list: [] });
  }, []);

  // eslint-disable-next-line consistent-return
  const fetchCreateIdcard = async (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
    try {
      if (!filePortrait.list.length) {
        return message.warn('请上传人像面');
      }

      if (!fileEmblem.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 compressFilePortrait;
      let compressFileEmblem;
      if (filePortrait.list[0].size > maxSize) {
        compressFilePortrait = await compressImage(filePortrait.url, 0.5);
      }
      if (fileEmblem.list[0].size > maxSize) {
        compressFileEmblem = await compressImage(fileEmblem.url, 0.5);
      }
      const file1 = compressFilePortrait || filePortrait.list[0];
      const file2 = compressFileEmblem || fileEmblem.list[0];
      formData.append('file1', file1);
      formData.append('file2', file2);

      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('网络异常');
      }
      handleDeletePortrait();
      handleDeleteEmblem();
      if (fail) fail(err);
    } finally {
      setLoading(false);
    }
  };

  return (
    <Modal
      title='上传身份证'
      {...props}
      width={600}
      maskClosable={false}
      onOk={fetchCreateIdcard}
      confirmLoading={loading}
      okText='保存'
      cancelText='取消'
    >
      {name && idcard ? (
        <p>
          请上传 &quot;{name}&quot; 身份证号 &quot;{idcard}&quot; 的身份证正反面
        </p>
      ) : null}

      <div className={`${classname}--showcase-wrap`}>
        <div className={`${classname}--showcase-item`}>
          {filePortrait.list.length ? (
            [
              <img
                key={1}
                className={`${classname}--showcase-img`}
                src={filePortrait.url}
                alt=''
              />,
              <div key={2} className={`${classname}--showcase-mask`}>
                <Upload
                  beforeUpload={internalBeforeUploadPortrait}
                  fileList={filePortrait.list}
                  accept={accept.mime.join(',')}
                >
                  <FormOutlined className={`${classname}--showcase-icon`} />
                </Upload>
                &nbsp;&nbsp;
                <DeleteOutlined
                  className={`${classname}--showcase-icon`}
                  onClick={handleDeletePortrait}
                />
              </div>,
            ]
          ) : (
            <Upload
              beforeUpload={internalBeforeUploadPortrait}
              fileList={filePortrait.list}
              accept={accept.mime.join(',')}
            >
              <img className={`${classname}--showcase-img`} src={PNGIdcardPortrait} alt='' />
            </Upload>
          )}
        </div>
        <div className={`${classname}--showcase-item`}>
          {fileEmblem.list.length ? (
            [
              <img key={1} className={`${classname}--showcase-img`} src={fileEmblem.url} alt='' />,
              <div key={2} className={`${classname}--showcase-mask`}>
                <Upload
                  beforeUpload={internalBeforeUploadEmblem}
                  fileList={fileEmblem.list}
                  accept={accept.mime.join(',')}
                >
                  <FormOutlined className={`${classname}--showcase-icon`} />
                </Upload>
                &nbsp;&nbsp;
                <DeleteOutlined
                  className={`${classname}--showcase-icon`}
                  onClick={handleDeleteEmblem}
                />
              </div>,
            ]
          ) : (
            <Upload
              beforeUpload={internalBeforeUploadEmblem}
              fileList={fileEmblem.list}
              accept={accept.mime.join(',')}
            >
              <img className={`${classname}--showcase-img`} src={PNGIdcardEmblem} 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={PNGIdcardCase1} alt='' />
            <div className={`${classname}--cases-text`}>
              <img src={PNGShowcaseSuccess} alt='' />
              标准拍摄
            </div>
          </div>
          <div className={`${classname}--cases-item`}>
            <img className={`${classname}--cases-img`} src={PNGIdcardCase2} alt='' />
            <div className={`${classname}--cases-text`}>
              <img src={PNGShowcaseFail} alt='' />
              边框缺失
            </div>
          </div>
          <div className={`${classname}--cases-item`}>
            <img className={`${classname}--cases-img`} src={PNGIdcardCase3} alt='' />
            <div className={`${classname}--cases-text`}>
              <img src={PNGShowcaseFail} alt='' />
              照片模糊
            </div>
          </div>
          <div className={`${classname}--cases-item`}>
            <img className={`${classname}--cases-img`} src={PNGIdcardCase4} alt='' />
            <div className={`${classname}--cases-text`}>
              <img src={PNGShowcaseFail} alt='' />
              拍摄倾斜
            </div>
          </div>
        </div>
      </div>
    </Modal>
  );
};

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

export default XuiModalIdcard;
