import { FC, ReactNode, useMemo, useRef, useState } from "react";
import { UploadFile } from "antd/es/upload/interface";
import {
  DeleteOutlined,
  DownloadOutlined,
  EyeOutlined,
} from "@ant-design/icons";
import { Button, Progress, message } from "antd";
import {
  DownloadCancelBtn,
  DownloadProgress,
  UploadFileItem,
  UploadFileItemActions,
  UploadPictureItem,
  UploadPictureItemActions,
} from "./style";
import { requestWithPercent } from "../../utils";

export interface DageUploadItemActionsProps {
  file: UploadFile;
  actions: {
    preview: () => void;
    remove: () => void;
  };
  isPictureCard?: boolean;
  disabled?: boolean;
  downloadErrorMessage: string;
  children: ReactNode;
}

export const DageUploadItemActions: FC<DageUploadItemActionsProps> = ({
  children,
  disabled,
  file,
  isPictureCard,
  actions,
  downloadErrorMessage,
}) => {
  const controller = useRef<AbortController | null>(null);
  const [downloading, setDownloading] = useState(false);
  /** 下载进度百分比 */
  const [downloadPercent, setDownloadPercent] = useState(0);
  /** 显示下载按钮 */
  const showDownload = (file.url || "").indexOf("http") > -1;
  /** 显示下载进度条 */
  const showDownloadProgress = useMemo(
    () => !isPictureCard && downloading,
    [isPictureCard, downloading]
  );
  const UploadItem = isPictureCard ? UploadPictureItem : UploadFileItem;
  const UploadItemActions = isPictureCard
    ? UploadPictureItemActions
    : UploadFileItemActions;

  const handleDownload = async () => {
    if (!file.url) return;

    try {
      setDownloading(true);
      controller.current = new AbortController();
      const res = await requestWithPercent({
        url: file.url,
        option: {
          signal: controller.current?.signal,
        },
        onProcess: (now, all) => {
          setDownloadPercent(Math.round((now / all) * 100));
        },
      });

      // @ts-ignore
      const blob = new Blob([res]);
      const url = URL.createObjectURL(blob);

      const link = document.createElement("a");
      link.href = url;
      link.target = "_blank";
      link.download = file.name;
      link.style.display = "none";
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    } catch (err) {
      if (err instanceof Error && err.name !== "AbortError") {
        message.error(downloadErrorMessage);
      }
    } finally {
      // 等待进度条动画完成
      setTimeout(() => {
        setDownloading(false);
        setDownloadPercent(0);
      }, 300);
    }
  };

  const handleDownloadCancel = () => {
    controller.current?.abort();
  };

  return (
    <UploadItem
      className="dage-upload__item"
      $showDownloadProgress={showDownloadProgress}
    >
      {children}

      <UploadItemActions className="dage-upload__item__actions">
        {isPictureCard && (
          <Button
            type="text"
            size="small"
            icon={<EyeOutlined />}
            onClick={actions.preview}
          />
        )}
        {showDownload && (
          <Button
            type="text"
            size="small"
            loading={downloading}
            disabled={downloading}
            icon={<DownloadOutlined />}
            onClick={handleDownload}
          />
        )}
        {!disabled && (
          <Button
            type="text"
            size="small"
            icon={<DeleteOutlined />}
            onClick={actions.remove}
          />
        )}
      </UploadItemActions>

      {/* 下载进度条 */}
      {showDownloadProgress && (
        <DownloadProgress className="dage-upload__item__progress">
          <Progress
            size="small"
            percent={downloadPercent}
            style={{ margin: 0 }}
          />

          {downloadPercent < 100 && (
            <DownloadCancelBtn onClick={handleDownloadCancel} />
          )}
        </DownloadProgress>
      )}
    </UploadItem>
  );
};
