#!/usr/bin/env node

const fs = require("node:fs");
const path = require("node:path");
const process = require("node:process");
const ci = require("miniprogram-ci");
const { resolveVersion } = require("./resolve-version.cjs");
const { resolveUploadDesc } = require("./resolve-upload-desc.cjs");

function requireEnvironment(name) {
  const value = process.env[name];
  if (!value) {
    throw new Error(`${name} is required.`);
  }
  return value;
}

async function main() {
  const projectPath = process.cwd();
  const repoRoot = path.resolve(projectPath, "..");
  const privateKeyPath = path.resolve(
    requireEnvironment("WECHAT_CI_PRIVATE_KEY_PATH"),
  );
  const appid = requireEnvironment("MINIAPP_APPID");
  const robot = Number.parseInt(process.env.MINIAPP_ROBOT ?? "1", 10);
  const versionLabel = requireEnvironment("MINIAPP_VERSION_LABEL");
  const version = resolveVersion(projectPath);
  const resultPath = path.resolve(
    process.env.MINIAPP_UPLOAD_RESULT ||
      path.join(projectPath, "ci-artifacts", "upload-result.json"),
  );

  if (!fs.existsSync(path.join(projectPath, "project.config.json"))) {
    throw new Error("The working directory must contain project.config.json.");
  }
  if (!fs.existsSync(privateKeyPath)) {
    throw new Error("The WeChat code-upload key file does not exist.");
  }
  if (!Number.isInteger(robot) || robot < 1 || robot > 30) {
    throw new Error("MINIAPP_ROBOT must be an integer from 1 to 30.");
  }

  const project = new ci.Project({
    appid,
    type: "miniProgram",
    projectPath,
    privateKeyPath,
    ignores: ["node_modules/**/*", ".git/**/*", "ci-artifacts/**/*"],
  });

  const desc = resolveUploadDesc({
    repoRoot,
    versionLabel,
    maxLength: Number.parseInt(process.env.MINIAPP_UPLOAD_DESC_MAX || "100", 10),
    maxItems: Number.parseInt(process.env.MINIAPP_UPLOAD_DESC_ITEMS || "3", 10),
  });
  console.log(`Uploading Mini Program version=${version} robot=${robot}`);
  console.log(`Upload remark: ${desc}`);

  const uploadResult = await ci.upload({
    project,
    version,
    desc,
    robot,
    setting: {
      useProjectConfig: true,
      es6: true,
      es7: true,
      enhance: true,
      minify: true,
      autoPrefixWXSS: true,
    },
    onProgressUpdate: (progress) => {
      if (typeof progress === "string") {
        console.log(progress);
      }
    },
  });

  fs.mkdirSync(path.dirname(resultPath), { recursive: true });
  fs.writeFileSync(
    resultPath,
    `${JSON.stringify(
      {
        appid,
        version,
        robot,
        desc,
        versionLabel,
        uploadedAt: new Date().toISOString(),
        result: uploadResult,
      },
      null,
      2,
    )}\n`,
  );

  console.log(`Upload succeeded: version ${version}`);
  console.log(`Upload result saved: ${resultPath}`);
  console.log(
    "If this robot upload is already selected as 体验版 in WeChat admin, it becomes the new experience version automatically. Otherwise open 版本管理 → 开发版本 → 选为体验版 once.",
  );
}

main().catch((error) => {
  console.error(`Mini Program upload failed: ${error.message}`);
  process.exitCode = 1;
});
