import type { IncomingMessage, ServerResponse } from 'node:http';
import { URL } from 'node:url';
import { config } from './config.js';
import { HttpError } from './errors.js';

export { HttpError } from './errors.js';

export interface RequestContext {
  req: IncomingMessage;
  res: ServerResponse;
  url: URL;
}

export type Handler = (ctx: RequestContext) => Promise<unknown>;

export function sendJson(res: ServerResponse, statusCode: number, body: unknown) {
  res.statusCode = statusCode;
  res.setHeader('content-type', 'application/json; charset=utf-8');
  res.end(JSON.stringify(body));
}

export function getHeader(req: IncomingMessage, name: string): string {
  const value = req.headers[name.toLowerCase()];
  if (Array.isArray(value)) return value[0] || '';
  return value || '';
}

export function applyCors(req: IncomingMessage, res: ServerResponse) {
  const origin = getHeader(req, 'origin');
  const allowAll = config.corsOrigins.includes('*');
  if (allowAll) {
    res.setHeader('access-control-allow-origin', '*');
  } else if (origin && config.corsOrigins.includes(origin)) {
    res.setHeader('access-control-allow-origin', origin);
    res.setHeader('vary', 'origin');
  }
  res.setHeader('access-control-allow-methods', 'GET,POST,PUT,PATCH,DELETE,OPTIONS');
  res.setHeader('access-control-allow-headers', 'content-type,authorization,x-tenant-id,x-tenant-code,x-user-id,x-platform-admin-key');
}

export function routeKey(method: string | undefined, pathname: string) {
  return `${method || 'GET'} ${pathname}`;
}

export function publicErrorBody(error: unknown) {
  if (error instanceof HttpError) {
    return {
      statusCode: error.statusCode,
      body: { error: error.message, code: error.code },
    };
  }

  const message = error instanceof Error ? error.message : 'Unknown error';
  return {
    statusCode: 500,
    body: {
      error: config.isProduction ? 'Internal server error' : message,
      code: 'INTERNAL_ERROR',
    },
  };
}
