import React, { useCallback, useMemo, useRef, useState } from "react";
import styles from "./index.module.scss";
import ImageLazy from "@/components/ImageLazy";
import {
  PlusOutlined,
  EyeOutlined,
  CloseOutlined,
  DownloadOutlined,
  UploadOutlined,
} from "@ant-design/icons";
import store from "@/store";
import { baseURL } from "@/utils/http";
import classNames from "classnames";
import { Button } from "antd";
import { MessageFu } from "@/utils/message";
import { fileDomInitialFu } from "@/utils/domShow";
import { API_upFile } from "@/store/action/layout";
import { forwardRef, useImperativeHandle } from "react";
import MyPopconfirm from "../MyPopconfirm";

// 这个组件 只处理 上传 一张图片或者 视频 音频 模型 的情况

type Props = {
  isLook: boolean; //是不是查看
  fileCheck: boolean; //有没有点击过确定
  size: number; //上传附件大小（M）
  dirCode: string; //文件的code码
  myUrl: string; //请求地址
  format: string[]; //上传格式
  formatTxt: string; //上传图片提示
  checkTxt: string;
  upTxt: string;
  myType: "thumb" | "video" | "audio" | "model";
  fromData?: any;
  ref: any; //当前自己的ref，给父组件调用
};

function ZupOne(
  {
    isLook,
    fileCheck,
    size,
    dirCode,
    myUrl,
    format,
    formatTxt,
    checkTxt,
    upTxt,
    myType,
    fromData,
  }: Props,
  ref: any
) {
  const [fileUrl, setFileUrl] = useState({
    fileName: "",
    filePath: "",
  });

  const myInput = useRef<HTMLInputElement>(null);

  // 上传封面图
  const handeUpPhoto = useCallback(
    async (e: React.ChangeEvent<HTMLInputElement>) => {
      if (e.target.files) {
        // 拿到files信息
        const filesInfo = e.target.files[0];
        // 校验格式
        const type = format;
        if (!type.includes(filesInfo.type)) {
          e.target.value = "";
          return MessageFu.warning(`只支持${formatTxt}格式!`);
        }
        // 校验大小
        if (filesInfo.size > size * 1024 * 1024) {
          e.target.value = "";
          return MessageFu.warning(`最大支持${size}M!`);
        }
        // 创建FormData对象
        const fd = new FormData();
        // 把files添加进FormData对象（‘photo’为后端需要的字段）
        fd.append("type", myType);
        fd.append("dirCode", dirCode);
        fd.append("file", filesInfo);

        if (fromData) {
          for (const k in fromData) {
            if (fromData[k]) fd.append(k, fromData[k]);
          }
        }

        e.target.value = "";

        try {
          const res = await API_upFile(fd, myUrl);
          if (res.code === 0) {
            MessageFu.success("上传成功!");
            setFileUrl(res.data);
          }
          fileDomInitialFu();
        } catch (error) {
          fileDomInitialFu();
        }
      }
    },
    [dirCode, format, formatTxt, fromData, myType, myUrl, size]
  );

  // 让父组件调用的 回显 附件 地址
  const setFileComFileFu = useCallback(
    (valObj: { fileName: string; filePath: string }) => {
      setFileUrl(valObj);
    },
    []
  );

  // 让父组件调用的返回 附件 名字和路径
  const fileComFileResFu = useCallback(() => {
    return fileUrl;
  }, [fileUrl]);

  // 可以让父组件调用子组件的方法
  useImperativeHandle(ref, () => ({
    setFileComFileFu,
    fileComFileResFu,
  }));

  const acceptRes = useMemo(() => {
    let accept = ".png,.jpg,.jpeg";
    if (myType === "video") accept = ".mp4";
    else if (myType === "audio") accept = ".mp3";
    else if (myType === "model") accept = ".4dage";
    return accept;
  }, [myType]);

  return (
    <div className={styles.ZupOne}>
      <input
        id="upInput"
        type="file"
        accept={acceptRes}
        ref={myInput}
        onChange={(e) => handeUpPhoto(e)}
      />
      {myType === "thumb" ? (
        <div
          hidden={fileUrl.filePath !== ""}
          className="file_upIcon"
          onClick={() => myInput.current?.click()}
        >
          <PlusOutlined rev={undefined} />
        </div>
      ) : (
        <Button
          hidden={fileUrl.filePath !== ""}
          onClick={() => myInput.current?.click()}
          icon={<UploadOutlined rev={undefined} />}
        >
          上传
        </Button>
      )}

      {/* 为图片的情况-------------- */}
      {myType === "thumb" ? (
        <div className="file_img" hidden={fileUrl.filePath === ""}>
          {fileUrl ? (
            <ImageLazy width={100} height={100} src={fileUrl.filePath} noLook />
          ) : null}

          {/* 删除 */}
          <div className="file_closeBox" hidden={isLook}>
            <MyPopconfirm
              txtK="删除"
              onConfirm={() => setFileUrl({ fileName: "", filePath: "" })}
              Dom={<CloseOutlined rev={undefined} />}
            />
          </div>

          {/* 预览 下载 */}
          <div className="file_lookBox">
            <EyeOutlined
              onClick={() =>
                store.dispatch({
                  type: "layout/lookBigImg",
                  payload: { url: baseURL + fileUrl.filePath, show: true },
                })
              }
              rev={undefined}
            />
            <a
              href={baseURL + fileUrl.filePath}
              download
              target="_blank"
              rel="noreferrer"
            >
              <DownloadOutlined rev={undefined} />
            </a>
          </div>
        </div>
      ) : fileUrl.filePath ? (
        <div className="fileInfo">
          <div className="upSuccTxt">{fileUrl.fileName}</div>
          {/* 视频预览 */}
          <div
            className="clearCover"
            hidden={!fileUrl.filePath}
            onClick={() =>
              store.dispatch({
                type: "layout/lookDom",
                payload: { src: fileUrl.filePath, type: myType },
              })
            }
          >
            <EyeOutlined rev={undefined} />
          </div>
          {/* 视频下载 */}
          <a
            href={baseURL + fileUrl.filePath}
            download
            target="_blank"
            className="clearCover"
            rel="noreferrer"
          >
            <DownloadOutlined rev={undefined} />
          </a>
          {/* 视频删除 */}

          <MyPopconfirm
            txtK="删除"
            onConfirm={() => setFileUrl({ fileName: "", filePath: "" })}
            Dom={<CloseOutlined className="clearCover" rev={undefined} />}
          />
        </div>
      ) : null}

      <div className="fileBoxRow_r_tit" hidden={isLook}>
        支持{formatTxt}格式；最大支持{size}M。{upTxt}
        <br />
        <div
          className={classNames(
            "noUpThumb",
            !fileUrl.filePath && fileCheck ? "noUpThumbAc" : ""
          )}
        >
          {checkTxt}
        </div>
      </div>
    </div>
  );
}

export default forwardRef(ZupOne);
