import fs from "fs";
import path from "path";
import { spawnSync } from "child_process";
import { MODEL_CONVERTER } from "../../paths.js";

// 格式映射
const FORMAT_EXT = {
  collada: ".dae", stp: ".stp", obj: ".obj", objnomtl: ".obj",
  stl: ".stl", stlb: ".stl", ply: ".ply", plyb: ".ply", "3ds": ".3ds",
  gltf2: ".gltf", glb2: ".glb",
  assbin: ".assbin", assxml: ".assxml", x3d: ".x3d",
  fbx: ".fbx", fbxa: ".fbx", "3mf": ".3mf", pbrt: ".pbrt", assjson: ".json"
};

// 缓存
let importExts = null;
let exportFormats = null;

// 获取支持的导入格式
export const getImportExtensions = () => {
  if (!importExts) {
    const r = spawnSync(MODEL_CONVERTER, ["listext"], { encoding: "utf8" });
    if (!r.stdout) throw new Error("无法获取支持的导入格式，请检查 model_converter.exe 是否存在");
    importExts = r.stdout.trim().split(";").map(e => e.replace("*", "").toLowerCase());
  }
  return importExts;
};

// 获取支持的导出格式
export const getExportFormats = () => {
  if (!exportFormats) {
    const r = spawnSync(MODEL_CONVERTER, ["listexport"], { encoding: "utf8" });
    if (!r.stdout) throw new Error("无法获取支持的导出格式，请检查 model_converter.exe 是否存在");
    exportFormats = r.stdout.trim().split(/\r?\n/).filter(Boolean);
  }
  return exportFormats;
};

// 转换文件
export const convert = async (inputFile, outputFile, format, cwd = process.cwd()) => {
  const r = spawnSync(MODEL_CONVERTER, ["export", inputFile, outputFile, `-f${format}`], { encoding: "utf8", cwd });
  if (r.status !== 0) throw new Error(r.stderr || r.stdout || "转换失败");
  return outputFile;
};

// 获取输出文件扩展名
const getOutputExt = (format) => {
  return FORMAT_EXT[format] || "." + format;
};

// 处理单个文件
export const processFile = async (file, config) => {
  const cwd = process.cwd();
  const { dir, name } = path.parse(file);
  const outputExt = getOutputExt(config.outputFormat);
  const outputFile = path.join(dir || "", `${name}${outputExt}`);
  const absolutePath = path.join(cwd, file);

  if (!fs.existsSync(absolutePath)) {
    return { ok: false, file, reason: "文件不存在" };
  }

  await convert(file, outputFile, config.outputFormat, cwd);
  return { ok: true, file, output: outputFile };
};
