import { gql } from "graphql-request";
import { DataFetcher } from "../DataFetcher";
export default class PersonalizedFilterFetcher {
  constructor() {
    this.DEFAULT_RESOURCE = '_default';
    this.templateByQuery = new Map();
    this.buildTemplates();
  }
  resolveURI(resourceID, configName, isDefault) {
    let uri = "filter-assistent-config://" + resourceID;
    if (configName) {
      uri += "." + configName;
    }
    if (isDefault) {
      uri += this.DEFAULT_RESOURCE;
    }
    return uri;
  }
  resolveLegacyConfigName(legacyConfigName, isDefault) {
    if (!legacyConfigName) {
      return '';
    }
    let legacyConfig = `?legacyResourceID=${legacyConfigName}`;
    if (isDefault) {
      legacyConfig += this.DEFAULT_RESOURCE;
    }
    return legacyConfig;
  }
  buildTemplates() {
    this.templateByQuery.set("fetchFilterFields", gql `
    query($name: String!) {
      $queryAlias$: fetchFilterFields(name: $name){
        currentLink {
          description
          uri
        }
        links {
          description
          uri
          fieldCount
        }
        fields {
          name
          description
          uri
          onlyDate
          dataType
          userInterface
          entityName
          properties {
            name
            value
          }
        }
      }
    }
    `);
    this.templateByQuery.set("fetchFilterAssistent", gql `
    query($name: String!) {
      $queryAlias$: fetchFilterAssistent(name: $name) {
        id
        name
        active
        expression
        warningMessage
        assistent
      }
    }`);
    this.templateByQuery.set("savePersonalizedFilter", gql `
    mutation($name: String!, $filterAssistent: InputFilterAssistent!)  {
      $queryAlias$: savePersonalizedFilter(name: $name, filterAssistent: $filterAssistent) {
        id
        name
      }
    }`);
    this.templateByQuery.set("deletePersonalizedFilter", gql `
    mutation($name: String!, $filterId: String!) {
      $queryAlias$: deletePersonalizedFilter(name: $name, filterId: $filterId) {
        id
        name
      }
    }`);
    this.templateByQuery.set("validateExpression", gql `
    query($dataUnitName: String!, $expression: String!) {
      $queryAlias$: validateExpression(dataUnitName: $dataUnitName, expression: $expression) {
        valid
        message
      }
    }`);
  }
  async loadDefaultFilter(resourceID, filterID, configName, legacyConfigName) {
    return this.loadPersonalizedFilter(resourceID, filterID, configName, legacyConfigName, true);
  }
  async loadPersonalizedFilter(resourceID, filterID, configName, legacyConfigName, isDefault) {
    return new Promise((resolve, reject) => {
      DataFetcher.get()
        .callGraphQL({
        values: { name: this.resolveURI(resourceID, configName, isDefault) + "/" + filterID + this.resolveLegacyConfigName(legacyConfigName, isDefault) },
        query: this.templateByQuery.get("fetchFilterAssistent"),
      })
        .then((resp) => {
        resp.assistent = JSON.parse(resp.assistent);
        resolve(resp);
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
  async saveDefaultFilter(personalizedFilter, resourceID, configName) {
    return this.savePersonalizedFilter(personalizedFilter, resourceID, configName, true);
  }
  async savePersonalizedFilter(personalizedFilter, resourceID, configName, isDefault) {
    if (!personalizedFilter || Object.keys(personalizedFilter).length == 0) {
      return Promise.reject(new Error("personalizedFilter não pode ser vazio"));
    }
    let personalizedFilterParsed = JSON.parse(JSON.stringify(personalizedFilter));
    personalizedFilterParsed.assistent = JSON.stringify(personalizedFilterParsed.assistent);
    return new Promise((resolve, reject) => {
      DataFetcher.get()
        .callGraphQL({
        values: { name: this.resolveURI(resourceID, configName, isDefault), filterAssistent: personalizedFilterParsed },
        query: this.templateByQuery.get("savePersonalizedFilter"),
      })
        .then((resp) => {
        resolve(resp);
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
  removeDefaultFilter(personalizedFilter, resourceID, configName) {
    return this.removePersonalizedFilter(personalizedFilter, resourceID, configName, true);
  }
  async removePersonalizedFilter(personalizedFilter, resourceID, configName, isDefault) {
    return new Promise((resolve, reject) => {
      DataFetcher.get()
        .callGraphQL({
        values: { name: this.resolveURI(resourceID, configName, isDefault), filterId: personalizedFilter.id },
        query: this.templateByQuery.get("deletePersonalizedFilter"),
      })
        .then((resp) => {
        resolve(resp);
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
  async validatePersonalizedFilter(dataUnitName, expression) {
    return new Promise((resolve, reject) => {
      DataFetcher.get()
        .callGraphQL({
        values: { dataUnitName: dataUnitName, expression: expression },
        query: this.templateByQuery.get("validateExpression"),
      })
        .then((resp) => {
        resolve(resp);
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
  loadFields(uri) {
    return new Promise((resolve, reject) => {
      DataFetcher.get()
        .callGraphQL({
        values: { name: uri },
        query: this.templateByQuery.get("fetchFilterFields"),
      })
        .then((resp) => {
        var _a;
        let fields = resp.fields;
        for (const field of fields) {
          if (Array.isArray(field.properties) && field.properties.length > 0) {
            const propertiesConvertedObject = field.properties.reduce((accumulator, prop) => {
              accumulator[prop.name] = prop.value;
              return accumulator;
            }, {});
            field.properties = propertiesConvertedObject;
          }
          if ((_a = field === null || field === void 0 ? void 0 : field.properties) === null || _a === void 0 ? void 0 : _a.options) {
            field.properties.options = JSON.parse(field.properties.options);
          }
        }
        resolve(Object.assign(Object.assign({}, resp), { fields: fields }));
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
}
