import type { DocumentNode } from 'graphql';

export interface GraphQLOriginalError {
  readonly statusCode: number;
  /**
   * NestJS standard body field. May be absent for OAuth errors that use `error`
   * as their primary body key (RFC 6749 §5.2 shape). Always present for
   * validation errors and most NestJS HttpExceptions.
   */
  readonly message?: string | string[] | Record<string, unknown>;
  /**
   * RFC 6749 §5.2 error code (e.g. `invalid_grant`, `invalid_client`).
   * Present on OAuth flow errors; absent on standard NestJS exceptions.
   */
  readonly error?: string;
  readonly translation?: string;
  readonly params?: Record<string, unknown>;
}

export interface GraphQLTranslationError {
  readonly statusCode: number;
  readonly translation?: string;
  readonly message: string;
}

export interface GraphQLErrorHandler {
  handleGraphQLErrors(errors: readonly GraphQLTranslationError[]): void;
  handleNetworkError(error: Error, statusCode?: number): void;
}

export interface GraphQLAuthHandler {
  getAuthorizationHeader(operationName: string | null): Promise<string | null>;
  /**
   * Attempt a transparent session refresh. Resolves `true` when a fresh access
   * token is now in `TokenStore` (the caller may retry the failed operation),
   * `false` when refresh is unavailable or rejected (caller should sign out).
   * Implementations SHOULD coalesce concurrent calls into a single in-flight
   * refresh (single-flight).
   */
  tryRefresh(): Promise<boolean>;
  handleUnauthorized(): void;
}

export interface GraphQLStatements {
  readonly fields: string;
  readonly relationsFields?: string;
  readonly queryPagination?: DocumentNode;
  readonly queryObjectRelations?: DocumentNode;
  readonly queryObjects?: DocumentNode;
  readonly queryObject?: DocumentNode;
  readonly mutationCreateObject?: DocumentNode;
  readonly mutationUpdateObject?: DocumentNode;
  readonly mutationDeleteObjectById?: DocumentNode;
}
