import { createSubscriptionsClient } from '@gqty/subscriptions';
import fetch from 'cross-fetch';
import { Cache, createClient, defaultResponseHandler, } from 'gqty';
import { hasuraGraphqlUri, hasuraQueryTypeHeader } from './constants';
import { generatedSchema, scalarsEnumsHash, } from './gqty';
import { wrapGraphQLClient } from './wrap';
export function useHasuraClient(args) {
    const $headers = args && 'headers' in args ? args.headers : undefined;
    const $fetch = (args && 'fetch' in args ? args.fetch : undefined) || fetch;
    const uri = args?.uri || hasuraGraphqlUri;
    const getHeaders = async (base) => {
        const headers = ($headers && typeof $headers === 'function'
            ? await $headers()
            : $headers) || {};
        if (base)
            for (const key in base)
                headers[key] = base[key];
        if (args && 'secret' in args && args.secret) {
            headers['x-hasura-admin-secret'] = args.secret;
        }
        else if (args && 'accessToken' in args && args.accessToken) {
            headers.authorization = args.accessToken.startsWith('Bearer ')
                ? args.accessToken
                : `Bearer ${args.accessToken}`;
        }
        if (args?.auditUserId)
            headers['x-hasura-audit-user-id'] = args.auditUserId;
        return headers;
    };
    const queryFetcher = async ({ query, variables, operationName }, fetchOptions) => {
        const headers = await getHeaders();
        if (fetchOptions?.headers) {
            for (const key in fetchOptions.headers) {
                headers[key] = fetchOptions.headers[key];
            }
        }
        // Modify "https://finalytic.hasura.app/v1/graphql" if needed
        const response = await fetch('https://finalytic.hasura.app/v1/graphql', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                query,
                variables,
                operationName,
            }),
            mode: 'cors',
            ...fetchOptions,
        });
        const json = await response.json();
        return await defaultResponseHandler(json);
    };
    const subscriptionsClient = args?.subscriptions === true
        ? createSubscriptionsClient({
            lazy: true,
            connectionInitPayload: async () => ({
                headers: await getHeaders({
                    [hasuraQueryTypeHeader]: 'subscription',
                }),
            }),
            wsEndpoint() {
                const wsUrl = new URL(uri);
                wsUrl.protocol = wsUrl.protocol
                    .replace('https', 'wss')
                    .replace('http', 'ws');
                return wsUrl.href;
            },
            /*url: () => {
            },*/
        })
        : undefined;
    /*const subscriptionsClient = (() => {
      if (args?.subscriptions === false) return;
      const wsUrl = new URL(uri);
      wsUrl.protocol = wsUrl.protocol
        .replace('https', 'wss')
        .replace('http', 'ws');
      const subscriptionsClient: SubscriptionsClient = createSubscriptionsClient({
        wsEndpoint: wsUrl.href,
        connectionInitPayload: async () => ({
          headers: await getHeaders({ [hasuraQueryTypeHeader]: 'subscription' }),
        }),
      });
      return subscriptionsClient;
    })();*/
    const cache = new Cache(undefined, {
        maxAge: 0,
        staleWhileRevalidate: 5 * 60 * 1000,
        normalization: true,
    });
    const client = createClient({
        schema: generatedSchema,
        scalars: scalarsEnumsHash,
        cache,
        fetchOptions: {
            fetcher: queryFetcher,
            subscriber: subscriptionsClient,
        },
    });
    /*const client: GQtyClient<GeneratedSchema> = createClient<GeneratedSchema>({
      schema: generatedSchema,
      scalarsEnumsHash,
      queryFetcher,
      subscriptionsClient,
      normalization: args?.normalization === true,
      defaults: {
        resolved: {
          noCache: args?.cache !== true,
          retry: false,
        },
      },
      ...args,
    });*/
    return wrapGraphQLClient(client, subscriptionsClient, args?.onError, args?.retries);
}
