import { RootState } from "@/store";
import {
  Button,
  Checkbox,
  Form,
  Input,
  Popconfirm,
  Radio,
  Select,
  Switch,
} from "antd";
import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import { useDispatch, useSelector } from "react-redux";
import TextArea from "antd/es/input/TextArea";
import styles from "./index.module.scss";
import { MessageFu } from "@/utils/message";
import ImageLazy from "@/components/ImageLazy";
import classNames from "classnames";
import {
  PlusOutlined,
  CloseCircleOutlined,
  UploadOutlined,
  CloseOutlined,
  PlayCircleOutlined,
} from "@ant-design/icons";
import {
  getGoodsInfoByIdAPI,
  getGoodsSaveAPI,
  goodsUploadAPI,
  setGoodsImgBoderAPI,
} from "@/store/action/B2Goods";
import { baseURL } from "@/utils/http";
import { FileListType, GoodsTableType } from "@/types";

type Props = {
  id: number;
  closeMoalFu: () => void;
  addListFu: () => void;
  editListFu: () => void;
};

// 上传附件的进度条
const UpAsyncLodingDom: any = document.querySelector("#UpAsyncLoding");
const progressDom: any = document.querySelector("#progress");

function GoodsAdd({ id, closeMoalFu, addListFu, editListFu }: Props) {
  const dispatch = useDispatch();

  // 后面添加的的知识驿站
  const [valueZS1, setValueZS1] = useState("");
  const [valueZS2, setValueZS2] = useState<any>([]);

  // 上传附件的信息
  const [fileList, setFileList] = useState({
    model: {} as FileListType,
    img: [] as FileListType[],
    audio: {} as FileListType,
    video: {} as FileListType,
  });

  // 表单的ref
  const FormBoxRef = useRef<any>({});

  // 文件的dirCode码
  const [dirCode, setDirCode] = useState("");

  const getInfoInAPIFu = useCallback(async (id: number) => {
    const res = await getGoodsInfoByIdAPI(id);
    FormBoxRef.current.setFieldsValue(res.data.entity);
    setCover(res.data.entity.thumb);

    if (res.data.entity.type) setTypeCheck(res.data.entity.type.split(","));

    setValueZS1(res.data.entity.tagType);
    if (res.data.entity.tagCountry)
      setValueZS2(res.data.entity.tagCountry.split(","));

    const data: FileListType[] = res.data.file;
    const obj = {
      model: {} as FileListType,
      img: [] as FileListType[],
      audio: {} as FileListType,
      video: {} as FileListType,
    };

    data.forEach((v) => {
      if (v.type === "img") obj.img.push(v);
      else obj[v.type!] = v;
    });
    setFileList(obj);
    setDirCode(res.data.entity.dirCode);
  }, []);

  useEffect(() => {
    if (id > 0) getInfoInAPIFu(id);
    else {
      setDirCode(Date.now() + "");
      FormBoxRef.current.setFieldsValue({
        topic: "不展示",
        display: 1,
        isBarrage: 0,
      });
    }
  }, [getInfoInAPIFu, id]);

  // 从仓库获取下拉列表数据
  const dictList = useSelector((state: RootState) => state.loginStore.dictList);

  // 上传封面图的ref
  const [coverCheck, setCoverCheck] = useState(false);
  const [cover, setCover] = useState("");
  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 = ["image/jpeg", "image/png"];
        if (!type.includes(filesInfo.type)) {
          e.target.value = "";
          return MessageFu.warning("只支持jpg、png格式!");
        }
        // 校验大小
        if (filesInfo.size > 20 * 1024 * 1024) {
          e.target.value = "";
          return MessageFu.warning("最大支持20M!");
        }
        // 创建FormData对象
        const fd = new FormData();
        // 把files添加进FormData对象（‘photo’为后端需要的字段）
        fd.append("type", "thumb");
        fd.append("dirCode", dirCode);
        fd.append("file", filesInfo);

        e.target.value = "";

        const res: any = await goodsUploadAPI(fd);
        if (res.code === 0) {
          MessageFu.success("上传成功!");
          setCover(res.data.filePath);
        }
        UpAsyncLodingDom.style.opacity = 0;
        UpAsyncLodingDom.style.pointerEvents = "none";

        progressDom.style.width = "0%";
      }
    },
    [dirCode]
  );

  // 选中附件类型
  const [typeCheck, setTypeCheck] = useState<any>([]);
  const [typeOk, setTypeOk] = useState(false);

  const typeCheckArr = useMemo(() => {
    return [
      { label: "模型", value: "model" },
      { label: "图片", value: "img" },
      { label: "音频", value: "audio" },
      { label: "视频", value: "video" },
    ];
  }, []);

  // 上传附件图片的有无边框的选择
  const upImgDoneFu = useCallback(
    async (val: boolean, id: number) => {
      const res = await setGoodsImgBoderAPI(id, val ? 1 : 0);
      if (res.code === 0) {
        const newData = {
          ...fileList,
          img: fileList.img.map((v) => {
            return {
              ...v,
              isFrame: v.id === id ? val : v.isFrame,
            };
          }),
        };
        setFileList(newData);
      }
    },
    [fileList]
  );

  // 附件信息的校验

  const fileCheckFu = useMemo(() => {
    let flag = false;
    if (typeCheck.length === 0) flag = true;
    if (typeCheck.includes("model") && !fileList.model.id) flag = true;
    if (typeCheck.includes("img") && fileList.img.length === 0) flag = true;
    if (typeCheck.includes("audio") && !fileList.audio.id) flag = true;
    if (typeCheck.includes("video") && !fileList.video.id) flag = true;
    return flag;
  }, [fileList, typeCheck]);

  // 点击上传附件按钮
  const myInput2 = useRef<HTMLInputElement>(null);

  const [fileOneType, setFileOneType] = useState("");

  useEffect(() => {
    if (fileOneType) myInput2.current?.click();
  }, [fileOneType]);

  const upFileFu = useCallback((type: string) => {
    setFileOneType("");
    window.setTimeout(() => {
      setFileOneType(type);
    }, 100);
  }, []);

  // 上传附件的处理函数
  const handeUpPhoto2 = useCallback(
    async (e: React.ChangeEvent<HTMLInputElement>) => {
      if (e.target.files) {
        // 拿到files信息
        const filesInfo = e.target.files[0];

        let anType = ["image/jpeg", "image/png", "image/gif"];
        let anTit1 = "只支持png、jpg、gif和jpeg格式!";
        let anTit2 = "最大支持20M!";
        let anSize = 20 * 1024 * 1024;

        if (fileOneType === "audio") {
          anType = ["audio/mpeg"];
          anTit1 = "只支持mp3格式!";
          anTit2 = "最大支持10M!";
          anSize = 10 * 1024 * 1024;
        } else if (fileOneType === "video") {
          anType = ["video/mp4"];
          anTit1 = "只支持mp4格式!";
          anTit2 = "最大支持500M!";
          anSize = 500 * 1024 * 1024;
        } else if (fileOneType === "model") {
          anType = [""];
          anTit1 = "只支持4dage格式!";
          anTit2 = "最大支持500M!";
          anSize = 500 * 1024 * 1024;
        }

        // 校验格式
        if (fileOneType !== "model") {
          if (!anType.includes(filesInfo.type)) {
            e.target.value = "";
            return MessageFu.warning(anTit1);
          }
        } else {
          if (!filesInfo.name.includes(".4dage")) {
            e.target.value = "";
            return MessageFu.warning(anTit1);
          }
        }

        // 校验大小
        if (filesInfo.size > anSize) {
          e.target.value = "";
          return MessageFu.warning(anTit2);
        }
        // 创建FormData对象
        const fd = new FormData();
        // 把files添加进FormData对象（‘photo’为后端需要的字段）
        fd.append("type", fileOneType);
        fd.append("dirCode", dirCode);
        fd.append("file", filesInfo);

        e.target.value = "";

        const res: any = await goodsUploadAPI(fd);

        if (res.code === 0) {
          MessageFu.success("上传成功!");
          if (fileOneType === "img")
            setFileList({ ...fileList, img: [res.data, ...fileList.img] });
          else setFileList({ ...fileList, [fileOneType]: res.data });
        }
        UpAsyncLodingDom.style.opacity = 0;
        UpAsyncLodingDom.style.pointerEvents = "none";
        progressDom.style.width = "0%";
      }
    },
    [dirCode, fileList, fileOneType]
  );

  // 附件图片的拖动
  const [dragImg, setDragImg] = useState<any>(null);

  const handleDragOver = useCallback(
    (e: React.DragEvent<HTMLDivElement>, item: FileListType) => {
      e.dataTransfer.dropEffect = "move";
    },
    []
  );

  const handleDragEnter = useCallback(
    (e: React.DragEvent<HTMLDivElement>, item: FileListType) => {
      e.dataTransfer.effectAllowed = "move";
      if (item === dragImg) return;
      const newItems = [...fileList.img]; //拷贝一份数据进行交换操作。
      const src = newItems.indexOf(dragImg); //获取数组下标
      const dst = newItems.indexOf(item);
      newItems.splice(dst, 0, ...newItems.splice(src, 1)); //交换位置
      setFileList({ ...fileList, img: newItems });
    },
    [dragImg, fileList]
  );

  // 删除某一张图片
  const delImgListFu = useCallback(
    (id: number) => {
      const newItems = fileList.img.filter((v) => v.id !== id);
      setFileList({ ...fileList, img: newItems });
    },
    [fileList]
  );

  // 没有通过校验
  const onFinishFailed = useCallback(() => {
    setCoverCheck(true);
    setTypeOk(true);
    return MessageFu.warning("有表单不符号规则!");
  }, []);

  // 通过校验点击确定
  const onFinish = useCallback(
    async (value: GoodsTableType) => {
      console.log("通过校验，点击确定");
      setCoverCheck(true);
      setTypeOk(true);
      if (typeCheck.length === 0 || cover === "" || fileCheckFu)
        return MessageFu.warning("有表单不符号规则!");

      const fileIds = [];
      if (fileList.model.id && typeCheck.includes("model"))
        fileIds.push(fileList.model.id);
      if (fileList.audio.id && typeCheck.includes("audio"))
        fileIds.push(fileList.audio.id);
      if (fileList.video.id && typeCheck.includes("video"))
        fileIds.push(fileList.video.id);
      if (typeCheck.includes("img")) {
        fileList.img.forEach((v) => {
          if (v.id) fileIds.push(v.id);
        });
      }

      const obj = {
        ...value,
        id: id > 0 ? id : null,
        dirCode,
        fileIds: fileIds.join(","),
        thumb: cover,
        type: typeCheck.join(","),
        tagType: valueZS1,
        tagCountry: valueZS2.join(","),
      } as GoodsTableType;
      const res = await getGoodsSaveAPI(obj);
      if (res.code === 0) {
        MessageFu.success(id > 0 ? "编辑成功!" : "新增成功!");
        closeMoalFu();
        if (id > 0) editListFu();
        else addListFu();
      }
    },
    [
      typeCheck,
      cover,
      fileCheckFu,
      fileList.model.id,
      fileList.audio.id,
      fileList.video.id,
      fileList.img,
      id,
      dirCode,
      valueZS1,
      valueZS2,
      closeMoalFu,
      editListFu,
      addListFu,
    ]
  );

  return (
    <div className={styles.GoodsAdd}>
      <div className="main">
        <Form
          ref={FormBoxRef}
          name="basic"
          labelCol={{ span: 3 }}
          onFinish={onFinish}
          onFinishFailed={onFinishFailed}
          autoComplete="off"
        >
          <Form.Item
            label="名称"
            name="name"
            rules={[{ required: true, message: "请输入名称!" }]}
            getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
          >
            <Input maxLength={25} showCount placeholder="请输入内容" />
          </Form.Item>

          <Form.Item
            label="登记编号"
            name="num"
            getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
          >
            <Input maxLength={25} showCount placeholder="请输入内容" />
          </Form.Item>

          <Form.Item
            label="类别"
            name="dictTexture"
            rules={[{ required: true, message: "请选择类别!" }]}
          >
            <Select
              placeholder="请选择"
              style={{ width: 400 }}
              options={dictList["texture"].slice(1)}
            />
          </Form.Item>

          <Form.Item
            label="年代"
            name="dictAge"
            rules={[{ required: true, message: "请选择年代!" }]}
          >
            <Select
              placeholder="请选择"
              style={{ width: 400 }}
              options={dictList["age"].slice(1)}
            />
          </Form.Item>

          <Form.Item
            label="级别"
            name="dictLevel"
            rules={[{ required: true, message: "请选择级别!" }]}
          >
            <Select
              placeholder="请选择"
              style={{ width: 400 }}
              options={dictList["level"].slice(1)}
            />
          </Form.Item>

          <Form.Item
            label="来源"
            name="dictSource"
            rules={[{ required: true, message: "请选择来源!" }]}
          >
            <Select
              placeholder="请选择"
              style={{ width: 400 }}
              options={dictList["source"].slice(1)}
            />
          </Form.Item>

          <Form.Item
            label="万物墙主题"
            name="topic"
            rules={[{ required: true, message: "请选择万物墙主题!" }]}
          >
            <Select
              placeholder="请选择"
              style={{ width: 400 }}
              options={[
                { value: "战争", label: "战争" },
                { value: "生活", label: "生活" },
                { value: "不展示", label: "不展示" },
              ]}
            />
          </Form.Item>

          <Form.Item
            label="简介"
            name="description"
            getValueFromEvent={(e) => e.target.value.trim()}
          >
            <TextArea
              rows={4}
              placeholder="请输入内容"
              showCount
              maxLength={200}
            />
          </Form.Item>

          {/* -----上传封面图片 */}
          <div className="myformBox myformBox0">
            <input
              id="upInput"
              type="file"
              accept=".png,.jpg,.jpeg"
              ref={myInput}
              onChange={(e) => handeUpPhoto(e)}
            />
            <input
              id="upInput2"
              type="file"
              accept={
                fileOneType === "img"
                  ? ".gif,.png,.jpg,.jpeg"
                  : fileOneType === "audio"
                  ? ".mp3"
                  : fileOneType === "model"
                  ? ".4dage"
                  : ".mp4"
              }
              ref={myInput2}
              onChange={(e) => handeUpPhoto2(e)}
            />
            <div className="label">
              <span>*</span> 封面图：
            </div>
            <div className="fileBoxRow_r">
              <div
                hidden={cover !== ""}
                className="fileBoxRow_up"
                onClick={() => myInput.current?.click()}
              >
                <PlusOutlined />
              </div>
              <div className="fileBoxRow_r_img" hidden={cover === ""}>
                {cover ? (
                  <ImageLazy width={100} height={100} src={cover} />
                ) : null}

                <Popconfirm
                  title="删除后无法恢复，是否删除?"
                  okText="删除"
                  cancelText="取消"
                  onConfirm={() => setCover("")}
                >
                  <div className="clearCover">
                    <CloseCircleOutlined />
                  </div>
                </Popconfirm>
              </div>
              <div className="fileBoxRow_r_tit">
                支持png、jpg和jpeg的图片格式；最大支持20M。
                <br />
                <div
                  className={classNames(
                    "noUpThumb",
                    !cover && coverCheck ? "noUpThumbAc" : ""
                  )}
                >
                  请上传封面图!
                </div>
              </div>
            </div>
          </div>

          {/* 选中文件类型和上传附件 */}
          <div className="myformBox">
            <div className="label">
              <span>*</span> 文件类型：
            </div>
            <div className="myformBoxR">
              <Checkbox.Group
                options={typeCheckArr}
                value={typeCheck}
                onChange={(e) => setTypeCheck(e)}
                // onChange={(e) => console.log(e)}
              />
            </div>
          </div>

          {/* -----------模型上传 */}
          <div
            className="myformBox myformBox2"
            hidden={!typeCheck.includes("model")}
          >
            <div className="label">
              <span>*</span> 模型：
            </div>
            {fileList.model.id ? (
              <div className="fileInfo">
                <a
                  href={baseURL + fileList.model.filePath}
                  download
                  target="_blank"
                  className="upSuccTxt"
                  rel="noreferrer"
                >
                  {fileList.model.fileName}
                </a>

                <Popconfirm
                  title="删除后无法恢复，是否删除?"
                  okText="删除"
                  cancelText="取消"
                  onConfirm={() => setFileList({ ...fileList, model: {} })}
                >
                  <div className="clearCover">
                    <CloseCircleOutlined />
                  </div>
                </Popconfirm>
              </div>
            ) : (
              <>
                <Button
                  onClick={() => upFileFu("model")}
                  icon={<UploadOutlined />}
                >
                  上传
                </Button>

                <div className="fileTit">
                  仅支持4dage格式的模型文件，大小不能超过500M。
                </div>
              </>
            )}
          </div>

          {/* -----------图片上传 */}
          <div
            className="myformBox myformBox3"
            hidden={!typeCheck.includes("img")}
          >
            <div className="label">
              <span>*</span> 图片：
            </div>
            <>
              <div className="fileBoxRow_r">
                <div className="upImgBox">
                  <div
                    hidden={!!fileList.img.length && fileList.img.length >= 30}
                    className="fileBoxRow_up"
                    onClick={() => upFileFu("img")}
                  >
                    <PlusOutlined />
                  </div>
                  {fileList.img.map((v) => (
                    <div
                      className="fileBoxRow_r_img"
                      key={v.id}
                      draggable="true"
                      onDragStart={() => setDragImg(v)}
                      onDragOver={(e) => handleDragOver(e, v)}
                      onDragEnter={(e) => handleDragEnter(e, v)}
                      onDragEnd={() => setDragImg(null)}
                    >
                      {/* 选择有没有边框 */}
                      <div className="upImgDoneBox">
                        边框：
                        <Switch
                          checkedChildren="有"
                          unCheckedChildren="无"
                          checked={v.isFrame}
                          onChange={(val) => upImgDoneFu(val, v.id!)}
                        />
                      </div>

                      {v.filePath ? (
                        <ImageLazy
                          noLook={dragImg ? true : false}
                          width={100}
                          height={100}
                          src={v.filePath}
                        />
                      ) : null}

                      <Popconfirm
                        title="删除后无法恢复，是否删除?"
                        okText="删除"
                        cancelText="取消"
                        onConfirm={() => delImgListFu(v.id!)}
                      >
                        <div className="clearCover">
                          <CloseOutlined />
                        </div>
                      </Popconfirm>
                    </div>
                  ))}
                </div>
                <div className="fileTit">
                  {fileList.img.length && fileList.img.length >= 2 ? (
                    <>
                      按住鼠标可拖动图片调整顺序。
                      <br />
                    </>
                  ) : null}
                  支持png、jpg、gif和jpeg的图片格式；最大支持20M；最多支持30张。
                </div>
              </div>
            </>
          </div>

          {/* -----------音频上传 */}
          <div
            className="myformBox myformBox2"
            hidden={!typeCheck.includes("audio")}
          >
            <div className="label">
              <span>*</span> 音频：
            </div>
            {fileList.audio.id ? (
              <div className="fileInfo">
                <a
                  href={baseURL + fileList.audio.filePath}
                  download
                  target="_blank"
                  className="upSuccTxt"
                  rel="noreferrer"
                >
                  {fileList.audio.fileName}
                </a>

                <Popconfirm
                  title="删除后无法恢复，是否删除?"
                  okText="删除"
                  cancelText="取消"
                  onConfirm={() => setFileList({ ...fileList, audio: {} })}
                >
                  <div className="clearCover">
                    <CloseCircleOutlined />
                  </div>
                </Popconfirm>
              </div>
            ) : (
              <>
                <Button
                  onClick={() => upFileFu("audio")}
                  icon={<UploadOutlined />}
                >
                  上传
                </Button>

                <div className="fileTit">
                  仅支持MP3格式的音频文件，大小不得超过10MB。
                </div>
              </>
            )}
          </div>

          {/* -----------视频上传 */}
          <div
            className="myformBox myformBox2"
            hidden={!typeCheck.includes("video")}
          >
            <div className="label">
              <span>*</span> 视频：
            </div>
            {fileList.video.id ? (
              <div className="fileInfo">
                <div className="upSuccTxt">{fileList.video.fileName}</div>
                <div
                  className="clearCover"
                  hidden={!fileList.video.filePath}
                  onClick={() =>
                    dispatch({
                      type: "login/lookVideo",
                      payload: fileList.video.filePath,
                    })
                  }
                >
                  <PlayCircleOutlined />
                </div>

                <Popconfirm
                  title="删除后无法恢复，是否删除?"
                  okText="删除"
                  cancelText="取消"
                  onConfirm={() => setFileList({ ...fileList, video: {} })}
                >
                  <div className="clearCover">
                    <CloseCircleOutlined />
                  </div>
                </Popconfirm>
              </div>
            ) : (
              <>
                <Button
                  onClick={() => upFileFu("video")}
                  icon={<UploadOutlined />}
                >
                  上传
                </Button>

                <div className="fileTit">
                  仅支持MP4格式的视频文件，大小不得超过500MB。
                </div>
              </>
            )}
          </div>

          <div
            className={classNames(
              "noUpThumb noUpThumb2",
              fileCheckFu && typeOk ? "noUpThumbAc" : ""
            )}
          >
            请至少选择一个文件类型，并上传对应附件!
          </div>

          <Form.Item
            label="展示状态"
            name="display"
            rules={[{ required: true, message: "请选择展示状态!" }]}
          >
            <Select
              placeholder="请选择"
              style={{ width: 400 }}
              options={[
                { value: 1, label: "展示" },
                { value: 0, label: "不展示" },
              ]}
            />
          </Form.Item>

          <Form.Item
            label="弹幕留言"
            name="isBarrage"
            rules={[{ required: true, message: "请选择弹幕留言!" }]}
          >
            <Select
              placeholder="请选择"
              style={{ width: 400 }}
              options={[
                { value: 1, label: "开启" },
                { value: 0, label: "关闭" },
              ]}
            />
          </Form.Item>

          <div className="myformBox">
            <div className="label">知识驿站：</div>
            <div className="laseFormRight">
              <div className="laseFormRightRow">
                <div className="laseFormRightLabel">类别标签：</div>
                <Radio.Group
                  onChange={(e) => setValueZS1(e.target.value)}
                  value={valueZS1}
                >
                  <Radio value={"军事"}>军事</Radio>
                  <Radio value={"历史"}>历史</Radio>
                  <Radio value={"人物"}>人物</Radio>
                  <Radio value={"科学"}>科学</Radio>
                  <Radio value={"教育"}>教育</Radio>
                  <Radio value={"经济"}>经济</Radio>
                </Radio.Group>
              </div>
              <div className="laseFormRightTit">
                如需文物关联知识驿站，请至少标注类别标签
              </div>
              <br />
              <div className="laseFormRightRow">
                <div className="laseFormRightLabel">国家标签：</div>
                <Checkbox.Group
                  value={valueZS2}
                  onChange={(e) => setValueZS2(e)}
                  options={[
                    { label: "清朝", value: "清朝", disabled: !valueZS1 },
                    { label: "美国", value: "美国", disabled: !valueZS1 },
                    { label: "西方", value: "西方", disabled: !valueZS1 },
                  ]}
                />
              </div>
            </div>
          </div>

          {/* 确定和取消按钮 */}
          <br />
          <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
            <Button type="primary" htmlType="submit">
              提交
            </Button>
            &emsp;
            <Popconfirm
              title="放弃编辑后，信息将不会保存!"
              okText="放弃"
              cancelText="取消"
              onConfirm={closeMoalFu}
            >
              <Button>取消</Button>
            </Popconfirm>
          </Form.Item>
        </Form>
      </div>
    </div>
  );
}

const MemoGoodsAdd = React.memo(GoodsAdd);

export default MemoGoodsAdd;
