/**
 * Store action 统一错误处理工具（任务 #7 DRY 抽离）。
 *
 * 之前 4 个 store（knowledge/ideas/projects/tasks）共 38 处重复:
 *   try { ... } catch (e: any) { state.error = e?.toString() ?? t('xxx') }
 *
 * 本工具:
 * - 用 `catch (e: unknown)` 替代 `any`（类型安全）
 * - 失败时写 state.error，返回 undefined（调用方判断）
 * - 成功时返回 fn 结果
 *
 * 注:带 seq 竞态守卫的场景调用方需在 fn 内部判断，不在本工具职责范围。
 */

// (Ref import 已移除,_Unused 类型已删除)

/** 带 error 字段的 store state 形状（仅约束 error，其他字段任意）。仅本模块内部使用。 */
interface ErrorSink {
  error: string | null
}

/**
 * 执行异步 action，失败时写 state.error + 返回 undefined。
 *
 * @param state 带 error 字段的响应式 state
 * @param i18nKey 失败时的 i18n 文案 key（兜底）
 * @param fn 异步 action
 * @returns 成功返 fn 结果；失败返 undefined
 */
export async function runWithCatch<T>(
  state: ErrorSink,
  i18nKey: string,
  fn: () => Promise<T>,
): Promise<T | undefined> {
  try {
    return await fn()
  } catch (e: unknown) {
    state.error = stringifyError(e) ?? i18nKey
    return undefined
  }
}

// stringifyError 仅本模块内部使用(runWithCatch/runWithCatchGuarded 调用),不导出。
function stringifyError(e: unknown): string | undefined {
  if (typeof e === 'string') return e
  if (e instanceof Error) return e.message || e.toString()
  if (e && typeof e === 'object' && 'toString' in e) {
    try {
      return String((e as { toString(): string }).toString())
    } catch {
      return undefined
    }
  }
  return undefined
}

/**
 * Variant：带前置守卫的错误捕获。
 *
 * 用于「旧请求的失败不污染当前视图」场景（如 seq 守卫）。
 *
 * @param guard 返回 true 时才写 state.error；false 时静默（旧响应丢弃）
 */
export async function runWithCatchGuarded<T>(
  state: ErrorSink,
  i18nKey: string,
  guard: () => boolean,
  fn: () => Promise<T>,
): Promise<T | undefined> {
  try {
    return await fn()
  } catch (e: unknown) {
    if (guard()) {
      state.error = stringifyError(e) ?? i18nKey
    }
    return undefined
  }
}

// _Unused 类型从未被外部 import,已删除(同时移除上方 Ref import)。
