import { describe, expect, it } from "vitest";
import { RpaError } from "@/modules/rpa/errors";
import { RpaDataInvalidError } from "@/modules/quote/types";
import {
  formatQuoteErrorMessage,
  isChineseUserFacingMessage,
  resolveQuoteFailureCode,
  resolveQuoteFailureMessage,
  toChineseUserFacingMessage,
  translateKnownEnglishPhrases,
} from "@/modules/quote/quote-error-messages";

describe("quote-error-messages", () => {
  it("RpaError 保留细分 error_code", () => {
    expect(
      resolveQuoteFailureCode(
        new RpaError("ADDRESS_SUGGESTION_NOT_FOUND", "未找到地址"),
      ),
    ).toBe("ADDRESS_SUGGESTION_NOT_FOUND");
  });

  it("技术英文原文不直出，回退中文默认", () => {
    const msg = resolveQuoteFailureMessage(
      new RpaError(
        "STRUCT_CHANGE",
        "locator.waitFor: Timeout 15000ms exceeded",
      ),
      "QUOTE_ENTRY_UNAVAILABLE",
    );
    expect(msg).toMatch(/自动化操作超时|报价入口/);
    expect(msg).not.toMatch(/locator\.waitFor/i);
  });

  it("Playwright 超时译为具体中文原因，不再吞成通用「暂时无法获取」", () => {
    const msg = toChineseUserFacingMessage(
      "locator.waitFor: Timeout 30000ms exceeded.\nCall log:\n  - waiting for getByTestId('ship-create-continue-button')",
      "QUOTE_UNAVAILABLE",
    );
    expect(msg).toContain("自动化操作超时");
    expect(msg).toContain("创建货件/报价表单控件");
    expect(msg).not.toBe("暂时无法获取报价，请稍后重试");
  });

  it("RpaDataInvalidError 映射为 RPA_DATA_INVALID 并保留中文原因", () => {
    expect(resolveQuoteFailureCode(new RpaDataInvalidError("缺少标准档报价"))).toBe(
      "RPA_DATA_INVALID",
    );
    expect(
      resolveQuoteFailureMessage(
        new RpaDataInvalidError("缺少标准档报价"),
        "RPA_DATA_INVALID",
      ),
    ).toMatch(/标准档|报价/);
  });

  it("含 rate-card 的中文业务句仍可展示", () => {
    expect(
      isChineseUserFacingMessage("登录态 rate-card 未能解析出承运商报价"),
    ).toBe(true);
    expect(
      toChineseUserFacingMessage(
        "登录态 rate-card 未能解析出承运商报价",
        "RPA_DATA_INVALID",
      ),
    ).toContain("承运商报价");
  });

  it("合格中文原文保留", () => {
    expect(
      formatQuoteErrorMessage("QUOTE_UNAVAILABLE", "该线路暂无可用运力，请换地址"),
    ).toBe("该线路暂无可用运力，请换地址");
  });

  it("formatQuoteErrorMessage 按 code 回退", () => {
    expect(formatQuoteErrorMessage("QUOTE_TIMEOUT")).toContain("420 秒");
  });

  it("PROVIDER_LOGIN_FAILED 统一用户文案", () => {
    expect(
      resolveQuoteFailureCode(
        new RpaError("PROVIDER_LOGIN_FAILED", "内部细节"),
      ),
    ).toBe("PROVIDER_LOGIN_FAILED");
    expect(
      resolveQuoteFailureMessage(
        new RpaError("SESSION_EXPIRED", "仍停在登录页，账密可能错误"),
        "SESSION_EXPIRED",
      ),
    ).toContain("即时保存更新");
    expect(formatQuoteErrorMessage("PROVIDER_LOGIN_FAILED")).toContain(
      "账号或密码可能不正确",
    );
    expect(
      formatQuoteErrorMessage(
        "RPA_DATA_INVALID",
        "FLOCK_LOGIN_FAILED：账号或密码错误",
      ),
    ).toContain("即时保存更新");
  });

  it("英文官网文案译为中文", () => {
    expect(translateKnownEnglishPhrases("No rates found")).toBe(
      "未找到可用报价",
    );
    expect(
      toChineseUserFacingMessage("No carriers available for this lane", "CARRIER_NO_CAPACITY"),
    ).toBe("该线路暂无可用运力");
  });

  it("附加服务 appointment 超时译为可读中文，不再吞成通用文案", () => {
    const msg = toChineseUserFacingMessage(
      "locator.waitFor: Timeout 8000ms exceeded.\nCall log:\n  - waiting for getByTestId('address-book-accessorials-option-appointment').first() to be visible",
      "QUOTE_UNAVAILABLE",
    );
    expect(msg).toContain("自动化操作超时");
    expect(msg).toMatch(/预约|附加服务/);
    expect(msg).not.toBe("暂时无法获取报价，请稍后重试");
  });

  it("附加服务不可用业务文案原样保留", () => {
    const raw =
      "派送附加服务「appointment」在官网下拉中不可用或未展开（可见选项：liftgate）。请取消该附加服务后重试，或确认地址类型是否支持。";
    expect(toChineseUserFacingMessage(raw, "CARRIER_NO_CAPACITY")).toBe(raw);
  });
});
