#!/usr/bin/env node
"use strict";

const assert = require("node:assert/strict");
const fs = require("node:fs");
const os = require("node:os");
const path = require("node:path");
const { spawnSync } = require("node:child_process");

const repoRoot = path.resolve(__dirname, "..");
const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), "mnote-convex-export-plan-"));
const fixturePath = path.join(tmpRoot, "fixture.json");
const outRoot = path.join(tmpRoot, "local-workspace");
const manifestPath = path.join(tmpRoot, "migration-manifest.json");
const conflictPath = path.join(tmpRoot, "conflicts.json");

const fixture = {
  workspace: {
    id: "ws_legacy_plan",
    name: "迁移计划空间",
    ownerId: "user_plan",
  },
  documents: [
    {
      id: "doc_root",
      title: "Project",
      parent_id: null,
      content: "# Project\n\n导出正文\n",
      wide_layout: true,
    },
  ],
  mediaAssets: [
    {
      id: "asset_logo",
      fileName: "logo.txt",
      documentId: "doc_root",
      content: "LOGO-NEW",
    },
  ],
  aiSessions: [],
};

function runExport(args, expectedStatus = 0) {
  const result = spawnSync(
    process.execPath,
    [path.join(repoRoot, "scripts", "export-convex-workspace-to-local.js"), ...args],
    { cwd: repoRoot, encoding: "utf8" },
  );
  assert.equal(result.status, expectedStatus, result.stderr || result.stdout);
  return result;
}

try {
  fs.writeFileSync(fixturePath, JSON.stringify(fixture, null, 2), "utf8");

  runExport([
    "--fixture",
    fixturePath,
    "--out",
    outRoot,
    "--dry-run",
    "--manifest",
    manifestPath,
    "--conflict-report",
    conflictPath,
  ]);
  assert.equal(fs.existsSync(path.join(outRoot, "pages", "Project.md")), false, "dry run 不应写入页面文件");
  const dryRunManifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
  assert.equal(dryRunManifest.dryRun, true);
  assert.equal(dryRunManifest.operations.some((item) => item.action === "create" && item.relativePath === "pages/Project.md"), true);

  fs.mkdirSync(path.join(outRoot, "pages"), { recursive: true });
  fs.writeFileSync(path.join(outRoot, "pages", "Project.md"), "原有内容\n", "utf8");
  const conflict = runExport([
    "--fixture",
    fixturePath,
    "--out",
    outRoot,
    "--manifest",
    manifestPath,
    "--conflict-report",
    conflictPath,
  ], 2);
  assert.match(conflict.stderr + conflict.stdout, /migration_conflict/);
  assert.equal(fs.readFileSync(path.join(outRoot, "pages", "Project.md"), "utf8"), "原有内容\n");
  const conflictReport = JSON.parse(fs.readFileSync(conflictPath, "utf8"));
  assert.equal(conflictReport.conflicts.some((item) => item.relativePath === "pages/Project.md"), true);

  fs.rmSync(outRoot, { recursive: true, force: true });
  runExport([
    "--fixture",
    fixturePath,
    "--out",
    outRoot,
    "--manifest",
    manifestPath,
  ]);
  assert.match(fs.readFileSync(path.join(outRoot, "pages", "Project.md"), "utf8"), /导出正文/);
  assert.equal(fs.existsSync(path.join(outRoot, ".mnote", "migration-manifest.json")), true);

  runExport(["--rollback", path.join(outRoot, ".mnote", "migration-manifest.json")]);
  assert.equal(fs.existsSync(path.join(outRoot, "pages", "Project.md")), false, "rollback 应删除本次新增页面");
  assert.equal(fs.existsSync(path.join(outRoot, "pages", "Project.assets", "logo.txt")), false, "rollback 应删除本次新增资源");

  console.log(JSON.stringify({ ok: true, smoke: "task455-convex-export-plan-rollback" }, null, 2));
} finally {
  fs.rmSync(tmpRoot, { recursive: true, force: true });
}
