import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";

import { afterEach, beforeEach, describe, expect, it } from "vitest";

import { loadArticleSamples } from "../e2e/sample-flow/sample-loader";

describe("loadArticleSamples", () => {
  let tempDir: string;

  beforeEach(() => {
    tempDir = mkdtempSync(join(tmpdir(), "geo-samples-"));
  });

  afterEach(() => {
    rmSync(tempDir, { recursive: true, force: true });
  });

  it("loads valid samples in filename order and normalizes optional fields", () => {
    writeFileSync(
      join(tempDir, "b-sample.json"),
      JSON.stringify({
        name: "B sample",
        input: {
          body: "第二篇文章正文",
          platform: "media_article",
        },
      }),
    );
    writeFileSync(
      join(tempDir, "a-sample.json"),
      JSON.stringify({
        name: "A sample",
        input: {
          title: "标题",
          body: "第一篇文章正文",
          image_lines: "图一",
          platform: "official_site",
          user_instructions: "保持事实准确",
        },
        expectedHardFailures: ["body_quality"],
        expectedWarnings: ["context_sensitive_terms"],
      }),
    );

    const result = loadArticleSamples(tempDir);

    expect(result.valid.map((sample) => sample.fileName)).toEqual([
      "a-sample.json",
      "b-sample.json",
    ]);
    expect(result.invalid).toEqual([]);
    expect(result.valid[1]).toEqual(
      expect.objectContaining({
        name: "B sample",
        input: expect.objectContaining({
          title: "",
          image_lines: "",
          user_instructions: "",
        }),
        expectedHardFailures: [],
        expectedWarnings: [],
      }),
    );
  });

  it("returns invalid entries for malformed samples without throwing", () => {
    writeFileSync(
      join(tempDir, "empty-body.json"),
      JSON.stringify({
        name: "Empty body",
        input: {
          body: "   ",
          platform: "official_site",
        },
      }),
    );
    writeFileSync(
      join(tempDir, "bad-platform.json"),
      JSON.stringify({
        name: "Bad platform",
        input: {
          body: "正文",
          platform: "unknown",
        },
      }),
    );

    const result = loadArticleSamples(tempDir);

    expect(result.valid).toEqual([]);
    expect(result.invalid).toEqual([
      expect.objectContaining({
        fileName: "bad-platform.json",
        reason:
          "input.platform must be one of official_site, media_article, comparison_review, recommendation_list",
      }),
      expect.objectContaining({
        fileName: "empty-body.json",
        reason: "input.body must be a non-empty string",
      }),
    ]);
  });
});
