/**
 * API 工具函数
 * 提供统一的错误处理和响应解析
 */

import { NextResponse } from "next/server";

/**
 * API 错误类
 */
export class ApiError extends Error {
  constructor(
    message: string,
    public status: number,
    public details?: unknown,
  ) {
    super(message);
    this.name = "ApiError";
  }
}

/**
 * 统一的 API 错误响应格式
 */
export interface ApiErrorResponse {
  error: string;
  details?: unknown;
}

/**
 * 创建 API 错误响应
 * @param message 错误消息
 * @param status HTTP 状态码
 * @param details 额外的错误详情
 * @returns NextResponse
 */
export function apiErrorResponse(
  message: string,
  status = 500,
  details?: unknown,
): NextResponse<ApiErrorResponse> {
  const payload: ApiErrorResponse =
    typeof details === "undefined" ? { error: message } : { error: message, details };
  return NextResponse.json(payload, { status });
}

/**
 * 常用错误响应的快捷方法
 */
export const errorResponses = {
  /** 400 - 请求参数错误 */
  badRequest: (message: string = "请求参数错误") => apiErrorResponse(message, 400),

  /** 401 - 未登录 */
  unauthorized: (message: string = "未登录") => apiErrorResponse(message, 401),

  /** 403 - 无权限 */
  forbidden: (message: string = "无权限访问") => apiErrorResponse(message, 403),

  /** 404 - 资源不存在 */
  notFound: (message: string = "资源不存在") => apiErrorResponse(message, 404),

  /** 500 - 服务器错误 */
  internalError: (message: string = "服务器错误") => apiErrorResponse(message, 500),

  /** AI 配置错误 */
  aiConfigError: (provider: "online" | "local") =>
    apiErrorResponse(
      provider === "local"
        ? "未找到本地 AI 配置（LOCAL_AI_BASE_URL/LOCAL_AI_MODEL 或 ai.local.md / ai-local.md）"
        : "未找到在线 AI 配置（ai.md 或 ONLINE_AI_* 环境变量）",
      500,
    ),
} as const;

/**
 * 处理 fetch 响应并解析 JSON
 * 如果响应不成功，抛出 ApiError
 * @param response Fetch Response 对象
 * @param defaultErrorMessage 默认错误消息
 * @returns 解析后的 JSON 数据
 */
export async function handleApiResponse<T>(
  response: Response,
  defaultErrorMessage: string = "请求失败",
): Promise<T> {
  if (!response.ok) {
    let message = defaultErrorMessage;
    let details: unknown;

    try {
      const payload = await response.json();
      if (payload && typeof payload === "object") {
        if ("error" in payload && typeof payload.error === "string") {
          message = payload.error;
        }
        if ("details" in payload) {
          details = payload.details;
        }
      }
    } catch {
      // JSON 解析失败，使用默认消息
    }

    throw new ApiError(message, response.status, details);
  }

  return response.json() as Promise<T>;
}

/**
 * 安全地解析 JSON，失败时返回 null
 * @param raw JSON 字符串
 * @returns 解析后的对象或 null
 */
export function safeParseJson<T = unknown>(raw: string | null | undefined): T | null {
  if (!raw) return null;
  try {
    return JSON.parse(raw) as T;
  } catch {
    return null;
  }
}

/**
 * 验证请求体是否包含必需字段
 * @param body 请求体对象
 * @param requiredFields 必需字段列表
 * @returns 如果验证失败，返回错误响应；否则返回 null
 */
export function validateRequestBody<T extends Record<string, unknown>>(
  body: T | null,
  requiredFields: (keyof T)[],
): NextResponse<ApiErrorResponse> | null {
  if (!body) {
    return apiErrorResponse("请求体为空", 400);
  }

  for (const field of requiredFields) {
    if (!(field in body) || body[field] === null || body[field] === undefined) {
      return apiErrorResponse(`缺少必需字段: ${String(field)}`, 400);
    }
  }

  return null;
}

/**
 * 从请求中安全地获取 JSON
 * @param request Next.js Request 对象
 * @returns 解析后的 JSON 或 null
 */
export async function safeGetJsonBody<T = unknown>(
  request: Request,
): Promise<T | null> {
  try {
    return (await request.json()) as T;
  } catch {
    return null;
  }
}
