import { useUserStore } from "@/stores/modules/user";
import { ElMessage } from "element-plus";

/**
 * 门店/文件相关接口基址（与 src/api/modules/upload.ts 中 httpStoreAlienStore 一致）
 * 若签名接口部署在其它域名，可改为 VITE_API_URL_PLATFORM 等
 */
function getStoreApiBase() {
  return String(import.meta.env.VITE_API_URL_STORE || "").replace(/\/$/, "");
}

/** 从路径或 fileType 解析文件后缀（如 jpg、mp4），用于生成带格式的文件名 */
export function getFileExtension(filePath, fileType) {
  const pathPart = (filePath || "").split("?")[0];
  const lastSegment = pathPart.split("/").pop() || "";
  const dot = lastSegment.lastIndexOf(".");
  if (dot > 0) {
    const ext = lastSegment.slice(dot + 1).toLowerCase();
    if (/^[a-z0-9]+$/i.test(ext) && ext.length <= 5) return ext;
  }
  if (fileType === "video") return "mp4";
  if (fileType === "image") return "jpg";
  return "jpg";
}

/**
 * GET 获取 OSS 直传签名（与 uni 版 1.js 一致）
 * @returns {Promise<Record<string, any>>}
 */
async function fetchOssSignature() {
  const base = getStoreApiBase();
  if (!base) {
    throw new Error("未配置 VITE_API_URL_STORE");
  }
  const userStore = useUserStore();
  const res = await fetch(`${base}/oss/direct/new/signature`, {
    method: "GET",
    headers: {
      Authorization: userStore.token || ""
    },
    credentials: "include"
  });
  if (!res.ok) {
    throw new Error("获取签名失败");
  }
  const body = await res.json();
  const data = body.data ?? body;
  if (!data || !data.host) {
    throw new Error(body.msg || "获取签名失败");
  }
  return data;
}

/**
 * 将入参统一为 File[]
 * @param {File | File[] | FileList} input
 * @returns {File[]}
 */
function normalizeFiles(input) {
  if (input == null) return [];
  if (input instanceof File) return [input];
  if (typeof FileList !== "undefined" && input instanceof FileList) {
    return Array.from(input);
  }
  if (Array.isArray(input)) {
    return input.filter(item => item instanceof File);
  }
  throw new Error("请传入 File、File[] 或 FileList");
}

/**
 * 单个 File 上传到 OSS（POST multipart，字段与 1.js / OSS4 直传一致）
 * @param {Record<string, any>} signRes 签名接口返回
 * @param {File} file
 * @param {string} key 对象 key（含 dir 前缀）
 * @returns {Promise<string>} 文件访问 URL
 */
async function postFileToOss(signRes, file, key) {
  const formData = new FormData();
  formData.append("success_action_status", "200");
  formData.append("policy", signRes.policy);
  formData.append("x-oss-signature", signRes.signature);
  formData.append("x-oss-signature-version", "OSS4-HMAC-SHA256");
  formData.append("x-oss-credential", signRes.x_oss_credential || signRes["x-oss-credential"] || "");
  formData.append("x-oss-date", signRes.x_oss_date || signRes["x-oss-date"] || "");
  formData.append("key", key);
  if (signRes.security_token != null) {
    formData.append("x-oss-security-token", signRes.security_token);
  }
  formData.append("file", file, file.name);

  const res = await fetch(signRes.host, {
    method: "POST",
    body: formData
  });

  if (res.status !== 200) {
    let msg = "上传失败";
    try {
      const t = await res.text();
      if (t) msg = t.slice(0, 200);
    } catch (_) {
      /* ignore */
    }
    throw new Error(msg);
  }

  const text = await res.text();
  if (text && typeof text === "string" && text.trim().startsWith("http")) {
    return text.trim();
  }
  return signRes.host.replace(/\/$/, "") + "/" + key;
}

/**
 * 上传文件到 OSS：先 GET 获取签名，再 POST 到 OSS host（与 src/api/1.js 逻辑一致，Web 使用 File / FormData）
 * @param {File | File[] | FileList} files 浏览器文件对象；支持单个 File、数组或 FileList
 * @param {string} [fileType] 文件类型（如 'image' | 'video'），用于在文件名无后缀时推断格式
 * @param {{ showLoading?: boolean }} [options] showLoading 为 true 时用 ElMessage 提示上传中（非阻塞）
 * @returns {Promise<string[]>} 上传成功后的文件 URL 列表
 */
export async function uploadFilesToOss(files, fileType, options = {}) {
  const { showLoading = false } = options;
  const fileArr = normalizeFiles(files);
  if (fileArr.length === 0) {
    throw new Error("请选择要上传的文件");
  }

  let closeLoading = () => {};
  if (showLoading) {
    const loading = ElMessage({ message: "上传中...", type: "info", duration: 0, showClose: false });
    closeLoading = () => loading.close();
  }

  try {
    const signRes = await fetchOssSignature();
    const uploadedUrls = [];

    for (let i = 0; i < fileArr.length; i++) {
      const file = fileArr[i];
      const filePath = file.name || "";
      const ext = getFileExtension(filePath, fileType);
      const rawBase = filePath.split("/").pop() || "";
      const baseName = rawBase.replace(/\.[^.]+$/, "") || `file_${Date.now()}_${i}`;
      const fileName = baseName.includes(".") ? baseName : `${baseName}.${ext}`;
      const key = (signRes.dir ? signRes.dir.replace(/\/$/, "") + "/" : "") + fileName;

      const url = await postFileToOss(signRes, file, key);
      uploadedUrls.push(url);
    }

    closeLoading();
    return uploadedUrls;
  } catch (e) {
    closeLoading();
    console.error("上传失败", e);
    const msg = e?.message || "上传失败";
    ElMessage.error(msg);
    throw e;
  }
}

/**
 * 上传单个文件，返回 URL 字符串
 * @param {File} file
 * @param {string} [fileType]
 * @param {{ showLoading?: boolean }} [options]
 * @returns {Promise<string>}
 */
export async function uploadFileToOss(file, fileType, options) {
  const urls = await uploadFilesToOss(file, fileType, options);
  return urls[0];
}

/**
 * 兼容 UploadImg 等组件的 api 格式：接收 FormData，返回 { data: { fileUrl } }
 * @param {FormData} formData 包含 file 字段
 * @param {string} [fileType] 文件类型，默认 'image'
 * @param {{ showLoading?: boolean }} [options]
 * @returns {Promise<{ data: { fileUrl: string } }>}
 */
export async function uploadFormDataToOss(formData, fileType = "image", options = {}) {
  const file = formData.get("file");
  if (!file || !(file instanceof File)) {
    throw new Error("请选择要上传的文件");
  }
  const url = await uploadFileToOss(file, fileType, options);
  return { data: { fileUrl: url } };
}
