import { Checkbox } from "antd";
import {
  forwardRef,
  useCallback,
  useEffect,
  useImperativeHandle,
  useMemo,
  useState,
} from "react";
import { CheckboxValueType } from "antd/es/checkbox/Group";
import { DAGE_FILE_CHECKBOX_OPTIONS } from "./constants";
import { DageFileCheckboxMethods, DageFileCheckboxProps } from "./types";
import {
  DageFileResponseType,
  DageUpload,
  DageUploadType,
} from "../DageUpload";
import { FileCheckboxItem } from "./style";

export const DageFileCheckbox = forwardRef<
  DageFileCheckboxMethods,
  DageFileCheckboxProps
>(
  (
    {
      value,
      action,
      disabled,
      hasMobileModel,
      maxAudioCount = 1,
      maxImgCount = 9,
      maxMobileModelCount = 1,
      maxModelCount = 1,
      maxVideoCount = 1,
      onChange,
      onFileChange,
    },
    ref
  ) => {
    const checkboxVal = useMemo(() => (value ? value.split(",") : []), [value]);
    const [modelFiles, setModelFiles] = useState<DageFileResponseType[]>([]);
    const [mobileModelFiles, setMobileModelFiles] = useState<
      DageFileResponseType[]
    >([]);
    const [imgFiles, setImgFiles] = useState<DageFileResponseType[]>([]);
    const [videoFiles, setVideoFiles] = useState<DageFileResponseType[]>([]);
    const [audioFiles, setAudioFiles] = useState<DageFileResponseType[]>([]);

    const hasModel = useMemo(
      () => checkboxVal.includes(DageUploadType.MODEL),
      [checkboxVal]
    );
    const hasImg = useMemo(
      () => checkboxVal.includes(DageUploadType.IMG),
      [checkboxVal]
    );
    const hasAudio = useMemo(
      () => checkboxVal.includes(DageUploadType.AUDIO),
      [checkboxVal]
    );
    const hasVideo = useMemo(
      () => checkboxVal.includes(DageUploadType.VIDEO),
      [checkboxVal]
    );

    useImperativeHandle(ref, () => ({
      validate(rule, val, callback) {
        if (!val) {
          callback("请选择文件类型");
        } else if (
          hasModel &&
          (!modelFiles.length || !modelFiles.some((i) => i.status === "done"))
        ) {
          callback("PC端模型文件不能为空");
        } else if (
          hasModel &&
          hasMobileModel &&
          (!mobileModelFiles.length ||
            !mobileModelFiles.some((i) => i.status === "done"))
        ) {
          callback("移动端模型文件不能为空");
        } else if (
          hasImg &&
          (!imgFiles.length || !imgFiles.some((i) => i.status === "done"))
        ) {
          callback("图片文件不能为空");
        } else if (
          hasVideo &&
          (!videoFiles.length || !videoFiles.some((i) => i.status === "done"))
        ) {
          callback("视频文件不能为空");
        } else if (
          hasAudio &&
          (!audioFiles.length || !audioFiles.some((i) => i.status === "done"))
        ) {
          callback("音频文件不能为空");
        }
        callback();
      },
      setFileList(list) {
        const stack: Record<string, DageFileResponseType[]> = {
          [DageUploadType.MODEL]: [],
          [DageUploadType.MOBILE_MODEL]: [],
          [DageUploadType.IMG]: [],
          [DageUploadType.AUDIO]: [],
          [DageUploadType.VIDEO]: [],
        };

        list.forEach((item) => {
          stack[item.dType].push(item);
        });

        Object.keys(stack).forEach((key) => {
          const list = stack[key];
          if (!list.length) return;
          switch (key) {
            case DageUploadType.MODEL:
              setModelFiles(list);
              break;
            case DageUploadType.MOBILE_MODEL:
              setMobileModelFiles(list);
              break;
            case DageUploadType.IMG:
              setImgFiles(list);
              break;
            case DageUploadType.AUDIO:
              setAudioFiles(list);
              break;
            case DageUploadType.VIDEO:
              setVideoFiles(list);
              break;
          }
        });
      },
    }));

    const handleCheckbox = useCallback(
      (val: CheckboxValueType[]) => {
        onChange?.(val.join(","));
      },
      [onChange]
    );

    const handleFileChange = useCallback(
      (
        method: (v: DageFileResponseType[]) => void,
        list: DageFileResponseType[]
      ) => {
        method(list);
      },
      []
    );

    useEffect(() => {
      if (!onFileChange) return;

      onFileChange([
        ...(hasModel ? modelFiles : []),
        ...(hasModel && hasMobileModel ? mobileModelFiles : []),
        ...(hasImg ? imgFiles : []),
        ...(hasVideo ? videoFiles : []),
        ...(hasAudio ? audioFiles : []),
      ]);
    }, [
      hasMobileModel,
      modelFiles,
      mobileModelFiles,
      imgFiles,
      videoFiles,
      audioFiles,
      hasModel,
      hasImg,
      hasVideo,
      hasAudio,
      onFileChange,
    ]);

    return (
      <div className="dage-file-checkbox">
        <Checkbox.Group
          disabled={disabled}
          value={checkboxVal}
          options={DAGE_FILE_CHECKBOX_OPTIONS}
          style={{
            display: "flex",
            alignItems: "center",
            height: "32px",
          }}
          onChange={handleCheckbox}
        />

        {hasModel && (
          <>
            <FileCheckboxItem className="dage-file-checkbox__item">
              <p>PC端模型：</p>
              <DageUpload
                disabled={disabled}
                value={modelFiles}
                action={action}
                dType={DageUploadType.MODEL}
                maxCount={maxModelCount}
                maxSize={500}
                tips="仅支持4dage格式的模型文件，大小不能超过500M"
                onChange={handleFileChange.bind(undefined, setModelFiles)}
              />
            </FileCheckboxItem>

            {hasMobileModel && (
              <FileCheckboxItem className="dage-file-checkbox__item">
                <p>移动端模型：</p>
                <DageUpload
                  disabled={disabled}
                  value={mobileModelFiles}
                  action={action}
                  dType={DageUploadType.MOBILE_MODEL}
                  maxCount={maxMobileModelCount}
                  maxSize={1000}
                  tips="仅支持zip格式的压缩包，大小不能超过1000M"
                  onChange={handleFileChange.bind(
                    undefined,
                    setMobileModelFiles
                  )}
                />
              </FileCheckboxItem>
            )}
          </>
        )}
        {hasImg && (
          <FileCheckboxItem className="dage-file-checkbox__item">
            <p>图片：</p>
            <DageUpload
              disabled={disabled}
              value={imgFiles}
              action={action}
              dType={DageUploadType.IMG}
              maxCount={maxImgCount}
              maxSize={20}
              tips="支持png、jpg和jpeg格式；最大20M，最多9张"
              onChange={handleFileChange.bind(undefined, setImgFiles)}
            />
          </FileCheckboxItem>
        )}
        {hasAudio && (
          <FileCheckboxItem className="dage-file-checkbox__item">
            <p>音频：</p>
            <DageUpload
              disabled={disabled}
              value={audioFiles}
              action={action}
              dType={DageUploadType.AUDIO}
              maxCount={maxAudioCount}
              maxSize={10}
              tips="仅支持MP3格式的音频文件，大小不得超过10MB"
              onChange={handleFileChange.bind(undefined, setAudioFiles)}
            />
          </FileCheckboxItem>
        )}
        {hasVideo && (
          <FileCheckboxItem className="dage-file-checkbox__item">
            <p>视频：</p>
            <DageUpload
              disabled={disabled}
              value={videoFiles}
              action={action}
              dType={DageUploadType.VIDEO}
              maxCount={maxVideoCount}
              maxSize={500}
              tips="仅支持MP4格式的视频文件，大小不得超过500MB"
              onChange={handleFileChange.bind(undefined, setVideoFiles)}
            />
          </FileCheckboxItem>
        )}
      </div>
    );
  }
);

export * from "./types";
export * from "./constants";
