"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getShopifyRedirectAccepted = exports.getShopifyRedirectDeclined = exports.getShopifyRedirectApp = exports.checkShopifyBulkStatus = exports.pollShopifyBulk = exports.queryShopifyBulk = exports.queryShopifyGraphql = exports.formatShopifyHeaders = exports.createShopifyStorefrontAccess = exports.createShopifyRecurringCharge = exports.activateShopifyRecurringCharge = exports.getShopifyRecurringCharge = exports.addShopifyWebhooks = exports.getShopifyHeaders = exports.getShopifyAuthUrl = exports.getShopifyAccessToken = exports.getShopifyToken = exports.getShopifyApi = void 0;

var _shopifyToken = _interopRequireDefault(require("shopify-token"));

var _shopifyApiNode = _interopRequireDefault(require("shopify-api-node"));

var _axios = _interopRequireDefault(require("axios"));

var _graphql = require("./graphql");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const getShopifyApi = async (config, shopName, accessToken) => await new _shopifyApiNode.default({
  shopName,
  accessToken,
  apiVersion: config.SHOPIFY_API_VERSION
});

exports.getShopifyApi = getShopifyApi;

const getShopifyToken = config => new _shopifyToken.default({
  redirectUri: `${config.SHOPIFY_APP_URL}/callback`,
  sharedSecret: config.SHOPIFY_API_SECRET,
  apiKey: config.SHOPIFY_API_KEY,
  scopes: config.SHOPIFY_API_SCOPES,
  timeout: 10000
});

exports.getShopifyToken = getShopifyToken;

const getShopifyAccessToken = async (config, query) => {
  const token = getShopifyToken(config);

  if (token.verifyHmac(query)) {
    return await token.getAccessToken(query.shop, query.code);
  } else {
    return new Error("Error validating or generating token");
  }
};

exports.getShopifyAccessToken = getShopifyAccessToken;

const getShopifyAuthUrl = (config, shop) => {
  let token = getShopifyToken(config);
  return token.generateAuthUrl(shop, undefined, token.generateNonce());
};

exports.getShopifyAuthUrl = getShopifyAuthUrl;

const getShopifyHeaders = req => {
  const shop = req.get("x-shopify-shop-domain");
  const accessToken = req.get("x-shopify-access-token");
  const apiVersion = req.get("x-shopify-api-version");
  const graphqlEndpoint = `https://${shop}/admin/api/${apiVersion}/graphql.json`;
  return {
    shop,
    accessToken,
    apiVersion,
    graphqlEndpoint
  };
};

exports.getShopifyHeaders = getShopifyHeaders;

const addShopifyWebhooks = async (config, shopify) => {
  try {
    const webhookConfig = config.SHOPIFY_APP_WEBHOOKS;
    const webhookShopify = await shopify.webhook.list();
    let webhookCreated = false;

    for (const topic of Object.keys(webhookConfig)) {
      const webhookTopic = topic.replace("-", "/");
      const webhookExists = webhookShopify ? webhookShopify.filter(webhook => webhook.topic === webhookTopic) : [];

      if (!webhookExists.length) {
        await shopify.webhook.create({
          topic: webhookTopic,
          address: `${config.SHOPIFY_APP_URL}${webhookConfig[topic]}`,
          metafield_namespaces: ["reactify", "connector", "dtk"]
        });
        webhookCreated = true;
      }
    }

    return webhookCreated;
  } catch (err) {
    console.log(err);
    return new Error("Failed to create webhooks");
  }
}; //TODO: export const removeShopifyWebhooks = async (shopify: ShopifyApi): Promise<any> => {}


exports.addShopifyWebhooks = addShopifyWebhooks;

const getShopifyRecurringCharge = async (shopify, chargeId) => await shopify.recurringApplicationCharge.get(chargeId);

exports.getShopifyRecurringCharge = getShopifyRecurringCharge;

const activateShopifyRecurringCharge = async (shopify, chargeId) => await shopify.recurringApplicationCharge.activate(chargeId, {});

exports.activateShopifyRecurringCharge = activateShopifyRecurringCharge;

