/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-inferrable-types */

import { ApolloClient, gql, HttpLink, from, InMemoryCache } from "@apollo/client";
import { onError } from "@apollo/client/link/error";
import { Observable } from "rxjs";
import { QueryClient } from "./QueryClient";
import fetch from 'cross-fetch';
import * as https from "https";
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('dotenv').config();
export class ApolloClientQuery extends QueryClient {


  clientInstance: any
  errorLink = onError(({ graphQLErrors, networkError }) => {
    if (graphQLErrors) {
      console.log(graphQLErrors);

    }

    if (networkError) {
      // handle network error
      console.log(networkError);
    }
  });
  constructor() {

    super();
    const fs = require('fs');
    const url_str: string = process.env.GRAPHQL_HOST;
    // CAN RUN 
    const url1: URL = new URL("graphql", url_str); 
    console.log(url1.toString());


    // Start apollo client

    this.clientInstance = new ApolloClient({
      link: from([this.errorLink, new HttpLink({
        //uri required exact url unable to use process.env variable
        uri: url1.toString(), fetchOptions: {
          agent: new https.Agent({
            key: fs.readFileSync(`src/SSL/cert/client-key.pem`),
            cert: fs.readFileSync(`src/SSL/cert/client-crt.pem`),
            ca: [
              fs.readFileSync(`src/SSL/cert/server-ca-crt.pem`)
            ],
          }),
        }, fetch
      })]),
      cache: new InMemoryCache(),
    });

  }

  sendQuery(queryString: string): Observable<any> {
    let queryObservable: Observable<any>;

    if (this.isCacheOn) {
      queryObservable = new Observable((subscriber) => {

        this.clientInstance.readQuery({
          query: gql`${queryString}`,
        }).then(x => {
          Object.keys(x.data).forEach(y => {
            Object.keys(x.data[y]).forEach(z => {
              if (z != '__typename') {
                subscriber.next(x.data[y][z]);
              }
            })
          })
          subscriber.complete();
        }).catch(error => {
          subscriber.error("error subscribe graphql " + error)
        });
      });

    }
    else {
      queryObservable = new Observable((subscriber) => {

        this.clientInstance.query({
          query: gql`${queryString}`,
        }).then(x => {
          Object.keys(x.data).forEach(y => {
            Object.keys(x.data[y]).forEach(z => {
              if (z != '__typename') {
                subscriber.next(x.data[y][z]);
              }
            })
          })
          subscriber.complete();
        }).catch(error => {
          subscriber.error("error subscribe graphql " + error)
        });
      });

    }
    return queryObservable;

  }
}