import assert from "node:assert/strict";
import fs from "node:fs/promises";
import path from "node:path";

const baseUrl = process.env.CMS_BASE_URL || "http://127.0.0.1:8793";
const apiKey = process.env.CMS_API_KEY;
if (!apiKey) throw new Error("CMS_API_KEY 未配置");

const headers = { Authorization: `Bearer ${apiKey}` };
const jsonHeaders = { ...headers, "Content-Type": "application/json" };

async function request(route, options = {}) {
  const response = await fetch(`${baseUrl}/api/cms${route}`, {
    ...options,
    headers: { ...headers, ...options.headers },
  });
  const payload = await response.json().catch(() => ({}));
  if (!response.ok) throw new Error(`${options.method || "GET"} ${route} 返回 ${response.status}：${payload.error || "未知错误"}`);
  return payload;
}

const categories = await request("/categories");
for (const required of ["学情指南", "学习方法"]) assert.ok(categories.categories.includes(required));

const image = await fs.readFile(path.resolve("pic/主页大图素材-1.png"));
const uploadedImage = await request("/uploads", {
  method: "POST",
  headers: jsonHeaders,
  body: JSON.stringify({ dataUrl: `data:image/png;base64,${image.toString("base64")}` }),
});

const markdownFile = path.resolve("tests/fixtures/import-test.md");
let markdown = await fs.readFile(markdownFile, "utf8");
const heading = markdown.match(/^#\s+(.+)$/m);
assert.ok(heading?.index !== undefined);
const markdownTitle = heading[1].trim();
markdown = `${markdown.slice(0, heading.index)}${markdown.slice(heading.index + heading[0].length)}`
  .trim()
  .replace("{{TEST_IMAGE_URL}}", uploadedImage.url);

const markdownImport = await request("/articles", {
  method: "POST",
  headers: jsonHeaders,
  body: JSON.stringify({ title: markdownTitle, category: "学情指南", body: markdown }),
});

const docxFile = path.resolve("tests/fixtures/import-test.docx");
const docx = await fs.readFile(docxFile);
const wordImport = await request("/imports/word", {
  method: "POST",
  headers: jsonHeaders,
  body: JSON.stringify({
    fileName: path.basename(docxFile),
    category: "学习方法",
    dataUrl: `data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,${docx.toString("base64")}`,
  }),
});

const markdownArticle = await request(`/articles/${markdownImport.slug}`);
const wordArticle = await request(`/articles/${wordImport.slug}`);

assert.equal(markdownImport.publishStatus, "new-draft");
assert.equal(markdownArticle.title, markdownTitle);
assert.equal(markdownArticle.category, "学情指南");
assert.match(markdownArticle.body, /QIYOUXUE-PRODUCTION-IMPORT-20260812-MARKDOWN/);
assert.match(markdownArticle.body, new RegExp(uploadedImage.url.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")));

assert.equal(wordImport.publishStatus, "new-draft");
assert.equal(wordImport.title, "家长如何准备一次学情沟通");
assert.equal(wordImport.imageCount, 1);
assert.equal(wordArticle.category, "学习方法");
assert.match(wordArticle.body, /QIYOUXUE-PRODUCTION-IMPORT-20260812-WORD/);
assert.doesNotMatch(wordArticle.body, /^#\s+家长如何准备一次学情沟通/m);

const wordImageUrl = wordArticle.body.match(/!\[[^\]]*\]\((\/uploads\/[^)]+)\)/)?.[1];
assert.ok(wordImageUrl);
for (const imageUrl of [uploadedImage.url, wordImageUrl]) {
  const response = await fetch(`${baseUrl}${imageUrl}`);
  assert.equal(response.status, 200);
  assert.equal(response.headers.get("content-type"), "image/png");
  assert.deepEqual(Buffer.from(await response.arrayBuffer()), image);
}

console.log(JSON.stringify({
  markdown: { slug: markdownImport.slug, title: markdownArticle.title, imageUrl: uploadedImage.url, publishStatus: markdownImport.publishStatus },
  word: { slug: wordImport.slug, title: wordImport.title, imageUrl: wordImageUrl, imageCount: wordImport.imageCount, publishStatus: wordImport.publishStatus, warnings: wordImport.warnings },
}, null, 2));
