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

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

import type { OptimizedArticle, QaReport } from "../../domain/types";
import { createLocalExportStore, createR2ExportStore } from "../export-store";

const article: OptimizedArticle = {
  title: "Example",
  summary: "Summary",
  body_markdown: "Body",
  image_suggestions: [],
  changed_sections: [],
  requires_user_confirmation: [],
  revision: 1,
};

const report: QaReport = {
  overall_status: "pass",
  checks: [],
};

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

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

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

  test("local store writes and reads exports", async () => {
    const store = createLocalExportStore(tempDir);

    const paths = await store.writeJobExports({
      jobId: "job_123",
      article,
      qaReport: report,
    });

    expect(paths.markdown).toContain("optimized.md");
    const file = await store.readJobExport("job_123", "optimized.md");
    expect(await file?.text()).toContain("# Example");
  });

  test("R2 store writes private export objects through binding", async () => {
    const put = vi.fn().mockResolvedValue(undefined);
    const bucket = { put } as unknown as R2Bucket;
    const store = createR2ExportStore(bucket);

    const paths = await store.writeJobExports({
      jobId: "job_123",
      article,
      qaReport: report,
    });

    expect(paths.markdown).toBe("r2://exports/job_123/optimized.md");
    expect(put).toHaveBeenCalledWith(
      "exports/job_123/optimized.md",
      expect.any(String),
      expect.objectContaining({
        httpMetadata: { contentType: "text/markdown; charset=utf-8" },
      }),
    );
  });
});
