import { v4 as uuidv4 } from 'uuid';
import { message } from 'antd';
import { RcFile } from 'antd/lib/upload/interface';
import { OSSImgConfig, File } from './interface';
import { UploadButtonProps } from '../uploadButton/interface';

// 检测加密链接是否过期
export const isExpire = (
  url: string,
  ossFile?: string,
  securityType?: string,
) => {
  if (!ossFile || securityType === 'public') return false;
  const nowTime = new Date().valueOf();
  const expireTimeStr = getQuery('Expires', url);
  const expireTime = Number(expireTimeStr || 0) * 1000;
  return !(expireTime > nowTime);
};
// value初始化处理
export const getStringFile = (url: string) => {
  const name = url.split('/').pop() || '';
  return {
    url,
    name,
    originalName: name,
    fileType: getFileType(url),
  };
};

export const getObjFile = (file: File) => {
  const { fileName, fileUrl, originalName, ...other } = file;
  const url = fileUrl || other.url || '';
  const name = fileName || other.name || url.split('/').pop() || '';
  return {
    ...file,
    url,
    name,
    originalName: originalName || name,
    fileType: getFileType(url),
  };
};
// 判断文件类型
export const imgTypeList = ['png', 'jpg', 'jpeg', 'webp', 'gif', 'svg', 'ico'];
export const getFileType = (fileUrl: string): string => {
  const url =
    fileUrl.indexOf('?') > -1
      ? fileUrl.substr(0, fileUrl.indexOf('?'))
      : fileUrl;
  const fileType = (url.split('.').pop() || '').toLocaleLowerCase();
  return imgTypeList.indexOf(fileType) > -1 ? 'image' : fileType;
};
// 获取oss图片配置信息
export const getOssImgConfig = (url?: string, ossImgConfig?: OSSImgConfig) => {
  if (!ossImgConfig || !url) return url || '';
  let config = 'x-oss-process=image';
  if (typeof ossImgConfig === 'string') {
    config = ossImgConfig;
  } else {
    for (let key in ossImgConfig) {
      if (ossImgConfig.hasOwnProperty(key)) {
        const keyArr = key.split('_');
        if (key === 'circle') {
          config = config + '/format,png';
          keyArr.push('r');
        }
        config =
          config +
          `/${keyArr[0]},${keyArr[1] || key.slice(0, 1)}_${ossImgConfig[key]}`;
      }
    }
  }

  return url.indexOf('?') > -1 ? `${url}&${config}` : `${url}?${config}`;
};
// 图片模式下文字省略截取
export const substrName = (name: string) => {
  if (name.length > 15) {
    return `${name.substr(0, 8)}......${name.substr(name.length - 7)}`;
  }
  return name;
};
// 获取过期时间
export const getQuery = (name: string, url: string) => {
  const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i');
  const search =
    url.indexOf('?') > -1 ? url.substr(url.indexOf('?'), url.length) : url;
  const values = search.substr(1).match(reg);
  if (values != null) {
    return unescape(values[2]);
  }
  return null;
};
// 解析xml
export const getXmlNode = (xmlString: string, nodeName: string = '') => {
  let xmlDoc = null;
  //判断浏览器的类型,支持IE浏览器
  if (!window.DOMParser && window.ActiveXObject) {
    //window.DOMParser 判断是否是非ie浏览器
    const xmlDomVersions = [
      'MSXML.2.DOMDocument.6.0',
      'MSXML.2.DOMDocument.3.0',
      'Microsoft.XMLDOM',
    ];
    for (let i = 0; i < xmlDomVersions.length; i++) {
      try {
        xmlDoc = new ActiveXObject(xmlDomVersions[i]);
        xmlDoc.async = false;
        xmlDoc.loadXML(xmlString); //loadXML方法载入xml字符串
        break;
      } catch (e) {}
    }
  }
  //支持Mozilla浏览器
  else if (
    window.DOMParser &&
    document.implementation &&
    document.implementation.createDocument
  ) {
    try {
      /* DOMParser 对象解析 XML 文本并返回一个 XML Document 对象。
       * 要使用 DOMParser，使用不带参数的构造函数来实例化它，然后调用其 parseFromString() 方法
       * parseFromString(text, contentType) 参数text:要解析的 XML 标记 参数contentType文本的内容类型
       * 可能是 "text/xml" 、"application/xml" 或 "application/xhtml+xml" 中的一个。注意，不支持 "text/html"。
       */
      const domParser = new DOMParser();
      xmlDoc = domParser.parseFromString(xmlString, 'text/xml');
    } catch (e) {}
  } else {
    return null;
  }

  if (!nodeName) return xmlDoc;

  const node = xmlDoc.getElementsByTagName(nodeName);

  return node[0] && node[0].firstChild.nodeValue;
};
// 重命名
export const transformFileName = (file: RcFile, dir: string) => {
  const suffix = file.name
    ? file.name.slice(file.name.lastIndexOf('.'))
    : `.${file.type.split('/')[1]}`;
  return dir + uuidv4() + suffix;
};
// 校验文件数量
export const checkMultiple = (
  file: RcFile,
  uploadFileList: RcFile[],
  props: UploadButtonProps,
) => {
  const { multiple, quantity, fileList } = props;
  return new Promise((resolve, reject) => {
    const findIndex = uploadFileList.findIndex((item) => item.uid === file.uid);
    const fileNum = findIndex + 1 + fileList.length;
    multiple && fileNum <= quantity
      ? resolve({ result: true })
      : reject(fileNum === quantity + 1);
  }).then(
    () => {
      return file;
    },
    (isShow) => {
      if (isShow)
        message.error(`超过限制上传数量${quantity}张，剩余文件已忽略！`);
      return Promise.reject(`超过限制上传数量${quantity}张，剩余文件已忽略`);
    },
  );
};
// 校验文件大小
export const checkSize = (file: RcFile, props: UploadButtonProps) => {
  const { maxSize } = props;
  return new Promise((resolve, reject) => {
    const fileSize = file.size / 1024 / 1024;
    maxSize && fileSize <= maxSize ? resolve({ result: true }) : reject();
  }).then(
    () => {
      return file;
    },
    () => {
      message.error(`超过限制大小${maxSize}MB，请重新选择！`);
      return Promise.reject(`超过限制大小${maxSize}MB，请重新选择！`);
    },
  );
};
// 校验文件格式
export const checkAccept = (file: RcFile, accept: string) => {
  return new Promise((resolve, reject) => {
    const nameList = file.name?.split('.') || [];
    accept &&
    (accept.indexOf(file.type.split('/')[1]) >= 0 ||
      accept.indexOf(nameList[nameList.length - 1]) >= 0)
      ? resolve({ result: true })
      : reject();
  }).then(
    () => {
      return file;
    },
    () => {
      message.error(`文件类型必须是${accept}，请重新选择！`);
      return Promise.reject(`文件类型必须是${accept}，请重新选择！`);
    },
  );
};
// 获取图片宽高
const getImageWidthHeightPrivate = (file: RcFile) => {
  return new Promise((resolve) => {
    let reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function (event: ProgressEvent<FileReader>) {
      let image = new Image();
      image.src =
        (event && event.target && (event.target.result as string)) || '';
      image.onload = function () {
        const obj: {
          width: number;
          height: number;
        } = {
          width: image.width,
          height: image.height,
        };
        resolve(obj);
      };
    };
  });
};
// 校验图片宽高
export const checkWidthHeight = async (
  file: RcFile,
  props: UploadButtonProps,
) => {
  const { picWidth, picHeight, deviation = 0 } = props;
  const ratio = picWidth && picHeight ? (picWidth / picHeight).toFixed(2) : 0;
  const deviationY = ratio ? Number((deviation / Number(ratio)).toFixed(0)) : 0;
  return new Promise((resolve, reject) => {
    if (picWidth && picHeight) {
      getImageWidthHeightPrivate(file).then((res: any) => {
        const imgRatio = (res.width / res.height).toFixed(2);
        // 保持比例一致
        if (deviation && imgRatio !== ratio) {
          reject();
        }
        // 大小在范围内
        if (
          picWidth + deviation >= res.width &&
          res.width >= picWidth - deviation &&
          picHeight + deviationY >= res.height &&
          res.height >= picHeight - deviationY
        ) {
          resolve({ result: true });
        } else {
          reject();
        }
      });
    } else {
      resolve({ result: true });
    }
  }).then(
    () => {
      return file;
    },
    () => {
      const msg =
        deviation && picWidth && picHeight
          ? `图片大小要求为${picWidth - deviation}*${
              picHeight - deviationY
            } 到 ${picWidth + deviation}*${
              picHeight + deviationY
            }, 并且比例为${ratio}`
          : `图片大小要求为${picWidth}*${picHeight}`;
      message.error(msg);
      return Promise.reject(msg);
    },
  );
};
