/**
 * Shared wire types for the server's response envelope and paginated lists.
 *
 * The server wraps every response in `ApiResult` (see the b0 swagger snapshot:
 * `dev/contracts/openapi/swagger.v1.json` → `components.schemas.ApiResult`). The
 * observed wire casing is **camelCase** (`isSuccess`, `statusCode`, `serverTimeUtc`),
 * not the snake_case the routing convention implies — always mirror the published
 * swagger, not an assumption.
 *
 * IMPORTANT: `clientFetch`/`serverFetch` currently return the raw response body, so a
 * real `clientApi` call gets the whole `ApiEnvelope<T>` and must read `.data`. Use
 * `unwrap()` for that. (Whether the fetch layer should unwrap centrally is filed in
 * `dev/shared-working-context/frontend/requests/for-backend.md`.)
 */

export interface ApiEnvelope<T> {
  isSuccess: boolean;
  statusCode: number;
  message?: string | null;
  requestId?: string | null;
  data?: T | null;
}

/** Reads the payload out of the server envelope, throwing if the call was not a success. */
export function unwrap<T>(envelope: ApiEnvelope<T>): T {
  if (!envelope?.isSuccess || envelope.data == null) {
    throw new Error(envelope?.message ?? 'Request did not succeed');
  }
  return envelope.data;
}

/** Standard paginated list payload (api-conventions §Pagination). Verify field casing per contract. */
export interface Paginated<T> {
  items: T[];
  total: number;
  page: number;
  pageSize: number;
}

/** Query params for a paginated list request. */
export interface PageParams {
  page?: number;
  pageSize?: number;
}
