import { PlusOutlined } from '@ant-design/icons';
import type { GetProp, UploadFile, UploadProps } from 'antd';
import { Image, message, Spin, Upload } from 'antd';
import React, { useCallback, useEffect, useState } from 'react';
import { uploadImage } from '@/services/infra/media';

type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];

const getBase64 = (file: FileType): Promise<string> =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = (error) => reject(error);
  });

// accept: .doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document  image/*,.pdf
const UploadImages: React.FC<{
  value?: string;
  onChange?: (value: string | string[]) => void;
  multiple?: boolean;
  accept?: string;
  maxCount?: number;
}> = (props) => {
  const {
    value,
    multiple = false,
    maxCount = 1,
    accept = 'image/png,image/jpeg',
    onChange,
  } = props;
  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewImage, setPreviewImage] = useState('');
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [uploading, setUploading] = useState(false);
  useEffect(() => {
    if (value) {
      console.log(value.split(','));
      const list = value.split(',').map((item, index) => ({
        uid: index.toString(),
        url: item,
        thumbUrl: item,
        status: 'done',
        name: item,
      }));
      setFileList(list as UploadFile[]);
    } else {
      setFileList([]);
    }
  }, [value]);
  const beforeUpload = (file: FileType) => {
    const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
    if (!isJpgOrPng) {
      message.error('仅支持.jpg .png 格式!');
    }
    // const isLt2M = file.size / 1024 / 1024 < 2;
    // if (!isLt2M) {
    //   message.error('Image must smaller than 2MB!');
    // }
    return isJpgOrPng;
  };
  const handlePreview = async (file: UploadFile) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj as FileType);
    }

    setPreviewImage(file.url || (file.preview as string));
    setPreviewOpen(true);
  };

  const handleRemove = (file: UploadFile): boolean => {
    const newFileList = fileList.filter((item) => item.uid !== file.uid);
    const newUrl = newFileList.map((item) => item.url) as string[];
    onChange?.(newUrl.join(','));
    return true;
  };

  const uploadButton = (
    <button style={{ border: 0, background: 'none' }} type="button">
      <PlusOutlined />
      <div style={{ marginTop: 8 }}>Upload</div>
    </button>
  );
  const uploadFile = useCallback(async (file: File): Promise<string> => {
    return new Promise((resolve, reject) => {
      const formData = new FormData();
      formData.append('file', file);
      try {
        uploadImage(formData).then((res) => {
          if (res) {
            resolve(res);
          } else {
            reject(new Error('上传失败：未返回有效的URL'));
          }
        });
      } catch (error) {
        reject(error);
      }
    });
  }, []);
  const handleLoadImage: UploadProps['customRequest'] = async (option) => {
    const { file, onSuccess, onError, onProgress } = option;

    try {
      setUploading(true);
      // 模拟进度更新
      onProgress?.({ percent: 10 });
      // 调用后端接口
      const url = await uploadFile(file as File);
      onProgress?.({ percent: 100 });
      if (url) {
        if (maxCount === 1) {
          onChange?.(url);
          onSuccess?.({ url });
        } else {
          const res = value?.split(',') || [];
          console.log([...res, url].join(','));
          onChange?.([...res, url].join(','));
        }

        message.success('上传成功');
      } else {
        setUploading(false);
        throw new Error('上传失败');
      }
    } catch (error) {
      setUploading(false);
      message.error(`上传失败: ${(error as Error).message}`);
    } finally {
      console.log('finally');
      setUploading(false);
    }
  };
  return (
    <Spin spinning={uploading}>
      {uploading}
      <>
        <Upload
          listType="picture-card"
          fileList={fileList}
          onPreview={handlePreview}
          onRemove={handleRemove}
          beforeUpload={beforeUpload}
          customRequest={handleLoadImage}
          multiple={multiple}
          accept={accept}
        >
          {fileList.length >= maxCount ? null : uploadButton}
        </Upload>
        {previewImage && (
          <Image
            wrapperStyle={{ display: 'none' }}
            preview={{
              visible: previewOpen,
              onVisibleChange: (visible) => setPreviewOpen(visible),
              afterOpenChange: (visible) => !visible && setPreviewImage(''),
            }}
            src={previewImage}
          />
        )}
      </>
    </Spin>
  );
};

export default UploadImages;
