import { NextResponse } from "next/server";

/**
 * 统一 API 响应包装。
 *
 * 成功：{ ok: true, data: ... }
 * 失败：{ ok: false, error: { code, message } }
 */

export type ApiOk<T> = { ok: true; data: T };
export type ApiErr = { ok: false; error: { code: string; message: string } };
export type ApiResponse<T> = ApiOk<T> | ApiErr;

export function ok<T>(data: T, init?: ResponseInit) {
  return NextResponse.json<ApiOk<T>>({ ok: true, data }, init);
}

export function err(code: string, message: string, status = 400) {
  return NextResponse.json<ApiErr>(
    { ok: false, error: { code, message } },
    { status },
  );
}

export const ERR = {
  UNAUTHORIZED: () => err("UNAUTHORIZED", "请先登录", 401),
  FORBIDDEN: (msg = "无权限") => err("FORBIDDEN", msg, 403),
  NOT_FOUND: (msg = "资源不存在") => err("NOT_FOUND", msg, 404),
  RATE_LIMITED: () => err("RATE_LIMITED", "操作过于频繁，请稍后再试", 429),
  VALIDATION: (msg: string) => err("VALIDATION", msg, 422),
  INTERNAL: (msg = "服务器错误") => err("INTERNAL", msg, 500),
  ACTIVITY_OFF: () => err("ACTIVITY_OFF", "投票活动暂未开放", 409),
  QUOTA_EXHAUSTED: (msg = "今日票数已用完") =>
    err("QUOTA_EXHAUSTED", msg, 409),
};

/**
 * 把 BigInt 转为字符串（JSON 不能直接序列化 BigInt）。
 * 用于 API 响应序列化前的清洗。
 */
export function sanitizeBigInt<T>(value: T): T {
  return JSON.parse(
    JSON.stringify(value, (_, v) => (typeof v === "bigint" ? v.toString() : v)),
  ) as T;
}
