import { useEffect, useRef, useState } from 'react';
import { Button, Image, Space, Typography, Upload, message } from 'antd';
import { UploadOutlined, DeleteOutlined } from '@ant-design/icons';
import type { UploadProps } from 'antd';
import { uploadFileToOss, type OssMediaType } from '../lib/upload';

type Props = {
  value?: string[];
  onChange?: (urls: string[]) => void;
  bizType: string;
  mediaType?: OssMediaType;
  /** 最多张数；不传则不限制 */
  maxCount?: number;
  tip?: string;
  accept?: string;
};

function normalizeUrls(value?: string[]) {
  return (value ?? []).map((u) => String(u || '').trim()).filter(Boolean);
}

/**
 * 多图批量上传（一次可选多张），用于套餐图 / 环境照 / 商品详情图等。
 * Form.Item 直接绑定 string[]。
 */
export default function MultiImageUpload({
  value,
  onChange,
  bizType,
  mediaType = 'IMAGE',
  maxCount,
  tip,
  accept = 'image/*',
}: Props) {
  const urls = normalizeUrls(value);
  const urlsRef = useRef(urls);
  const onChangeRef = useRef(onChange);
  const [uploading, setUploading] = useState(false);
  const batchBuf = useRef<File[]>([]);
  const batchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const uploadChain = useRef(Promise.resolve());

  useEffect(() => {
    urlsRef.current = urls;
  }, [urls]);

  useEffect(() => {
    onChangeRef.current = onChange;
  }, [onChange]);

  useEffect(() => {
    return () => {
      if (batchTimer.current) clearTimeout(batchTimer.current);
    };
  }, []);

  const remaining = maxCount != null ? Math.max(0, maxCount - urls.length) : Number.POSITIVE_INFINITY;
  const canAdd = remaining > 0;

  async function uploadBatch(files: File[]) {
    const current = urlsRef.current;
    const room = maxCount != null ? Math.max(0, maxCount - current.length) : files.length;
    const picked = files.slice(0, room);
    if (!picked.length) {
      message.warning(maxCount != null ? `最多 ${maxCount} 张` : '无法上传');
      return;
    }
    if (files.length > picked.length) {
      message.warning(`已达上限，仅上传前 ${picked.length} 张`);
    }

    setUploading(true);
    const appended: string[] = [];
    let fail = 0;
    try {
      for (const file of picked) {
        try {
          const result = await uploadFileToOss(file, { bizType, mediaType });
          appended.push(result.url);
        } catch {
          fail += 1;
        }
      }
      if (appended.length) {
        // 始终基于最新列表追加，避免并行上传互相覆盖
        const next = [...urlsRef.current, ...appended];
        urlsRef.current = next;
        onChangeRef.current?.(next);
        message.success(`成功上传 ${appended.length} 张${fail ? `，失败 ${fail} 张` : ''}`);
      } else if (fail) {
        message.error('上传失败');
      }
    } finally {
      setUploading(false);
    }
  }

  function enqueueUploadBatch(files: File[]) {
    uploadChain.current = uploadChain.current
      .then(() => uploadBatch(files))
      .catch(() => undefined);
  }

  function flushBatch() {
    if (batchTimer.current) {
      clearTimeout(batchTimer.current);
      batchTimer.current = null;
    }
    if (!batchBuf.current.length) return;
    const files = [...batchBuf.current];
    batchBuf.current = [];
    enqueueUploadBatch(files);
  }

  const beforeUpload: UploadProps['beforeUpload'] = (file) => {
    batchBuf.current.push(file as File);
    // 多选时 beforeUpload 可能逐文件触发；短防抖合并成一次批量
    if (batchTimer.current) clearTimeout(batchTimer.current);
    batchTimer.current = setTimeout(() => {
      flushBatch();
    }, 80);
    return false;
  };

  function removeAt(index: number) {
    const next = urlsRef.current.filter((_, i) => i !== index);
    urlsRef.current = next;
    onChangeRef.current?.(next);
  }

  return (
    <Space direction="vertical" style={{ width: '100%' }} size="middle">
      <Typography.Text type="secondary">
        {tip ??
          (maxCount != null
            ? `最多 ${maxCount} 张，支持一次选择多张批量上传`
            : '支持一次选择多张批量上传')}
        {maxCount != null ? `（已选 ${urls.length}/${maxCount}）` : urls.length ? `（已选 ${urls.length}）` : ''}
      </Typography.Text>

      {urls.length > 0 ? (
        <Image.PreviewGroup>
          <Space wrap size={12}>
            {urls.map((url, index) => (
              <div key={`${url}-${index}`} style={{ position: 'relative', width: 96 }}>
                <Image
                  src={url}
                  width={96}
                  height={96}
                  style={{ objectFit: 'cover', borderRadius: 6, border: '1px solid #f0f0f0' }}
                />
                <Button
                  type="text"
                  danger
                  size="small"
                  icon={<DeleteOutlined />}
                  onClick={() => removeAt(index)}
                  style={{
                    position: 'absolute',
                    top: 0,
                    right: 0,
                    background: 'rgba(255,255,255,0.85)',
                  }}
                />
              </div>
            ))}
          </Space>
        </Image.PreviewGroup>
      ) : null}

      <Upload
        accept={accept}
        multiple
        showUploadList={false}
        beforeUpload={beforeUpload}
        disabled={uploading || !canAdd}
      >
        <Button icon={<UploadOutlined />} loading={uploading} disabled={!canAdd}>
          {canAdd ? '批量上传图片' : '已达上限'}
        </Button>
      </Upload>
    </Space>
  );
}
