/**
 * Standard error response schema and utilities for Beignet
 */

import type { AppError, ErrorDef } from "./catalog.js";

/**
 * Standard Beignet error response body.
 */
export interface ErrorResponseBody {
  /**
   * Stable machine-readable error code.
   */
  code: string;
  /**
   * Human-readable error message.
   */
  message: string;
  /**
   * Optional structured details.
   *
   * These details are sent to clients. Beignet does not automatically redact
   * app-owned response details, so only include values that are safe to expose.
   */
  details?: unknown;
  /**
   * Optional request ID for support and log correlation.
   */
  requestId?: string;
}

/**
 * Create a standard error response body and omit undefined optional fields.
 */
export function createErrorResponseBody(
  args: ErrorResponseBody,
): ErrorResponseBody {
  return {
    code: args.code,
    message: args.message,
    ...(args.details !== undefined ? { details: args.details } : {}),
    ...(args.requestId !== undefined ? { requestId: args.requestId } : {}),
  };
}

/**
 * Check whether a value looks like a standard Beignet error response body.
 */
export function isErrorResponseBody(
  value: unknown,
): value is ErrorResponseBody {
  if (typeof value !== "object" || value === null) return false;

  const body = value as Record<string, unknown>;
  return typeof body.code === "string" && typeof body.message === "string";
}

/**
 * Convert an `AppError` to a standard error response body.
 */
export function toErrorResponseBody(
  err: AppError<ErrorDef>,
): ErrorResponseBody {
  return createErrorResponseBody({
    code: err.code,
    message: err.message,
    details: err.details,
  });
}
