import { onError } from "apollo-link-error";
import { auth } from "../firebase/firebase.utils";
//https://stackoverflow.com/questions/57163454/refreshing-a-token-with-apollo-client-firebase-auth

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

    let expired = false;
    if (graphQLErrors) {
      if (graphQLErrors[0].message.includes("JWTExpired")) {
        expired = true;
      }
    }
    if (networkError) {
      if (networkError.message.includes("JWTExpired")) {
        expired = true;
      }
    }
    if (expired) {
      //User access token has expired
      console.log("Old Token", window.localStorage.getItem("token"));
      // Let's refresh token through async request

      auth.currentUser.getIdToken(true).then(token => {
        if (token) {
          console.log("Got the new token.", token);
          window.localStorage.setItem("token", token);

          const oldHeaders = operation.getContext().headers;
          operation.setContext({
            headers: {
              ...oldHeaders,
              authorization: token ? `Bearer ${token}` : ""
            }
          });
          console.log(operation.getContext());
          // console.log("forward", forward);
          // console.log("operation", operation);
          return forward(operation);

          // return new Observable(observer => {
          //   const subscriber = {
          //     next: observer.next.bind(observer),
          //     error: observer.error.bind(observer),
          //     complete: observer.complete.bind(observer)
          //   };
          //   console.log("About to resend the request.");
          //   // Retry last failed request
          //   forward(operation).subscribe(subscriber);
          // });
        }
      });

      // return new Observable(observer => {
      //   auth.currentUser
      //     .getIdToken(true)
      //     .then(function(idToken) {
      //       if (!idToken) {
      //         window.localStorage.removeItem("token");
      //         return console.log("Refresh token has expired");
      //       }
      //       console.log("Got a new token", idToken);
      //       window.localStorage.setItem("token", idToken);

      //       // reset the headers
      //       operation.setContext(({ headers = {} }) => ({
      //         headers: {
      //           // Re-add old headers
      //           ...headers,
      //           // Switch out old access token for new one
      //           authorization: idToken ? `Bearer ${idToken}` : ""
      //         }
      //       }));

      //       const subscriber = {
      //         next: observer.next.bind(observer),
      //         error: observer.error.bind(observer),
      //         complete: observer.complete.bind(observer)
      //       };
      //       console.log("About to resend the request.");
      //       // Retry last failed request
      //       forward(operation).subscribe(subscriber);
      //     })
      //     .catch(error => {
      //       // No refresh or client token available, we force user to login
      //       console.log("Hit an error.");
      //       observer.error(error);
      //     });
      // });
    }
  }
);

export default errorLink;
