import { NextResponse } from "next/server";
import { ApiV1Error, isApiV1Error } from "@/lib/api-v1/errors";

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

export function jsonError(status: number, code: string, message: string, details?: unknown) {
  return NextResponse.json(
    {
      error: {
        code,
        message,
        details: details ?? null,
      },
    },
    { status }
  );
}

export function toErrorResponse(error: unknown) {
  if (isApiV1Error(error)) {
    return NextResponse.json({ error: error.message }, { status: error.status });
  }

  const message = error instanceof Error && error.message ? error.message : "Erro interno da API.";
  return NextResponse.json({ error: message }, { status: 500 });
}

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

export function apiJsonError(status: number, code: string, message: string, details?: unknown, init?: ResponseInit) {
  return NextResponse.json(
    {
      success: false,
      error: {
        code,
        message,
        details: details ?? null,
      },
    },
    {
      status,
      ...(init || {}),
    }
  );
}

export function toApiErrorResponse(error: unknown, init?: ResponseInit) {
  if (isApiV1Error(error)) {
    return apiJsonError(error.status, error.code, error.message, error.details, init);
  }

  const message = error instanceof Error && error.message ? error.message : "Erro interno da API.";
  return apiJsonError(500, "internal_error", message, null, init);
}

export function assertPresent<T>(value: T | null | undefined, status: number, code: string, message: string): T {
  if (value === null || value === undefined) {
    throw new ApiV1Error(status, code, message);
  }
  return value;
}