const createShopifyRecurringCharge = async (config, shopify, shop, token, trial, redirect) => {
  if (config.SHOPIFY_APP_CUSTOM_PRIVATE === "true") return redirect;

  try {
    const charges = await shopify.recurringApplicationCharge.list();
    const activeCharges = charges ? charges.find(charge => charge.status === "active" && charge.name === config.SHOPIFY_APP_PLAN_NAME) : false;

    if (!activeCharges && config.SHOPIFY_APP_PLAN_NAME && config.SHOPIFY_APP_PLAN_PRICE) {
      let data = {
        name: config.SHOPIFY_APP_PLAN_NAME,
        price: config.SHOPIFY_APP_PLAN_PRICE,
        return_url: `${config.SHOPIFY_APP_URL}/activate-charge?shop=${shop}&token=${token}`
      };
      if (trial) data = { ...data,
        trial_days: config.SHOPIFY_APP_PLAN_TRIAL
      };
      if (config.SHOPIFY_APP_PLAN_TEST === "true") data = { ...data,
        test: true
      };
      const charge = await shopify.recurringApplicationCharge.create(data);
      return charge.confirmation_url;
    } else {
      return redirect;
    }
  } catch (err) {
    return new Error("Failed to create charges");
  }
};

exports.createShopifyRecurringCharge = createShopifyRecurringCharge;

const createShopifyStorefrontAccess = async (config, shopify) => {
  if (!config.SHOPIFY_APP_STOREFRONT_ACCESS) return false;

  try {
    const storefrontToken = await shopify.storefrontAccessToken.create({
      title: config.SHOPIFY_APP_PLAN_NAME
    }); //@ts-ignore

    if (!(storefrontToken === null || storefrontToken === void 0 ? void 0 : storefrontToken.access_token)) throw new Error(storefrontToken === null || storefrontToken === void 0 ? void 0 : storefrontToken.errors);
    return storefrontToken === null || storefrontToken === void 0 ? void 0 : storefrontToken.access_token;
  } catch (err) {
    console.log(err);
    return new Error("Failed to create storefront access token");
  }
};

exports.createShopifyStorefrontAccess = createShopifyStorefrontAccess;

const formatShopifyHeaders = accessToken => ({
  "X-Shopify-Access-Token": accessToken,
  "Content-Type": "application/json",
  Accept: "application/json"
});

exports.formatShopifyHeaders = formatShopifyHeaders;

const queryShopifyGraphql = async (res, endpoint, token, body) => await (0, _axios.default)({
  method: "POST",
  url: endpoint,
  data: body,
  headers: formatShopifyHeaders(token)
}).then(result => result ? res.status(200).json(result.data) : res.status(200).json({
  status: "error",
  body: "No data returned"
}));

exports.queryShopifyGraphql = queryShopifyGraphql;

const queryShopifyBulk = async (shopify, type, query, poll) => {
  var _result$bulkOperation, _result$bulkOperation2;

  console.log(`[QUERY] Starting bulk query for ${type}s`);
  const result = await shopify.graphql((0, _graphql.SHOPIFY_BULK_QUERY)(query));

  if ((result === null || result === void 0 ? void 0 : (_result$bulkOperation = result.bulkOperationRunQuery) === null || _result$bulkOperation === void 0 ? void 0 : (_result$bulkOperation2 = _result$bulkOperation.bulkOperation) === null || _result$bulkOperation2 === void 0 ? void 0 : _result$bulkOperation2.status) === "CREATED") {
    var _result$bulkOperation3, _result$bulkOperation4;

    console.log(`[QUERY] Current status: ${result === null || result === void 0 ? void 0 : (_result$bulkOperation3 = result.bulkOperationRunQuery) === null || _result$bulkOperation3 === void 0 ? void 0 : (_result$bulkOperation4 = _result$bulkOperation3.bulkOperation) === null || _result$bulkOperation4 === void 0 ? void 0 : _result$bulkOperation4.status}`);

    if (poll) {
      const downloadUrl = await pollShopifyBulk(shopify, poll);
      console.log(`[QUERY] Download URL for ${type}s: ${downloadUrl}`);
      return downloadUrl;
    } else {
      return true;
    }
  } else {
    var _result$bulkOperation5, _result$bulkOperation6, _result$bulkOperation7;

    console.log(`[QUERY] Error on query for ${type}s`);
    console.error(result === null || result === void 0 ? void 0 : (_result$bulkOperation5 = result.bulkOperationRunQuery) === null || _result$bulkOperation5 === void 0 ? void 0 : (_result$bulkOperation6 = _result$bulkOperation5.userErrors[0]) === null || _result$bulkOperation6 === void 0 ? void 0 : _result$bulkOperation6.message);
    throw new Error(result === null || result === void 0 ? void 0 : (_result$bulkOperation7 = result.bulkOperationRunQuery) === null || _result$bulkOperation7 === void 0 ? void 0 : _result$bulkOperation7.userErrors);
  }
};

