import type { Logger } from "@incubrain/logger";
import { BaseClient } from "./base.client.js";
import type { Client } from "urql";
import type { DocumentNode } from "graphql";
export type Primitive = string | number | boolean | null;
export type DeepPartial<T> = {
    [P in keyof T]?: T[P] extends Primitive ? T[P] : T[P] extends Array<infer U> ? Array<DeepPartial<U>> : T[P] extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : DeepPartial<T[P]>;
};
export interface ClientConfig {
    endpoint: string;
    headers?: Record<string, string>;
    exchanges?: any[];
    plugins?: ClientPlugin[];
    logger?: Logger;
    defaultPluginOptions?: DefaultPluginOptions;
}
export interface DefaultPluginOptions {
    retry?: RetryPluginConfig;
    cache?: CachePluginConfig;
    logging?: LoggingPluginConfig;
}
export interface ClientPlugin {
    name: string;
    onInit?: (client: BaseClient) => Promise<void> | void;
    beforeRequest?: (requestConfig: RequestConfig) => Promise<RequestConfig> | RequestConfig;
    afterRequest?: (response: any, requestConfig: RequestConfig) => Promise<any> | any;
    onError?: (error: Error, requestConfig: RequestConfig) => Promise<any> | void;
    extends?: Record<string, Function>;
}
export interface RetryPluginConfig {
    enabled?: boolean;
    maxRetries?: number;
    retryDelay?: number;
    retryOnNetworkError?: boolean;
    retryOnTimeout?: boolean;
    retryableStatusCodes?: number[];
}
export interface CachePluginConfig {
    enabled?: boolean;
    ttl?: number;
    exclude?: string[];
    maxSize?: number;
    invalidateOnMutation?: boolean;
}
export interface LoggingPluginConfig {
    enabled?: boolean;
    logLevel?: "debug" | "info" | "warn" | "error";
    logRequests?: boolean;
    logResponses?: boolean;
    logErrors?: boolean;
    maskHeaders?: string[];
}
export interface Operation {
    key: string;
    document: DocumentNode;
}
export interface RequestConfig {
    operation: Operation;
    variables?: Record<string, any>;
    context?: Record<string, any>;
    client: Client;
}
export interface EntityField {
    type: string;
    nullable: boolean;
    list: boolean;
}
export interface EntityFields {
    [fieldName: string]: EntityField;
}
export interface Entity {
    name: string;
    fields: EntityFields;
}
export interface WhereInput {
    [key: string]: any;
}
export interface WhereUniqueInput {
    id?: string | number;
    [key: string]: any;
}
export interface OrderByInput {
    [key: string]: "asc" | "desc";
}
export type SelectionMap<T> = {
    [K in keyof T]?: boolean | SelectionMap<T[K]>;
};
export type IncludeMap<T> = {
    [K in keyof T]?: boolean | {
        select?: SelectionMap<T[K]>;
    };
};
type WhereCondition<T> = {
    [P in keyof T]?: T[P] extends (infer U)[] ? WhereCondition<U> | {
        _in: U[];
    } : T[P] extends object ? WhereCondition<T[P]> : {
        _eq?: T[P];
        _neq?: T[P];
        _in?: T[P][];
        _nin?: T[P][];
        _gt?: T[P];
        _gte?: T[P];
        _lt?: T[P];
        _lte?: T[P];
        _like?: T[P] extends string ? string : never;
        _ilike?: T[P] extends string ? string : never;
    };
};
type WhereConditionWithLogicalOperators<T> = WhereCondition<T> & {
    AND?: WhereCondition<T>[];
    OR?: WhereCondition<T>[];
};
export interface FindManyArgs<TEntity> {
    where?: WhereConditionWithLogicalOperators<TEntity>;
    orderBy?: Record<keyof TEntity, "asc" | "desc">;
    take?: number;
    skip?: number;
    select?: SelectionMap<TEntity>;
    include?: IncludeMap<TEntity>;
    options?: QueryOptions;
}
export interface CreateArgs<TData, TEntity> {
    data: TData;
    select?: SelectionMap<TEntity>;
    include?: IncludeMap<TEntity>;
    options?: QueryOptions;
}
export interface UpdateArgs<TData, TEntity> {
    where: WhereUniqueInput;
    data: Partial<TData>;
    select?: SelectionMap<TEntity>;
    include?: IncludeMap<TEntity>;
    options?: QueryOptions;
}
export interface DeleteArgs<TEntity, TSelect> {
    where: WhereUniqueInput;
    select?: SelectionMap<TEntity>;
    include?: IncludeMap<TEntity>;
    options?: QueryOptions;
}
export interface QueryOptions {
    cache?: boolean;
    cacheTTL?: number;
    variables?: Record<string, any>;
}
export type FieldSelection<T> = {
    [K in keyof T]?: boolean | FieldSelection<T[K]>;
};
type WhereUnique = {
    id: string | number;
} | {
    [key: string]: string | number;
};
export interface FindUniqueArgs<TEntity> {
    where: WhereUnique;
    select?: FieldSelection<TEntity>;
    include?: Record<string, boolean>;
    options?: QueryOptions;
}
export interface ClientConfig {
    url: string;
    fetchOptions?: RequestInit;
    logger?: Logger;
}
export interface RelationField<T> {
    select?: SelectionMap<T>;
    include?: IncludeMap<T>;
}
export type WithRelations<T> = {
    [K in keyof T]: T[K] extends Array<infer U> ? Array<WithRelations<U>> : T[K] extends object ? WithRelations<T[K]> : T[K];
};
export {};
