import { describe, expect, it, vi } from "vitest";
import { mkdirSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";

import { exportResultCopy, runExportFlow } from "../../apps/web/src/export-flow.js";

function writeEvidence(file: string, value: unknown) {
  const root = process.env.DADA_EVIDENCE_DIR_LATEST_EXPORTS;
  if (!root) return;
  const directory = resolve(root, "TDD-WP2-EXP-001-result-matrix");
  mkdirSync(directory, { recursive: true });
  writeFileSync(resolve(directory, file), `${JSON.stringify(value, null, 2)}\n`);
}

describe("TDD-WP2-EXP-001-result-matrix", () => {
  it("uses the exact same Blob for download and latest persistence", async () => {
    const blob = new Blob(["same-export"], { type: "image/png" });
    const download = vi.fn(async (_value: Blob) => undefined);
    const persist = vi.fn(async (_value: Blob) => undefined);
    const result = await runExportFlow({ compose: async () => blob, download, persist });

    expect(result.status).toBe("downloaded_and_saved");
    expect(download).toHaveBeenCalledWith(blob);
    expect(persist).toHaveBeenCalledWith(blob);
    expect(download.mock.calls[0][0]).toBe(persist.mock.calls[0][0]);
    expect(exportResultCopy[result.status]).toBe("已下载并保存为最新成品");
  });

  it("preserves the composed Blob for retry when browser download fails", async () => {
    const blob = new Blob(["retry-export"], { type: "image/jpeg" });
    const persist = vi.fn();
    const result = await runExportFlow({
      compose: async () => blob,
      download: async () => { throw new Error("download_failed"); },
      persist,
    });

    expect(result.status).toBe("download_failed");
    expect(result.blob).toBe(blob);
    expect(persist).not.toHaveBeenCalled();
    expect(exportResultCopy[result.status]).toBe("浏览器下载失败，可重新下载同一次合成结果");
  });

  it("does not turn a successful local download into a false double success", async () => {
    const result = await runExportFlow({
      compose: async () => new Blob(["local-only"], { type: "image/png" }),
      download: async () => undefined,
      persist: async () => { throw new Error("latest_failed"); },
    });

    expect(result.status).toBe("downloaded_not_saved");
    expect(exportResultCopy[result.status]).toBe("文件已下载，但未保存为最新成品");
  });

  it("does not download or persist after composition failure", async () => {
    const download = vi.fn();
    const persist = vi.fn();
    const result = await runExportFlow({
      compose: async () => { throw new Error("composition_failed"); },
      download,
      persist,
    });

    expect(result).toEqual({ blob: null, status: "composition_failed" });
    expect(download).not.toHaveBeenCalled();
    expect(persist).not.toHaveBeenCalled();
    expect(exportResultCopy[result.status]).toBe("合成失败，请返回编辑器检查");
    writeEvidence("network-timeline.json", {
      composition_failed: ["compose:failed", "download:not_started", "persist:not_started"],
      download_failed: ["compose:succeeded", "download:failed", "persist:not_started"],
      downloaded_and_saved: ["compose:succeeded", "download:succeeded", "persist:succeeded"],
      downloaded_not_saved: ["compose:succeeded", "download:succeeded", "persist:failed"],
    });
    writeEvidence("response.json", { copy: exportResultCopy, statuses: Object.keys(exportResultCopy) });
    writeEvidence("db-diff.json", { browser_persistent_blob_writes: 0, latest_updates_after_backend_failure: 0 });
  });
});
