import { gql } from "graphql-request";
import { DataFetcher } from "../DataFetcher";
export class TotalsFetcher {
  constructor() {
    this.templateByQuery = new Map();
    this.cancel = [];
    this.buildTemplates();
  }
  buildTemplates() {
    this.templateByQuery.set("fetchTotals", gql `query($filters: [InputFilter!] $name: String!) {
                $queryAlias$: fetchTotals(name: $name, filters: $filters ){
                name
                value
                }
            }`);
  }
  fetchTotals(name, resourceID, filters = []) {
    const cancelKey = `${name}_${resourceID}`;
    const anotherPromiseIndex = this.cancel.findIndex(promiseExecuting => promiseExecuting[cancelKey]);
    if (anotherPromiseIndex >= 0) {
      this.cancel[anotherPromiseIndex][cancelKey]();
      this.cancel.splice(anotherPromiseIndex, 1);
    }
    return Promise
      .race([
      new Promise(resolve => this.cancel.push({ [cancelKey]: resolve })),
      this.getTotals(name, resourceID, filters)
    ])
      .then((results) => {
      let dataResult = new Map();
      if (results) {
        dataResult = results;
        const myPromiseIndex = this.cancel.findIndex(promiseExecuting => promiseExecuting[cancelKey]);
        if (myPromiseIndex >= 0) {
          this.cancel.splice(myPromiseIndex, 1);
        }
      }
      return dataResult;
    });
  }
  getTotals(name, resourceID, filters = []) {
    return new Promise((accept, reject) => {
      DataFetcher
        .get()
        .callGraphQL({
        query: this.templateByQuery.get("fetchTotals"),
        values: {
          name: `totals://${name}/${resourceID}`,
          filters: filters
        },
      })
        .then(result => {
        if (result.length > 0) {
          const totalsData = new Map();
          result.forEach(total => totalsData.set(total.name, parseFloat(total.value)));
          return accept(totalsData);
        }
        return reject("Não foi possível recuperar os totalizadores");
      })
        .catch(reject);
    });
  }
}
