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

import { friendlyError, friendlyFromApiError } from "./messages";

describe("friendlyError", () => {
  it("maps LLM_UNAVAILABLE to copy + a settings action", () => {
    const e = friendlyError("LLM_UNAVAILABLE", "fallback exhausted");
    expect(e.text).toContain("未连接");
    expect(e.actionHref).toBe("/settings/providers");
    expect(e.actionLabel).toBe("去设置提供商");
  });

  it("maps NETWORK to friendly copy without leaking raw message", () => {
    const e = friendlyError("NETWORK", "TypeError: Failed to fetch");
    expect(e.text).toBe("网络中断，请检查连接后重试。");
    expect(e.actionHref).toBeUndefined();
  });

  it("falls back to the raw message for an unknown code", () => {
    const e = friendlyError("WEIRD_CODE", "something specific happened");
    expect(e.text).toBe("something specific happened");
  });

  it("uses generic copy when code is unknown and no message given", () => {
    expect(friendlyError(undefined).text).toBe("出错了，请稍后重试。");
    expect(friendlyError("WEIRD_CODE", "   ").text).toBe("出错了，请稍后重试。");
  });
});

describe("friendlyFromApiError", () => {
  it("surfaces a business error envelope code + action (QA #2/#11)", () => {
    const e = friendlyFromApiError({ error: { code: "LLM_UNAVAILABLE", message: "x" } });
    expect(e.text).toContain("未连接");
    expect(e.actionHref).toBe("/settings/providers");
  });

  it("maps a FastAPI 422 detail envelope to friendly VALIDATION copy (no leak)", () => {
    const e = friendlyFromApiError({ detail: [{ msg: "Input should be >= 1", loc: ["volume"] }] });
    expect(e.text).toBe("提交内容有误，请检查后重试。");
  });

  it("falls back to generic copy for null/unknown shapes", () => {
    expect(friendlyFromApiError(null).text).toBe("出错了，请稍后重试。");
    expect(friendlyFromApiError({ weird: 1 }).text).toBe("出错了，请稍后重试。");
  });
});
