import React, { useContext, useMemo, useState } from "react";
import { getModelTypes } from "_util/config";
import { message } from "antd";
import { ConfigContext } from "config-provider";
import { Icon, Upload } from "easy-design";
import ErrorBoundary from "../../error-boundary";

const modelTypes = getModelTypes();

const accepts = {
  uploadImage: "image/*",
  image: "image/*",
  video: "video/*",
  audio: "audio/*",
  folder: ".zip,application/zip",
  uploadModel: `${modelTypes.map((d) => `.${d}`).join(",")}`,
};

export default function EasyUpload({
  type,
  maxSize,
  value,
  showDownload,
  accept,
  onChange,
  onCustomEvents,
  customField,
}) {
  const [loading, setLoading] = useState(false);
  const {
    assetsUrl,
    uploadBasePath,
    onUpload,
    imageMaxSize = 5 * 1024 * 1024,
    videoMaxSize = 150 * 1024 * 1024,
    audioMaxSize = 150 * 1024 * 1024,
    fileMaxSize = 150 * 1024 * 1024,
  } = useContext(ConfigContext);
  const urls = useMemo(() => {
    if (type === "pointNineImage" && value?.url) {
      return value.url;
    } else {
      return value;
    }
  }, [value, type]);
  if (type === "uploadModel" && accept) {
    const _accepts = accept.split(",").map((d) => d.trim().replace(".", ""));
    accept = _accepts.every((e) => modelTypes.includes(e)) ? accept : accepts["uploadModel"];
  }

  // 递归处理嵌套结构的函数
  const createJSXElement = (node) => {
    const { tagName, props, children, innerHTML = "" } = node;

    if (typeof tagName === "string") {
      const nodeArr = [];
      if (children instanceof HTMLCollection) {
        // HTMLCollection不能用正常数组的map等方法
        for (let i = 0; i < children.length; i++) {
          nodeArr.push(createJSXElement(children[i]));
        }
      }

      if (nodeArr.length)
        return React.createElement(tagName.toLowerCase(), props || null, ...nodeArr);
      else return React.createElement(tagName.toLowerCase(), props || null, innerHTML);
    }
  };

  const getContent = () => {
    if (customField) {
      try {
        const customFunction = eval(`(${customField})`);

        if (customFunction) {
          const customNode = createJSXElement(customFunction());
          return customNode;
        }
      } catch (error) {
        console.error("upload控件自定义内容解析时发生错误：", error);
      }
    }

    if (type === "uploadImage" || type === "image" || type === "pointNineImage") {
      return (
        <div
          style={{
            backgroundImage: `url('${assetsUrl}${urls}')`,
            backgroundRepeat: "no-repeat",
            backgroundPosition: "center center",
            backgroundSize: "contain",
            width: "100%",
            height: "100%",
          }}
        />
      );
    }
    return <Icon type={type} style={{ fontSize: 28 }} />;
  };

  const pathType = type === "uploadImage" || type === "image" ? "img" : type;

  const globalConfigs = window.appConfig?.CONFIGS;
  const getLimitSize = (configKey, contextMaxSize) => {
    let size = 0;
    const sizeData = globalConfigs?.find((v) => v.key === configKey)?.value;
    const configSize = (sizeData?.current || sizeData?.default) * 1024 * 1024;
    size = configSize ? configSize : maxSize ? maxSize : contextMaxSize;

    return size;
  };

  const handleCustomRequest = async (e) => {
    if (onUpload) {
      const file = e.file;

      if (type === "uploadImage" || type === "image" || type === "pointNineImage") {
        const size = getLimitSize("imageSizeLimit", imageMaxSize);
        if (file.size > size) {
          message.error(`图片不能超过${getSize(size)}`);
          return;
        }
      } else if (type === "audio") {
        const size = getLimitSize("audioSizeLimit", audioMaxSize);
        if (file.size > size) {
          message.error(`音频不能超过${getSize(size)}`);
          return;
        }
      } else if (type === "video") {
        const size = getLimitSize("videoSizeLimit", videoMaxSize);
        if (file.size > size) {
          message.error(`视频不能超过${getSize(size)}`);
          return;
        }
      } else if (type === "uploadModel") {
        const size = getLimitSize("moduleSizeLimit", fileMaxSize);
        if (file.size > size) {
          message.error(`模型不能超过${getSize(size)}`);
          return;
        }
      } else {
        const size = getLimitSize("fileSizeLimit", fileMaxSize);
        if (file.size > size) {
          message.error(`文件不能超过${getSize(size)}`);
          return;
        }
      }

      setLoading(true);
      const result = await onUpload({
        file: file,
        path: `${uploadBasePath}/${pathType}/${file.name}`,
      });
      setLoading(false);
      if (result) {
        onChange(result);
      } else {
        message.error("上传失败");
      }
    } else {
      message.error("暂不支持上传");
    }
  };

  return (
    <ErrorBoundary message="upload控件发生错误">
      <Upload
        loading={loading}
        disabled={!onUpload}
        showDownload={showDownload}
        content={getContent()}
        url={urls}
        type={type}
        value={urls && `${assetsUrl}${urls}`}
        config={value}
        accept={accept ? accept : accepts[type]}
        onChange={onChange}
        onCustomEvents={onCustomEvents}
        customRequest={handleCustomRequest}
      />
    </ErrorBoundary>
  );
}

function getSize(size) {
  return size / 1024 < 1024 ? `${Math.floor(size / 1024)}KB` : `${Math.floor(size / 1024 / 1024)}M`;
}