exports.queryShopifyBulk = queryShopifyBulk;

const pollShopifyBulk = async (shopify, amount) => {
  console.log(`[POLL] Starting poll of bulk query`);
  let url = false;
  let count = 0;

  while (!url && count < amount) {
    var _result$currentBulkOp, _result$currentBulkOp2;

    await new Promise(resolve => setTimeout(() => resolve(), 10000));
    const result = await shopify.graphql(_graphql.SHOPIFY_BULK_QUERY_STATUS);
    console.log(`[POLL] Current status: ${result.currentBulkOperation.status} and object count: ${result.currentBulkOperation.objectCount}`);
    if ((result === null || result === void 0 ? void 0 : (_result$currentBulkOp = result.currentBulkOperation) === null || _result$currentBulkOp === void 0 ? void 0 : _result$currentBulkOp.status) === "COMPLETED") url = result === null || result === void 0 ? void 0 : (_result$currentBulkOp2 = result.currentBulkOperation) === null || _result$currentBulkOp2 === void 0 ? void 0 : _result$currentBulkOp2.url;
    count++;
  }

  return url;
};

exports.pollShopifyBulk = pollShopifyBulk;

const checkShopifyBulkStatus = async shopify => {
  var _result$currentBulkOp3, _result$currentBulkOp4;

  console.log(`[CHECK] Checking status of bulk query`);
  let url = false;
  const result = await shopify.graphql(_graphql.SHOPIFY_BULK_QUERY_STATUS);
  console.log(`[CHECK] Current status: ${result.currentBulkOperation.status} and object count: ${result.currentBulkOperation.objectCount}`);
  return (result === null || result === void 0 ? void 0 : (_result$currentBulkOp3 = result.currentBulkOperation) === null || _result$currentBulkOp3 === void 0 ? void 0 : _result$currentBulkOp3.status) === "COMPLETED" ? result === null || result === void 0 ? void 0 : (_result$currentBulkOp4 = result.currentBulkOperation) === null || _result$currentBulkOp4 === void 0 ? void 0 : _result$currentBulkOp4.url : false;
};

exports.checkShopifyBulkStatus = checkShopifyBulkStatus;

const getShopifyRedirectApp = (config, shop, token, customToken) => `https://${shop}/admin/apps/${config.SHOPIFY_APP_NAME_URL}?token=${token}&shop=${shop}&uid=${customToken}`;

exports.getShopifyRedirectApp = getShopifyRedirectApp;

const getShopifyRedirectDeclined = (config, shop) => `https://${shop}/admin/apps/${config.SHOPIFY_APP_NAME_URL}/error/declined`;

exports.getShopifyRedirectDeclined = getShopifyRedirectDeclined;

const getShopifyRedirectAccepted = (config, shop, token, uid) => `https://${shop}/admin/apps/${config.SHOPIFY_APP_NAME_URL}?token=${token}&shop=${shop}&uid=${uid}`; // export const getShopifyAll = async (shopify, object) => {
//   let records = []
//   let data = null
//   let pageNumber = 1
//   do {
//     data = await shopify[object].list({ limit: 250 })
//     records.push.apply(records, data)
//     pageNumber++
//   } while (data.length === 250)
//   return records
// }


exports.getShopifyRedirectAccepted = getShopifyRedirectAccepted;
//# sourceMappingURL=shopify.js.map