import { ApolloClient, from, HttpLink, InMemoryCache } from "@apollo/client";
import { setContext } from "@apollo/client/link/context";
import { onError } from "@apollo/client/link/error";
import { RetryLink } from "@apollo/client/link/retry";

import env from "../env";
import { auth } from "../firebase/firebase.utils";
const httpLink = new HttpLink({
  uri: env.uri,
});

//https://stackoverflow.com/questions/57163454/refreshing-a-token-with-apollo-client-firebase-auth

const errorLink = onError(
  ({ graphQLErrors, networkError, operation, forward }) => {
    console.error(graphQLErrors);
    if (graphQLErrors)
      graphQLErrors.forEach(({ message, locations, path }) =>
        console.error(
          `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
        )
      );
    if (networkError)
      console.error(`[Network error]: ${JSON.stringify(networkError)}`);
  }
);

// const subscriptionMiddleware = {
//   applyMiddleware: async (options, next) => {
//     options.authToken =
//       auth.currentUser && (await auth.currentUser.getIdToken(true));
//     next();
//   },
// };


const authLink = setContext((_, { headers }) => {
  return (
    auth.currentUser &&
    auth.currentUser.getIdToken().then((token) => {
      if (token) {
        return {
          headers: {
            ...headers,
            authorization: token ? `Bearer ${token}` : "",
          },
        };
      } else {
        return { headers };
      }
    })
  );
});

const retryLink = new RetryLink({
  delay: {
    initial: 500,
    max: 5,
    jitter: true,
  },
  attempts: {
    max: 5,
    retryIf: (error, _operation) => !!error,
  },
});

const cache = new InMemoryCache();

export const client = new ApolloClient({
  //link: ApolloLink.from(middlewares),
  //link: from([apolloLogger, errorLink, authLink, link]),
  link: from([authLink, retryLink, errorLink, httpLink]),
  cache,
  notifyOnNetworkStatusChange: true,
  defaultOptions: {
    watchQuery: {
      fetchPolicy: "network-only",
      nextFetchPolicy: "network-only",
    },
    query: {
      fetchPolicy: "network-only",
    },
  },
});
