import OSS from "ali-oss";
import { http } from "@/utils/http";

interface OssCredential {
  accessKeyId: string;
  accessKeySecret: string;
  securityToken: string;
  expiration: string;
  host: string;
  dir: string;
}

export interface UploadResult {
  url: string;
  objectKey: string;
  fileName: string;
  fileSize: number;
  fileExtension: string;
}

let cachedCredential: OssCredential | null = null;
let credentialExpireTime = 0;

/**
 * 获取 OSS 上传凭证（带缓存，过期前60秒自动刷新）
 */
async function getOssCredential(dir: string): Promise<OssCredential> {
  const now = Date.now();
  if (cachedCredential && credentialExpireTime - now > 60000) {
    return cachedCredential;
  }

  const res = await http.request<{
    code: number;
    message: string;
    data: OssCredential;
  }>("get", "/oss/upload-credential", { params: { dir } });

  if (res.code !== 200) {
    throw new Error(res.message || "获取上传凭证失败");
  }

  cachedCredential = res.data;
  credentialExpireTime = new Date(res.data.expiration).getTime();
  return cachedCredential;
}

/**
 * 前端直传文件到 OSS
 *
 * @param file       待上传文件
 * @param dir        上传目录（如 "shop-archive/contract"）
 * @param onProgress 上传进度回调 (percent: number) => void
 * @returns          上传结果（URL、objectKey等）
 */
export async function uploadToOss(
  file: File,
  dir: string = "shop-archive",
  onProgress?: (percent: number) => void
): Promise<UploadResult> {
  const credential = await getOssCredential(dir);

  // 从 host 中提取 region 和 bucket
  const hostMatch = credential.host.match(
    /\/\/(.+?)\.(oss-.+?)\.aliyuncs\.com/
  );
  const bucket = hostMatch?.[1] || "";
  const region = hostMatch?.[2] || "oss-cn-hangzhou";

  const client = new OSS({
    region,
    accessKeyId: credential.accessKeyId,
    accessKeySecret: credential.accessKeySecret,
    stsToken: credential.securityToken,
    bucket,
    endpoint: credential.host
  });

  // 生成 objectKey：dir/yyyyMMdd/uuid.ext
  const ext = file.name.includes(".")
    ? file.name.substring(file.name.lastIndexOf("."))
    : "";
  const dateStr = new Date()
    .toISOString()
    .slice(0, 10)
    .replace(/-/g, "");
  const uuid = Math.random().toString(36).substring(2, 15) + Date.now().toString(36);
  const objectKey = `${credential.dir}${dateStr}/${uuid}${ext}`;

  await client.put(objectKey, file, {
    progress: (p: number) => onProgress?.(Math.round(p * 100))
  });

  // 拼接完整访问URL
  const url = `${credential.host.replace(/\/$/, "")}/${objectKey}`;

  return {
    url,
    objectKey,
    fileName: file.name,
    fileSize: file.size,
    fileExtension: ext.replace(".", "")
  };
}
