import { Response, Request } from "express";

export interface PaginationMeta {
  page: number;
  limit: number;
  total: number;
  totalPages: number;
}

export interface ApiResponse<T = unknown> {
  success: boolean;
  statusCode: number;
  message?: string;
  data?: T;
  error?: string;
  errorCode?: string;
  details?: unknown;
  meta?: PaginationMeta;
  timestamp: string;
  path?: string;
  requestId?: string;
}

function getRequestMeta(req?: any) {
  return {
    timestamp: new Date().toISOString(),
    path: req ? req.originalUrl || req.path : undefined,
    requestId: req
      ? req.id || (req.headers && req.headers["x-request-id"])
      : undefined,
  };
}

export function sendSuccess<T>(
  res: Response,
  data: T,
  statusCode = 200,
  message?: string,
  meta?: PaginationMeta,
) {
  if (res.headersSent) return res;
  const metaInfo = getRequestMeta(res.req);
  if (message) {
    (res as any).message = message;
  }
  const payload: ApiResponse<T> = {
    success: true,
    statusCode,
    ...(message && { message }),
    data,
    ...(meta && { meta }),
    ...metaInfo,
  };
  return res.status(statusCode).json(payload);
}

export function sendError(
  res: Response,
  message: string,
  statusCode = 500,
  errorCode = "INTERNAL_SERVER_ERROR",
  details?: unknown,
) {
  if (res.headersSent) return res;
  const metaInfo = getRequestMeta(res.req);
  (res as any).error = message;
  (res as any).errorCode = errorCode;
  (res as any).details = details;

  const payload: ApiResponse = {
    success: false,
    statusCode,
    error: message,
    errorCode,
    ...(details !== undefined && { details }),
    ...metaInfo,
  };
  return res.status(statusCode).json(payload);
}

export function sendPaginated<T>(
  res: Response,
  items: T[],
  total: number,
  page: number,
  limit: number,
  message?: string,
) {
  const totalPages = Math.ceil(total / (limit || 1));
  return sendSuccess(res, items, 200, message, {
    page,
    limit,
    total,
    totalPages,
  });
}
