import { NextResponse } from 'next/server';
import { AppError, ValidationError } from '@server/errors';
import { RouteContext, RouteHandler } from './withErrorHandler';
import { runRequestLifecycle } from '@server/logger/request';

import { childLogger } from '@server/logger';
const log = childLogger('middleware.v1-errors');

/**
 * Public REST API v1 error envelope.
 *
 * Internal services throw `AppError` (or its subclasses), whose `toJSON()`
 * yields the dashboard-friendly shape `{ error, code, fields? }`. Public API
 * consumers expect a strictly nested `{ error: { code, message, details? } }`
 * envelope, where `details` carries field-level validation hints when
 * applicable. This helper does the remap so route handlers can keep throwing
 * the same exceptions used everywhere else.
 */
export function v1ErrorBody(message: string, code: string, details?: unknown) {
  return details === undefined
    ? { error: { code, message } }
    : { error: { code, message, details } };
}

export function v1ErrorResponse(err: unknown): NextResponse {
  if (err instanceof ValidationError) {
    return NextResponse.json(
      v1ErrorBody(err.message, err.code, err.fields ?? undefined),
      { status: err.statusCode }
    );
  }
  if (err instanceof AppError) {
    return NextResponse.json(
      v1ErrorBody(err.message, err.code),
      { status: err.statusCode }
    );
  }
  log.error({ err }, 'API v1 error');
  return NextResponse.json(
    v1ErrorBody('Internal server error', 'INTERNAL_ERROR'),
    { status: 500 }
  );
}

/**
 * Wrap a v1 route handler with the public error envelope. Replaces the
 * default `withErrorHandler` for /api/v1/** routes.
 */
export function withV1ErrorHandler(handler: RouteHandler): RouteHandler {
  return async (req: Request, context: RouteContext) => {
    return runRequestLifecycle(req, async () => {
      try {
        return await handler(req, context);
      } catch (err) {
        return v1ErrorResponse(err);
      }
    });
  };
}
