/* global WP_Smush */
/* global ajaxurl */

/**
 * Directory scanner module that will Smush images in the Directory Smush modal.
 *
 * @since 2.8.1
 *
 * @param {string|number} totalSteps
 * @param {string|number} currentStep
 * @return {Object}  Scan object.
 * @class
 */
const DirectoryScanner = (totalSteps, currentStep) => {
  totalSteps = parseInt(totalSteps);
  currentStep = parseInt(currentStep);

  let cancelling = false,
    failedItems = 0,
    skippedItems = 0;

  const obj = {
    scan() {
      const remainingSteps = totalSteps - currentStep;
      if (currentStep !== 0) {
        // Scan started on a previous page load.
        step(remainingSteps);
      } else {
        jQuery.post(ajaxurl, { action: "directory_smush_start" }, () =>
          step(remainingSteps)
        );
      }
    },

    cancel() {
      cancelling = true;
      return jQuery.post(ajaxurl, { action: "directory_smush_cancel" });
    },

    getProgress() {
      if (cancelling) {
        return 0;
      }
      // O M G ... Logic at it's finest!
      const remainingSteps = totalSteps - currentStep;
      return Math.min(
        Math.round((parseInt(totalSteps - remainingSteps) * 100) / totalSteps),
        99
      );
    },

    onFinishStep(progress) {
      jQuery(".wp-smush-progress-dialog .sui-progress-state-text").html(
        currentStep -
          failedItems +
          "/" +
          totalSteps +
          " " +
          window.wp_smush_msgs.progress_smushed
      );
      WP_Smush.directory.updateProgressBar(progress);
    },

    onFinish() {
      WP_Smush.directory.updateProgressBar(100);
      window.location.href = window.wp_smush_msgs.directory_url + "&scan=done";
    },

    limitReached() {
      const dialog = jQuery("#wp-smush-progress-dialog");

      dialog.addClass("wp-smush-exceed-limit");
      dialog
        .find("#cancel-directory-smush")
        .attr("data-tooltip", window.wp_smush_msgs.bulk_resume);
      dialog
        .find(".sui-icon-close")
        .removeClass("sui-icon-close")
        .addClass("sui-icon-play");
      dialog
        .find("#cancel-directory-smush")
        .attr("id", "cancel-directory-smush-disabled");
    },

    resume() {
      const dialog = jQuery("#wp-smush-progress-dialog");
      const resume = dialog.find("#cancel-directory-smush-disabled");

      dialog.removeClass("wp-smush-exceed-limit");
      dialog
        .find(".sui-icon-play")
        .removeClass("sui-icon-play")
        .addClass("sui-icon-close");
      resume.attr("data-tooltip", "Cancel");
      resume.attr("id", "cancel-directory-smush");

      obj.scan();
    }
  };

  /**
   * Execute a scan step recursively
   *
   * Private to avoid overriding
   *
   * @param {number} remainingSteps
   */
  const step = function(remainingSteps) {
    if (remainingSteps >= 0) {
      currentStep = totalSteps - remainingSteps;
      jQuery.post(
        ajaxurl,
        {
          action: "directory_smush_check_step",
          step: currentStep
        },
        response => {
          // We're good - continue on.
          if ("undefined" !== typeof response.success && response.success) {
            if (
              "undefined" !== typeof response.data &&
              "undefined" !== typeof response.data.skipped &&
              true === response.data.skipped
            ) {
              skippedItems++;
            }

            currentStep++;
            remainingSteps = remainingSteps - 1;
            obj.onFinishStep(obj.getProgress());
            step(remainingSteps);
          } else if (
            "undefined" !== typeof response.data.error &&
            "dir_smush_limit_exceeded" === response.data.error
          ) {
            // Limit reached. Stop.
            obj.limitReached();
          } else {
            // Error? never mind, continue, but count them.
            failedItems++;
            currentStep++;
            remainingSteps = remainingSteps - 1;
            obj.onFinishStep(obj.getProgress());
            step(remainingSteps);
          }
        }
      );
    } else {
      jQuery.post(
        ajaxurl,
        {
          action: "directory_smush_finish",
          items: totalSteps - (failedItems + skippedItems),
          failed: failedItems,
          skipped: skippedItems
        },
        response => obj.onFinish(response)
      );
    }
  };

  return obj;
};

export default DirectoryScanner;
