import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { APOLLO_OPTIONS } from 'apollo-angular';
import { HttpLink } from 'apollo-angular/http';
import { InMemoryCache, ApolloLink } from '@apollo/client/core';
import { setContext } from '@apollo/client/link/context';
import { StorageModule, StorageMap } from '@ngx-pwa/local-storage';

@NgModule({
  imports: [StorageModule],
  providers: [
    {
      provide: APOLLO_OPTIONS,
      useFactory: (httpLink: HttpLink, storage: StorageMap) => {
        const basic = setContext((/*operation, context*/) => ({
          headers: {
            // eslint-disable-next-line @typescript-eslint/naming-convention
            Accept: 'charset=utf-8'
          }
        }));

        const auth = setContext((/*operation, context*/) => {
          const token = storage.get('accessToken').subscribe(() => {});

          return !token
            ? {}
            : {
                headers: {
                  // eslint-disable-next-line @typescript-eslint/naming-convention
                  Authorization: `Bearer ${token}`
                }
              };
        });

        const link = ApolloLink.from([
          basic,
          auth,
          httpLink.create({ uri: '/graphql' })
        ]);

        const cache = new InMemoryCache();

        return {
          link,
          cache
        };
      },
      deps: [HttpLink, StorageMap]
    }
  ],
  exports: [HttpClientModule]
})
export class GraphqlModule {}
