(function ($) {
  "use strict";

  function tmpl(str, vars) {
    if (!str) return "";
    return String(str)
      .replace(/%processed%/g, String(vars.processed || 0))
      .replace(/%total%/g, String(vars.total || 0))
      .replace(/%applied%/g, String(vars.applied || 0));
  }

  function initOne($wrap) {
    var token = $wrap.data("token") || "";
    var view = $wrap.data("view") || "posts";

    var $start = $wrap.find(".wpsn-bulk-ajax-start");
    var $cancel = $wrap.find(".wpsn-bulk-ajax-cancel");
    var $status = $wrap.find(".wpsn-bulk-ajax-status");
    var $progress = $wrap.find(".wpsn-progress");
    var $bar = $wrap.find(".wpsn-progress-bar");

    var sessionId = null;
    var canceled = false;

    function setStatus(text) {
      $status.text(text || "");
    }

    function setProgress(pct) {
      var v = pct;
      if (v < 0) v = 0;
      if (v > 100) v = 100;
      $bar.css("width", v + "%");
    }

    function fail(message) {
      setStatus(message || (WPSN_BULK_IMPORT && WPSN_BULK_IMPORT.strings && WPSN_BULK_IMPORT.strings.error) || "Error");
      $start.prop("disabled", false);
      $cancel.hide().prop("disabled", false);
    }

    function step() {
      if (canceled || !sessionId) return;

      $.post(
        WPSN_BULK_IMPORT.ajaxUrl,
        {
          action: "wpsn_bulk_table_import_apply_step",
          nonce: WPSN_BULK_IMPORT.nonce,
          session_id: sessionId,
        },
        function (resp) {
          if (!resp || !resp.success) {
            var msg = resp && resp.data && resp.data.message ? resp.data.message : null;
            fail(msg);
            return;
          }

          var d = resp.data || {};
          var processed = parseInt(d.processed || 0, 10);
          var total = parseInt(d.total || 0, 10);
          var applied = parseInt(d.applied_fields || 0, 10);

          var pct = total > 0 ? Math.round((processed / total) * 100) : 100;
          setProgress(pct);
          setStatus(tmpl(WPSN_BULK_IMPORT.strings.progress, { processed: processed, total: total, applied: applied }));

          if (d.done) {
            if (d.redirect) {
              window.location = d.redirect;
            } else if (WPSN_BULK_IMPORT.pageUrlBase) {
              window.location = WPSN_BULK_IMPORT.pageUrlBase + "&view=" + encodeURIComponent(view);
            } else {
              window.location.reload();
            }
            return;
          }

          window.setTimeout(step, 250);
        },
        "json"
      ).fail(function () {
        fail();
      });
    }

    $start.on("click", function (e) {
      e.preventDefault();
      if (!token) {
        fail("Missing token");
        return;
      }

      canceled = false;
      sessionId = null;

      $start.prop("disabled", true);
      $cancel.show().prop("disabled", false);
      $progress.show();
      setProgress(0);
      setStatus(WPSN_BULK_IMPORT.strings.starting);

      $.post(
        WPSN_BULK_IMPORT.ajaxUrl,
        {
          action: "wpsn_bulk_table_import_apply_start",
          nonce: WPSN_BULK_IMPORT.nonce,
          token: token,
          view: view,
        },
        function (resp) {
          if (!resp || !resp.success) {
            var msg = resp && resp.data && resp.data.message ? resp.data.message : null;
            fail(msg);
            return;
          }
          sessionId = resp.data.session_id;
          var total = parseInt(resp.data.total || 0, 10);
          setStatus(tmpl(WPSN_BULK_IMPORT.strings.started, { total: total }));
          step();
        },
        "json"
      ).fail(function () {
        fail();
      });
    });

    $cancel.on("click", function (e) {
      e.preventDefault();
      if (!sessionId) {
        canceled = true;
        $cancel.hide();
        $start.prop("disabled", false);
        setStatus(WPSN_BULK_IMPORT.strings.canceled);
        return;
      }

      canceled = true;
      $cancel.prop("disabled", true);
      setStatus(WPSN_BULK_IMPORT.strings.canceling);

      $.post(
        WPSN_BULK_IMPORT.ajaxUrl,
        {
          action: "wpsn_bulk_table_import_apply_cancel",
          nonce: WPSN_BULK_IMPORT.nonce,
          session_id: sessionId,
        },
        function () {
          $cancel.hide().prop("disabled", false);
          $start.prop("disabled", false);
          setStatus(WPSN_BULK_IMPORT.strings.canceled);
        },
        "json"
      ).always(function () {
        $cancel.hide().prop("disabled", false);
        $start.prop("disabled", false);
      });
    });
  }

  function initRewritePresets() {
    if (typeof WPSN_BULK_IMPORT === "undefined") return;

    function getStrings() {
      return (WPSN_BULK_IMPORT && WPSN_BULK_IMPORT.strings) || {};
    }

    function getPresets() {
      return (WPSN_BULK_IMPORT && WPSN_BULK_IMPORT.rewritePresets) || {};
    }

    function setStatus($box, text, isError) {
      var $st = $box.find(".wpsn-rewrite-preset-status");
      if (!$st.length) return;
      $st.text(text || "");
      $st.css("color", isError ? "#b32d2e" : "");
    }

    function refreshAllSelects() {
      var presets = getPresets();
      var ids = Object.keys(presets);
      ids.sort(function (a, b) {
        var an = (presets[a] && presets[a].name) || a;
        var bn = (presets[b] && presets[b].name) || b;
        return String(an).localeCompare(String(bn));
      });

      $(".wpsn-rewrite-preset-select").each(function () {
        var $sel = $(this);
        var current = $sel.val() || "";
        $sel.find("option").not(":first").remove();
        ids.forEach(function (id) {
          var label = (presets[id] && presets[id].name) || id;
          $sel.append($("<option>").attr("value", id).text(label));
        });
        if (current && presets[current]) {
          $sel.val(current);
        } else {
          $sel.val("");
        }
      });
    }

    // Apply preset → fill textarea + name.
    $(document).on("change", ".wpsn-rewrite-preset-select", function () {
      var presets = getPresets();
      var strings = getStrings();

      var $sel = $(this);
      var presetId = $sel.val() || "";
      if (!presetId || !presets[presetId]) return;

      var $details = $sel.closest("details");
      var $textarea = $details.find('textarea[name="rewrite_rules"]');
      var $name = $details.find(".wpsn-rewrite-preset-name");

      var rules = (presets[presetId] && presets[presetId].rules) || "";
      var label = (presets[presetId] && presets[presetId].name) || "";

      if ($textarea.length) {
        var current = ($textarea.val() || "").trim();
        if (current && current !== String(rules).trim()) {
          var ok = window.confirm(strings.preset_replace_confirm || "Replace current rewrite rules?");
          if (!ok) {
            return;
          }
        }
        $textarea.val(rules);
      }

      if ($name.length) {
        $name.val(label);
      }
    });

    // Save preset.
    $(document).on("click", ".wpsn-rewrite-preset-save", function (e) {
      e.preventDefault();

      var strings = getStrings();
      var $btn = $(this);
      var $box = $btn.closest(".wpsn-rewrite-presets");
      var $details = $btn.closest("details");

      var $sel = $details.find(".wpsn-rewrite-preset-select");
      var presetId = ($sel.val() || "").toString();
      var name = ($details.find(".wpsn-rewrite-preset-name").val() || "").toString().trim();
      var rules = ($details.find('textarea[name="rewrite_rules"]').val() || "").toString();

      if (!name) {
        setStatus($box, strings.preset_name_required || "Preset name is required", true);
        return;
      }
      if (!rules || !rules.trim()) {
        setStatus($box, strings.preset_rules_required || "Rules are required", true);
        return;
      }

      $btn.prop("disabled", true);
      setStatus($box, strings.starting || "Saving…", false);

      $.post(
        WPSN_BULK_IMPORT.ajaxUrl,
        {
          action: "wpsn_bulk_table_rewrite_preset_save",
          nonce: WPSN_BULK_IMPORT.nonce,
          preset_id: presetId,
          name: name,
          rules: rules,
        },
        function (resp) {
          $btn.prop("disabled", false);
          if (!resp || !resp.success) {
            var msg = resp && resp.data && resp.data.message ? resp.data.message : (strings.error || "Error");
            setStatus($box, msg, true);
            return;
          }

          // Update presets client-side.
          if (resp.data && resp.data.presets) {
            WPSN_BULK_IMPORT.rewritePresets = resp.data.presets;
            refreshAllSelects();
          }

          var newId = (resp.data && resp.data.preset_id) || presetId;
          if ($sel.length && newId) {
            $sel.val(newId);
          }

          setStatus($box, (resp.data && resp.data.message) || strings.preset_saved || "Saved", false);
        },
        "json"
      ).fail(function () {
        $btn.prop("disabled", false);
        setStatus($box, strings.error || "Error", true);
      });
    });

    // Delete preset.
    $(document).on("click", ".wpsn-rewrite-preset-delete", function (e) {
      e.preventDefault();

      var strings = getStrings();
      var $btn = $(this);
      var $box = $btn.closest(".wpsn-rewrite-presets");
      var $details = $btn.closest("details");

      var $sel = $details.find(".wpsn-rewrite-preset-select");
      var presetId = ($sel.val() || "").toString();
      if (!presetId) {
        setStatus($box, "", false);
        return;
      }

      var ok = window.confirm(strings.preset_delete_confirm || "Delete this preset?");
      if (!ok) return;

      $btn.prop("disabled", true);
      setStatus($box, strings.canceling || "Deleting…", false);

      $.post(
        WPSN_BULK_IMPORT.ajaxUrl,
        {
          action: "wpsn_bulk_table_rewrite_preset_delete",
          nonce: WPSN_BULK_IMPORT.nonce,
          preset_id: presetId,
        },
        function (resp) {
          $btn.prop("disabled", false);
          if (!resp || !resp.success) {
            var msg = resp && resp.data && resp.data.message ? resp.data.message : (strings.error || "Error");
            setStatus($box, msg, true);
            return;
          }

          if (resp.data && resp.data.presets) {
            WPSN_BULK_IMPORT.rewritePresets = resp.data.presets;
            refreshAllSelects();
          }

          if ($sel.length) {
            $sel.val("");
          }
          $details.find(".wpsn-rewrite-preset-name").val("");
          setStatus($box, (resp.data && resp.data.message) || strings.preset_deleted || "Deleted", false);
        },
        "json"
      ).fail(function () {
        $btn.prop("disabled", false);
        setStatus($box, strings.error || "Error", true);
      });
    });

    // Import presets (JSON) via AJAX (no nested form needed).
    $(document).on("click", ".wpsn-rewrite-preset-import", function (e) {
      e.preventDefault();
      var $box = $(this).closest(".wpsn-rewrite-presets");
      var $file = $box.find(".wpsn-rewrite-preset-import-file");
      if (!$file.length) return;
      // Reset input to allow re-import of same file.
      $file.val("");
      $file.trigger("click");
    });

    $(document).on("change", ".wpsn-rewrite-preset-import-file", function () {
      var strings = getStrings();
      var $file = $(this);
      var $box = $file.closest(".wpsn-rewrite-presets");
      var files = $file[0] && $file[0].files ? $file[0].files : null;
      if (!files || !files.length) {
        setStatus($box, strings.preset_import_select_file || "Please select a JSON file", true);
        return;
      }

      var replace = $box.find(".wpsn-rewrite-preset-import-replace").is(":checked");
      if (replace) {
        var ok = window.confirm(strings.preset_import_replace_confirm || "Replace all existing presets?");
        if (!ok) {
          return;
        }
      }

      var file = files[0];
      var reader = new FileReader();

      reader.onerror = function () {
        setStatus($box, strings.error || "Error", true);
      };

      reader.onload = function () {
        var payload = (reader.result || "").toString();
        if (!payload || !payload.trim()) {
          setStatus($box, strings.preset_import_select_file || "Please select a JSON file", true);
          return;
        }

        setStatus($box, strings.preset_importing || strings.starting || "Importing…", false);

        $.post(
          WPSN_BULK_IMPORT.ajaxUrl,
          {
            action: "wpsn_bulk_table_rewrite_presets_import",
            nonce: WPSN_BULK_IMPORT.nonce,
            payload: payload,
            replace: replace ? "1" : "0",
          },
          function (resp) {
            if (!resp || !resp.success) {
              var msg = resp && resp.data && resp.data.message ? resp.data.message : (strings.error || "Error");
              setStatus($box, msg, true);
              return;
            }

            if (resp.data && resp.data.presets) {
              WPSN_BULK_IMPORT.rewritePresets = resp.data.presets;
              refreshAllSelects();
            }

            setStatus($box, (resp.data && resp.data.message) || strings.preset_imported || "Imported", false);
          },
          "json"
        ).fail(function () {
          setStatus($box, strings.error || "Error", true);
        });
      };

      reader.readAsText(file);
    });
  }

  $(function () {
    $(".wpsn-bulk-import-ajax").each(function () {
      initOne($(this));
    });

    initRewritePresets();
  });
})(jQuery);
