import { Button, message, Progress } from "antd";
import type { UploadFile as UploadFiles } from "antd";
import { Col, Flex, Row, Typography, Upload } from "antd";
import { nanoid } from "nanoid";
import React, { useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
import { Delete, ErrorFileIcon, FilesIcon, PlayCircleFill, UploadIcon } from "../../Icons";
import {
  eUploadStatusType,
  type iUploadFilePropsType,
  type iUploadFileValueType,
} from "./index.type";
import { CoverFileInfoWrapper, UploadErrorMessage, UploadFileWrapper } from "./styled";

const { Text } = Typography;
const acceptType =
  ".mp3,.wav,.m4a,.wma,.aac,.ogg,.amr,.flac,.aiff,.mp4,.wmv,.m4v,.flv,.rmvb,.dat,.mov,.mkv,.webm,.avi,.mpeg,.3gp,.ogg";
export const UploadFile = React.forwardRef<any, iUploadFilePropsType>(
  (
    {
      value = {},
      onChange = () => {},
      disabled = false,
      confirmText = "开始分析",
      confirmDataAutolog,
      onConfirmHandler = () => {},
      maxSize = 6 * 1024 * 1024 * 1024, // 6GB
      accept = acceptType,
      title = "点击或拖拽文件至此区域上传",
      uploadIcon,
      fileStatusPosition = "footer",
      describe = "支持mp3、wav、m4a、wma、aac、ogg、amr、flac、aiff格式的音频文件和mp4、wmv、m4v、flv、rmvb、dat、mov、mkv、webm、avi、mpeg、3gp、ogg格式的视频文件。文件大小不超过6GB。",
      onPreVerifyHandler = async () => true,
      onClickContainerHandler = () => {},
    },
    ref
  ) => {
    const uploadRef = useRef<any>();
    const [uploadFile, setUploadFile] = useState<UploadFiles>();
    const [percent, setPercent] = useState(0);
    const uploadFileValueRef = useRef<iUploadFileValueType>();
    const [uploadStatus, setUploadStatus] = useState<eUploadStatusType>(eUploadStatusType.IDLE);
    const [uploadErrorMessage, setUploadErrorMessage] = useState<string>("系统出错了，请重试");

    // 暴露给父组件的方法
    useImperativeHandle(ref, () => ({
      clearFile: () => {
        handleClearFile();
      },
      getUploadStatus: () => uploadStatus,
    }));

    // // 查询上传 token
    // const getOssAuthInfo = async (params: {
    //   fileContentType: string;
    //   fileName: string;
    //   fileUniqueId: string;
    //   fileSize: number;
    // }) => {
    //   try {
    //     const result = await uploadTFile({
    //       fileName: params.fileName,
    //       fileSize: params.fileSize,
    //     });

    //     if (result.sts) {
    //       return { ...result.sts, fileId: result.fileId };
    //     }

    //     return null;
    //   } catch (error) {
    //     console.log(error);
    //   }
    // };

    const handleUploadData = ({ file }: { file: any }) => {
      const newValue: iUploadFileValueType = {
        ...value,
        progress: 100,
        // TODO 文件路径。
        fileUrl:
          "https://agentic-resource-pre.oss-cn-hangzhou.aliyuncs.com/%E8%AF%95%E9%A9%BE%E6%A1%88%E4%BE%8B.wav?OSSAccessKeyId=LTAI5tKZP7TuS7QuF8TYNMn1&Expires=1763943764&Signature=PUgSMleiks7lmRmJdhEA91o65vE%3D",
      };

      uploadFileValueRef.current = newValue;
      onChange(newValue);
    };

    /** 上传文件 */
    const onBeforeUpload = async (file: UploadFiles) => {
      try {
        // 中止之前的上传
        const preVerify = await onPreVerifyHandler();
        if (!preVerify) return;
        // TODO 上传之前取消之前上传中的文件
        // if (uploadFile) {
        //   abortUpload("");
        // }

        // 文件大小验证
        if (file.size! > maxSize) {
          message.error({
            content: `请上传${formatFileSize(maxSize)}以内的文件`,
          });
          return false;
        }

        const name = file.name;
        const type = name.slice(name.lastIndexOf(".")).toLocaleLowerCase();
        // 文件类型验证
        if (!acceptType.split(",").includes(type!)) {
          message.error({ content: "请上传正确的文件类型" });
          return false;
        }

        setUploadFile(file);
        setUploadStatus(eUploadStatusType.FINISH);
        setPercent(100);

        // const fileSize = file.size!;
        // const fileContentType = file.type!;
        // const fileUniqueId = nanoid();

        // 更新表单值
        const newValue: iUploadFileValueType = {
          fileName: file.name,
          fileSize: file.size,
          uploadStatus: eUploadStatusType.FINISH,
          progress: 100,
        };
        uploadFileValueRef.current = newValue;
        onChange(newValue);
        // TODO 上传到oss上。
        // const ossAuthInfo = await getOssAuthInfo({
        //   fileContentType,
        //   fileUniqueId,
        //   fileSize,
        //   fileName: file.name,
        // });

        // if (!ossAuthInfo) {
        //   setUploadStatus(eUploadStatusType.FAILED);
        //   const nextValue: iUploadFileValueType = {
        //     ...newValue,
        //     uploadStatus: eUploadStatusType.FAILED,
        //   };
        //   uploadFileValueRef.current = nextValue;
        //   onChange(nextValue);
        //   return false;
        // }

        // const mime = `${file.type};charset=utf-8`;

        // 更新文件信息
        // const updatedValue: iUploadFileValueType = {
        //   ...newValue,
        //   fileUrl: ossAuthInfo.key,
        //   fileId: ossAuthInfo.fileId,
        // };
        // uploadFileValueRef.current = updatedValue;
        // onChange(updatedValue);

        // await startUploadFunc({
        //   file,
        //   fileId: ossAuthInfo.fileId,
        //   ossAuthInfo: {
        //     accessKeyId: ossAuthInfo.accessKeyId,
        //     accessKeySecret: ossAuthInfo.accessKeySecret,
        //     stsToken: ossAuthInfo.securityToken,
        //     bucketName: ossAuthInfo.bucket,
        //     endpoint: ossAuthInfo.endpoint,
        //     dir: ossAuthInfo.key,
        //   },
        //   multipartUploadOptions: {
        //     mime,
        //   },
        // } as any);
      } catch (error) {
        setUploadStatus(eUploadStatusType.FAILED);
        const nextValue: iUploadFileValueType = {
          ...value,
          uploadStatus: eUploadStatusType.FAILED,
        };
        uploadFileValueRef.current = nextValue;
        onChange(nextValue);
        message.error("上传失败，请重试");
      }

      return false; // 阻止默认上传行为
    };

    const customRequest = () => {};

    const formatFileSize = (bytes: number) => {
      const sizes = ["B", "KB", "MB", "GB", "TB"];
      if (bytes === 0) return "0 B";
      const i = Math.floor(Math.log(bytes) / Math.log(1024));
      return `${Math.round(bytes / Math.pow(1024, i))} ${sizes[i]}`;
    };

    const handleClearFile = () => {
      setUploadFile(undefined);
      setPercent(0);
      setUploadStatus(eUploadStatusType.IDLE);
      // abortUpload("");
      uploadFileValueRef.current = undefined;
      onChange({});
    };

    // 从 value 中恢复状态
    useEffect(() => {
      if (value.fileName && !uploadFile) {
        setUploadFile({
          uid: nanoid(),
          name: value.fileName,
          size: value.fileSize,
          type: "",
        });
      }
      if (value.progress !== undefined) {
        setPercent(value.progress);
      }
      if (value.uploadStatus) {
        setUploadStatus(value.uploadStatus);
      }
    }, [value]);

    const renderFooterFileInfo = useMemo(() => {
      if (!uploadFile?.name || fileStatusPosition !== "footer") return null;
      return (
        <Row justify="space-between" className="Context" align="middle">
          <Col span={1} style={{ minWidth: "40px" }}>
            <FilesIcon />
          </Col>
          <Col span={20}>
            <Flex vertical>
              <Text className="Context__Name">{uploadFile.name}</Text>
              {uploadStatus === eUploadStatusType.RUNNING && percent < 100 && (
                <Progress
                  className="Context__Name"
                  percent={Math.round(percent)}
                  showInfo={false}
                  size={100}
                />
              )}
              {uploadStatus === eUploadStatusType.FINISH && (
                <Text className="Context__Text">
                  {formatFileSize(uploadFile.size || 0)} - 上传完成
                </Text>
              )}
              {uploadStatus === eUploadStatusType.FAILED && (
                <Text className="Context__Text1">上传失败，请重试</Text>
              )}
              {uploadStatus === eUploadStatusType.IDLE && uploadFile.size && (
                <Text className="Context__Text">{formatFileSize(uploadFile.size)}</Text>
              )}
            </Flex>
          </Col>
          <Col span={1}>
            <span style={{ textAlign: "center", cursor: "pointer" }} onClick={handleClearFile}>
              <Delete style={{ marginLeft: "16px", marginTop: "6px" }} />
            </span>
          </Col>
        </Row>
      );
    }, [percent, uploadFile, uploadStatus, fileStatusPosition, handleClearFile]);

    const renderCoverFileInfo = useMemo(() => {
      if (!uploadFile?.name || fileStatusPosition !== "cover") return null;

      let content = null;

      switch (uploadStatus) {
        case eUploadStatusType.FAILED: {
          content = (
            <UploadErrorMessage align="center" justify="center">
              {uploadErrorMessage}
            </UploadErrorMessage>
          );
          break;
        }
        case eUploadStatusType.FINISH: {
          content = (
            <Button
              type="primary"
              onClick={() => {
                onConfirmHandler(uploadFileValueRef.current || {});
              }}
              data-autolog={confirmDataAutolog}
            >
              <Flex gap={8} align="center" justify="center">
                <PlayCircleFill />
                {confirmText}
              </Flex>
            </Button>
          );
          break;
        }
        default: {
          content = (
            <Flex justify="center" align="center">
              <Progress percent={percent} size={100} showInfo={false} />
            </Flex>
          );
          break;
        }
      }
      return (
        <CoverFileInfoWrapper vertical justify="center" align="center">
          <div className="UploadFileThumbnail">
            {uploadStatus === eUploadStatusType.FAILED ? <ErrorFileIcon /> : <FilesIcon />}
          </div>
          <Flex align="center" justify="center" gap={8} className="UploadFileName">
            <div
              className={`UploadFileName__Text ${
                uploadStatus === eUploadStatusType.FAILED ? "UploadFileName__Error" : ""
              }`}
            >
              {uploadFile?.name}
            </div>
            <div onClick={handleClearFile} className="UploadFileName__Cancel">
              取消
            </div>
          </Flex>
          {content}
        </CoverFileInfoWrapper>
      );
    }, [
      percent,
      uploadFile,
      uploadStatus,
      confirmText,
      uploadErrorMessage,
      onConfirmHandler,
      fileStatusPosition,
      handleClearFile,
    ]);

    return (
      <Flex vertical gap={12} style={{ position: "relative" }} onClick={onClickContainerHandler}>
        <Upload.Dragger
          ref={uploadRef}
          maxCount={1}
          accept={accept}
          beforeUpload={onBeforeUpload}
          customRequest={customRequest}
          fileList={[]}
          disabled={disabled || uploadStatus === eUploadStatusType.RUNNING}
          onChange={handleUploadData}
        >
          <UploadFileWrapper vertical justify="center" align="center">
            {uploadIcon || (
              <div className="Upload__Icon">
                <UploadIcon />
              </div>
            )}
            <div className="Upload__Desc">{title}</div>
            <div className="Upload__Limit">{describe}</div>
          </UploadFileWrapper>
        </Upload.Dragger>
        {renderFooterFileInfo}
        {renderCoverFileInfo}
      </Flex>
    );
  }
);

UploadFile.displayName = "UploadFile";
