import { request } from '@umijs/max';
import { Button, Image, Space, Upload, message } from 'antd';
import type { UploadProps } from 'antd';
import React, { useState } from 'react';

type SingleImageUploadProps = {
    value?: string;
    onChange?: (value: string) => void;
    disabled?: boolean;
    onUploadingChange?: (uploading: boolean) => void;
};

/** 使用字符串地址作为表单值，让上传控件参与 Form 必填校验。 */
const SingleImageUpload: React.FC<SingleImageUploadProps> = ({
    value, onChange, disabled, onUploadingChange,
}) => {
    const [uploading, setUploading] = useState(false);

    const beforeUpload: UploadProps['beforeUpload'] = (file) => {
        if (!['image/jpeg', 'image/png'].includes(file.type)) {
            message.error('请上传 JPG 或 PNG 图片');
            return Upload.LIST_IGNORE;
        }
        // 启动页图片在 App 冷启动时下载，限制 2M 以缩短弱网下的加载时间
        if (file.size > 2 * 1024 * 1024) {
            message.error('图片不能超过 2M');
            return Upload.LIST_IGNORE;
        }
        return true;
    };

    const upload: UploadProps['customRequest'] = async (options) => {
        setUploading(true);
        onUploadingChange?.(true);
        try {
            const data = new FormData();
            data.append('file', options.file as File);
            // 与项目其他上传一致，必须声明 form，否则 FormData 会被序列化为 JSON 导致上传失败。
            const response = await request('/upload/image', { method: 'POST', data, requestType: 'form' });
            const url = response.data?.url;
            if (!url) {
                throw new Error('服务器未返回图片地址');
            }
            onChange?.(url);
            options.onSuccess?.(response);
        } catch (error) {
            console.error('[启动页图片上传失败]', error);
            message.error((error as Error).message || '图片上传失败');
            options.onError?.(error as Error);
        } finally {
            setUploading(false);
            onUploadingChange?.(false);
        }
    };

    return (
        <Space direction="vertical">
            {value && <Image src={value} width={120} style={{ maxHeight: 220, objectFit: 'contain' }} />}
            <Space>
                <Upload accept="image/png,image/jpeg" showUploadList={false}
                    disabled={disabled || uploading} beforeUpload={beforeUpload} customRequest={upload}>
                    <Button disabled={disabled} loading={uploading}>{value ? '更换图片' : '上传图片'}</Button>
                </Upload>
                {value && <Button disabled={disabled || uploading} onClick={() => onChange?.('')}>移除</Button>}
            </Space>
        </Space>
    );
};

export default SingleImageUpload;
