// 错误码 → 友好中文文案（+ 可选跳转动作）。
// 对齐后端 ErrorCode（ARCH §7.1）+ 前端流式/网络码（useDraftStream）。
// 目的：UI 不直接暴露 error code，给作者可读的下一步。

export interface FriendlyError {
  text: string;
  // 可选的「下一步」链接（如未连模型 → 去设置）。
  actionHref?: string;
  actionLabel?: string;
}

const PROVIDER_ACTION = {
  actionHref: "/settings/providers",
  actionLabel: "去设置提供商",
} as const;

const MESSAGES: Record<string, FriendlyError> = {
  // 后端 ErrorCode
  LLM_UNAVAILABLE: {
    text: "未连接可用模型，去设置里连一个 provider。",
    ...PROVIDER_ACTION,
  },
  RATE_LIMITED: { text: "请求过于频繁，稍后再试。" },
  CONFLICT_UNRESOLVED: { text: "仍有未裁决的冲突，请先逐条裁决再验收。" },
  NOT_FOUND: { text: "资源不存在或已被删除。" },
  VALIDATION: { text: "提交内容有误，请检查后重试。" },
  INTERNAL: { text: "服务出了点问题，请稍后重试。" },
  // 前端流式/网络码
  NETWORK: { text: "网络中断，请检查连接后重试。" },
  STREAM_FAILED: { text: "写章中断，请重试。" },
};

const DEFAULT_TEXT = "出错了，请稍后重试。";

// 把 (code, 原始 message) 映射为友好文案。
// 已知码 → 预设文案 + 动作；未知码 → 回退到原始 message（非空）或通用兜底。
export function friendlyError(
  code: string | undefined,
  fallbackMessage?: string,
): FriendlyError {
  if (code && MESSAGES[code]) {
    return MESSAGES[code];
  }
  const fallback = fallbackMessage?.trim();
  return { text: fallback && fallback.length > 0 ? fallback : DEFAULT_TEXT };
}

// 从原始 API 错误对象（openapi-fetch 的 `error`）提取友好文案。
// 兼容两种信封：业务错误 `{error:{code,message}}`（ARCH §7.1）与 FastAPI 校验错误 `{detail:[...]}`。
// 422 一律映射为友好的 VALIDATION 文案（不泄露技术性 detail）。未知形 → 通用兜底。
export function friendlyFromApiError(apiError: unknown): FriendlyError {
  if (apiError && typeof apiError === "object") {
    const env = apiError as {
      error?: { code?: string; message?: string };
      detail?: unknown;
    };
    if (env.error?.code) {
      return friendlyError(env.error.code, env.error.message);
    }
    if (env.detail !== undefined) {
      return friendlyError("VALIDATION");
    }
  }
  return friendlyError(undefined);
}
