// src/types/api.ts
// ============================================================================
// API RESPONSE TYPE DEFINITIONS
// ============================================================================
// Standardized response types for all API endpoints per ADR-028.
// These types ensure consistent response structure across the entire API.
// ============================================================================

/**
 * Standard pagination metadata included in paginated responses.
 */
export interface PaginationMeta {
  /** Current page number (1-indexed) */
  page: number;
  /** Number of items per page */
  limit: number;
  /** Total number of items across all pages */
  total: number;
  /** Total number of pages */
  totalPages: number;
  /** Whether there is a next page */
  hasNextPage: boolean;
  /** Whether there is a previous page */
  hasPrevPage: boolean;
}

/**
 * Optional metadata that can be included in any response.
 */
export interface ResponseMeta {
  /** Unique request identifier for tracking/debugging */
  requestId?: string;
  /** ISO timestamp of when the response was generated */
  timestamp?: string;
  /** Pagination info (only for paginated responses) */
  pagination?: PaginationMeta;
}

/**
 * Standard success response envelope.
 * All successful API responses should follow this structure.
 *
 * @example
 * // Single item response
 * {
 *   "success": true,
 *   "data": { "id": 1, "name": "Item" }
 * }
 *
 * @example
 * // Paginated list response
 * {
 *   "success": true,
 *   "data": [{ "id": 1 }, { "id": 2 }],
 *   "meta": {
 *     "pagination": { "page": 1, "limit": 20, "total": 100, ... }
 *   }
 * }
 */
export interface ApiSuccessResponse<T> {
  success: true;
  data: T;
  meta?: ResponseMeta;
}

/**
 * Standard error response envelope.
 * All error responses should follow this structure.
 *
 * @example
 * // Validation error
 * {
 *   "success": false,
 *   "error": {
 *     "code": "VALIDATION_ERROR",
 *     "message": "The request data is invalid.",
 *     "details": [{ "path": ["email"], "message": "Invalid email format" }]
 *   }
 * }
 *
 * @example
 * // Not found error
 * {
 *   "success": false,
 *   "error": {
 *     "code": "NOT_FOUND",
 *     "message": "User not found"
 *   }
 * }
 */
export interface ApiErrorResponse {
  success: false;
  error: {
    /** Machine-readable error code (e.g., 'VALIDATION_ERROR', 'NOT_FOUND') */
    code: string;
    /** Human-readable error message */
    message: string;
    /** Additional error details (validation errors, etc.) */
    details?: unknown;
  };
  meta?: Pick<ResponseMeta, 'requestId' | 'timestamp'>;
}

/**
 * Union type for all API responses.
 * Useful for frontend type narrowing based on `success` field.
 */
export type ApiResponse<T> = ApiSuccessResponse<T> | ApiErrorResponse;

// ============================================================================
// ERROR CODES
// ============================================================================
// Standardized error codes for consistent error identification.
// ============================================================================

/**
 * Standard error codes used across the API.
 * These should be used with the `sendError` helper function.
 */
export const ErrorCode = {
  // Client errors (4xx)
  VALIDATION_ERROR: 'VALIDATION_ERROR',
  NOT_FOUND: 'NOT_FOUND',
  UNAUTHORIZED: 'UNAUTHORIZED',
  FORBIDDEN: 'FORBIDDEN',
  CONFLICT: 'CONFLICT',
  BAD_REQUEST: 'BAD_REQUEST',
  RATE_LIMITED: 'RATE_LIMITED',
  PAYLOAD_TOO_LARGE: 'PAYLOAD_TOO_LARGE',

  // Server errors (5xx)
  INTERNAL_ERROR: 'INTERNAL_ERROR',
  SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE',
  EXTERNAL_SERVICE_ERROR: 'EXTERNAL_SERVICE_ERROR',
  NOT_IMPLEMENTED: 'NOT_IMPLEMENTED',
} as const;

export type ErrorCodeType = (typeof ErrorCode)[keyof typeof ErrorCode];

// ============================================================================
// HELPER TYPES
// ============================================================================

/**
 * Input for creating paginated responses.
 */
export interface PaginationInput {
  page: number;
  limit: number;
  total: number;
}

/**
 * Type guard to check if a response is a success response.
 */
export function isApiSuccess<T>(response: ApiResponse<T>): response is ApiSuccessResponse<T> {
  return response.success === true;
}

/**
 * Type guard to check if a response is an error response.
 */
export function isApiError<T>(response: ApiResponse<T>): response is ApiErrorResponse {
  return response.success === false;
}
