import { useEffect, useRef, useState } from 'react';
import { uploadFileToOss, type OssMediaType } from '../lib/upload';
import { enqueueUpload } from '../lib/upload-lock';
import { formatChooseImageFailMessage } from '@dukang/weixin-sdk';
import { isWechatEnv, weixinSdk } from '../lib/weixin';
import { toastError, toastSuccess } from '../lib/toast';

type Props = {
  value?: string[];
  onChange?: (urls: string[]) => void;
  bizType: string;
  mediaType?: OssMediaType;
  maxCount?: number;
  disabled?: boolean;
  label?: string;
  /** 系统文件选择器的 accept，默认仅图片 */
  accept?: string;
  /** 计量单位文案，如「张」「个」 */
  unit?: string;
};

function isCancelError(msg: string): boolean {
  return /cancel|取消/i.test(msg);
}

function isPdf(url: string): boolean {
  return /\.pdf(\?|$)/i.test(url);
}

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

/** 合伙人端多图批量上传（微信相册可多选） */
export default function MultiOssUploadField({
  value,
  onChange,
  bizType,
  mediaType = 'IMAGE',
  maxCount = 20,
  disabled,
  label,
  accept = 'image/*',
  unit = '张',
}: Props) {
  const inputRef = useRef<HTMLInputElement>(null);
  const pickingRef = useRef(false);
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState('');

  const urls = normalizeUrls(value);
  const urlsRef = useRef(urls);
  const onChangeRef = useRef(onChange);
  const remaining = Math.max(0, maxCount - urls.length);
  const inWechat = isWechatEnv();

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

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

  useEffect(() => {
    if (!inWechat) return;
    void weixinSdk.init().catch(() => {});
  }, [inWechat]);

  function showUploadError(text: string) {
    setError(text);
    toastError(text);
  }

  async function uploadFiles(files: File[]) {
    const current = urlsRef.current;
    const room = Math.max(0, maxCount - current.length);
    const picked = files.slice(0, room);
    if (!picked.length) {
      showUploadError(`最多 ${maxCount} ${unit}`);
      return;
    }
    setUploading(true);
    setError('');
    const appended: string[] = [];
    try {
      for (const file of picked) {
        if (!file.size) continue;
        const result = await enqueueUpload(() => uploadFileToOss(file, { bizType, mediaType }));
        appended.push(result.url);
      }
      if (appended.length) {
        const next = [...urlsRef.current, ...appended];
        urlsRef.current = next;
        onChangeRef.current?.(next);
        toastSuccess(`已上传 ${appended.length} ${unit}`);
      }
    } catch (e) {
      showUploadError(e instanceof Error ? e.message : '上传失败');
    } finally {
      setUploading(false);
      if (inputRef.current) inputRef.current.value = '';
    }
  }

  async function pickWechat() {
    if (pickingRef.current || uploading || disabled || remaining <= 0) return;
    pickingRef.current = true;
    setError('');
    try {
      await weixinSdk.init();
      const files = await weixinSdk.chooseImages({
        count: Math.min(remaining, 9),
        sourceType: ['album', 'camera'],
      });
      if (!files?.length) return;
      await uploadFiles(files);
    } catch (e) {
      const msg = e instanceof Error ? e.message : '无法打开相册';
      if (isCancelError(msg)) return;
      const formatted = formatChooseImageFailMessage(msg) || msg;
      showUploadError(formatted);
      inputRef.current?.click();
    } finally {
      pickingRef.current = false;
    }
  }

  function removeAt(index: number) {
    if (disabled) return;
    onChange?.(urls.filter((_, i) => i !== index));
  }

  return (
    <div className="partner-oss-upload">
      <input
        ref={inputRef}
        type="file"
        accept={accept}
        multiple
        className="partner-oss-upload-input"
        disabled={disabled || uploading || remaining <= 0}
        onChange={(e) => {
          const list = Array.from(e.target.files ?? []);
          if (list.length) void uploadFiles(list);
        }}
      />

      {urls.length > 0 ? (
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginBottom: 8 }}>
          {urls.map((url, index) => (
            <div key={`${url}-${index}`} style={{ position: 'relative', width: 88, height: 88 }}>
              {isPdf(url) ? (
                <a
                  href={url}
                  target="_blank"
                  rel="noreferrer"
                  style={{
                    display: 'flex',
                    width: 88,
                    height: 88,
                    flexDirection: 'column',
                    alignItems: 'center',
                    justifyContent: 'center',
                    gap: 2,
                    borderRadius: 8,
                    border: '1px solid rgba(0,0,0,0.08)',
                    background: '#f7f7f7',
                    fontSize: 12,
                  }}
                >
                  <span className="material-symbols-outlined text-primary" style={{ fontSize: 26 }}>
                    description
                  </span>
                  <span className="text-muted">PDF</span>
                </a>
              ) : (
                <img
                  src={url}
                  alt=""
                  style={{ width: 88, height: 88, objectFit: 'cover', borderRadius: 8 }}
                />
              )}
              {!disabled ? (
                <button
                  type="button"
                  className="partner-packages-remove"
                  style={{
                    position: 'absolute',
                    top: 2,
                    right: 2,
                    margin: 0,
                    padding: '2px 6px',
                    fontSize: 12,
                    background: 'rgba(0,0,0,0.55)',
                    color: '#fff',
                    borderRadius: 4,
                  }}
                  onClick={() => removeAt(index)}
                >
                  删
                </button>
              ) : null}
            </div>
          ))}
        </div>
      ) : null}

      <button
        type="button"
        className="partner-upload-dashed partner-upload-dashed--compact"
        disabled={disabled || uploading || remaining <= 0}
        onClick={() => {
          if (inWechat) void pickWechat();
          else inputRef.current?.click();
        }}
      >
        <span className="material-symbols-outlined text-primary" style={{ fontSize: 28 }}>
          {uploading ? 'hourglass_top' : 'add_a_photo'}
        </span>
        <span className="text-primary" style={{ fontWeight: 500 }}>
          {uploading
            ? '上传中…'
            : remaining <= 0
              ? `已达上限 ${maxCount}${unit}`
              : label ?? `批量上传（${urls.length}/${maxCount}）`}
        </span>
      </button>
      {error ? (
        <p className="partner-form-error" role="alert">
          {error}
        </p>
      ) : null}
    </div>
  );
}
