(function initMyronAssetPicker(global) {
  "use strict";

  function onReady(callback) {
    if (global.document.readyState === "loading") {
      global.document.addEventListener("DOMContentLoaded", callback, { once: true });
      return;
    }

    callback();
  }

  function closest(element, selector) {
    return element && typeof element.closest === "function" ? element.closest(selector) : null;
  }

  function setPreview(preview, url, altText) {
    if (!preview) {
      return;
    }
    preview.textContent = "";
    if (!url) {
      var empty = global.document.createElement("span");
      empty.textContent = "No asset selected.";
      preview.appendChild(empty);
      return;
    }
    var image = global.document.createElement("img");
    image.src = url;
    image.alt = altText || "";
    if (!altText) {
      image.setAttribute("aria-hidden", "true");
    }
    preview.appendChild(image);
  }

  function close(modal) {
    if (!modal) {
      return;
    }
    var backdrop = global.document.querySelector('[data-mc-asset-picker-backdrop="' + modal.id + '"]');
    modal.hidden = true;
    modal.setAttribute("aria-hidden", "true");
    if (backdrop) {
      backdrop.hidden = true;
      backdrop.setAttribute("aria-hidden", "true");
    }
  }

  function open(modalId, targetId, previewId) {
    var modal = global.document.getElementById(modalId);
    if (!modal) {
      return;
    }
    modal.setAttribute("data-mc-asset-picker-active-target-id", targetId || "");
    modal.setAttribute("data-mc-asset-picker-active-preview-id", previewId || "");
    var backdrop = global.document.querySelector('[data-mc-asset-picker-backdrop="' + modal.id + '"]');
    modal.hidden = false;
    modal.setAttribute("aria-hidden", "false");
    if (backdrop) {
      backdrop.hidden = false;
      backdrop.setAttribute("aria-hidden", "false");
    }
    if (typeof modal.focus === "function") {
      modal.focus();
    }
  }

  function activeTarget(modal) {
    return modal ? global.document.getElementById(modal.getAttribute("data-mc-asset-picker-active-target-id") || "") : null;
  }

  function activePreview(modal) {
    return modal ? global.document.getElementById(modal.getAttribute("data-mc-asset-picker-active-preview-id") || "") : null;
  }

  function assignAsset(modal, url, altText) {
    var target = activeTarget(modal);
    if (!target || !url) {
      return false;
    }
    target.value = url;
    target.dispatchEvent(new Event("change", { bubbles: true }));
    setPreview(activePreview(modal), url, altText || "");
    return true;
  }

  function uploadError(form) {
    return form ? form.querySelector("[data-mc-asset-picker-upload-error]") : null;
  }

  function showUploadError(form, message) {
    var error = uploadError(form);
    if (!error) {
      return;
    }
    error.textContent = message || "Upload failed.";
    error.hidden = false;
  }

  function clearUploadError(form) {
    var error = uploadError(form);
    if (!error) {
      return;
    }
    error.textContent = "";
    error.hidden = true;
  }

  function assetText(asset, key, fallback) {
    if (!asset || typeof asset[key] !== "string") {
      return fallback || "";
    }
    return asset[key];
  }

  function messageForStatus(status) {
    if (status === 401 || status === 403) {
      return "Upload failed because your session or permissions changed. Refresh and try again.";
    }
    if (status === 419) {
      return "Upload failed because the form expired. Refresh and try again.";
    }
    if (status >= 500) {
      return "Upload failed because the server could not process the file.";
    }
    return "Upload failed.";
  }

  function addAssetCard(modal, asset) {
    var grid = modal ? modal.querySelector("[data-mc-asset-picker-grid]") : null;
    var url = assetText(asset, "file_url", "");
    if (!grid || !url) {
      return;
    }
    var existing = Array.prototype.slice.call(grid.querySelectorAll("[data-asset-url]")).some(function hasUrl(button) {
      return button.getAttribute("data-asset-url") === url;
    });
    if (existing) {
      return;
    }

    grid.querySelectorAll(".mc-asset-picker__empty").forEach(function removeEmpty(empty) {
      empty.remove();
    });

    var title = assetText(asset, "title", assetText(asset, "original_filename", "Asset"));
    var filename = assetText(asset, "original_filename", title);
    var extension = assetText(asset, "file_extension", "").toUpperCase();
    var dimensions = assetText(asset, "dimensions_label", "");
    var meta = (dimensions + " · " + extension).trim();
    var altText = assetText(asset, "alt_text", title);

    var article = global.document.createElement("article");
    article.className = "mc-asset-picker-card";
    article.setAttribute("data-mc-asset-picker-card", "");

    var preview = global.document.createElement("div");
    preview.className = "mc-asset-picker-card__preview";
    var image = global.document.createElement("img");
    image.src = url;
    image.alt = altText;
    preview.appendChild(image);

    var body = global.document.createElement("div");
    body.className = "mc-asset-picker-card__body";
    var strong = global.document.createElement("strong");
    strong.className = "mc-asset-picker-card__title";
    strong.textContent = title;
    var filenameNode = global.document.createElement("span");
    filenameNode.className = "mc-asset-picker-card__meta";
    filenameNode.textContent = filename;
    var metaNode = global.document.createElement("span");
    metaNode.className = "mc-asset-picker-card__meta";
    metaNode.textContent = meta;
    body.appendChild(strong);
    body.appendChild(filenameNode);
    body.appendChild(metaNode);

    var insert = global.document.createElement("button");
    insert.className = "sg-button sg-button--primary";
    insert.type = "button";
    insert.setAttribute("data-mc-asset-picker-insert", "");
    insert.setAttribute("data-asset-url", url);
    insert.setAttribute("data-asset-alt", altText);
    insert.textContent = "Insert";

    article.appendChild(preview);
    article.appendChild(body);
    article.appendChild(insert);
    grid.insertBefore(article, grid.firstChild);
  }

  function setupAssetPickers() {
    global.document.addEventListener("click", function onAssetPickerClick(event) {
      var target = event.target;
      if (!target) {
        return;
      }

      var openButton = closest(target, "[data-mc-asset-picker-open]");
      if (openButton) {
        event.preventDefault();
        open(
          openButton.getAttribute("data-mc-asset-picker-open") || "",
          openButton.getAttribute("data-mc-asset-picker-target-id") || "",
          openButton.getAttribute("data-mc-asset-picker-preview-id") || ""
        );
        return;
      }

      var clearButton = closest(target, "[data-mc-asset-picker-clear]");
      if (clearButton) {
        event.preventDefault();
        var field = global.document.getElementById(clearButton.getAttribute("data-mc-asset-picker-target-id") || "");
        var preview = global.document.getElementById(clearButton.getAttribute("data-mc-asset-picker-preview-id") || "");
        if (field) {
          field.value = "";
          field.dispatchEvent(new Event("change", { bubbles: true }));
        }
        setPreview(preview, "", "");
        return;
      }

      var closeButton = closest(target, "[data-mc-asset-picker-close]");
      if (closeButton) {
        event.preventDefault();
        close(closest(closeButton, "[data-mc-asset-picker-modal]"));
        return;
      }

      var insertButton = closest(target, "[data-mc-asset-picker-insert]");
      if (insertButton) {
        var modal = closest(insertButton, "[data-mc-asset-picker-modal]");
        if (!modal) {
          return;
        }
        event.preventDefault();
        if (assignAsset(modal, insertButton.getAttribute("data-asset-url") || "", insertButton.getAttribute("data-asset-alt") || "")) {
          close(modal);
        }
      }
    });

    global.document.addEventListener("submit", function onAssetPickerUpload(event) {
      var form = closest(event.target, "[data-mc-asset-picker-upload]");
      if (!form || !global.fetch || !global.FormData) {
        return;
      }

      event.preventDefault();
      clearUploadError(form);
      var modal = closest(form, "[data-mc-asset-picker-modal]");
      var submit = form.querySelector("[data-mc-asset-picker-upload-submit]");
      if (submit) {
        submit.disabled = true;
        submit.setAttribute("aria-busy", "true");
      }
      var uploadUrl = form.getAttribute("action") || global.location.href;

      global.fetch(uploadUrl, {
        method: "POST",
        body: new FormData(form),
        headers: {
          "Accept": "application/json",
          "X-Requested-With": "XMLHttpRequest"
        },
        credentials: "same-origin"
      }).then(function onResponse(response) {
        return response.json().then(function onJson(payload) {
          if (payload && typeof payload === "object") {
            payload.httpStatus = response.status;
          }
          if (!response.ok && (!payload || typeof payload.error !== "string" || !payload.error)) {
            return { ok: false, error: messageForStatus(response.status), httpStatus: response.status };
          }
          return payload;
        }).catch(function onInvalidJson() {
          return {
            ok: false,
            error: response.ok ? "Upload response was invalid." : messageForStatus(response.status),
            httpStatus: response.status
          };
        });
      }).then(function onPayload(payload) {
        if (!payload || payload.ok !== true || !payload.asset) {
          showUploadError(form, assetText(payload, "error", "Upload failed."));
          return;
        }
        addAssetCard(modal, payload.asset);
        assignAsset(modal, assetText(payload.asset, "file_url", ""), assetText(payload.asset, "alt_text", ""));
        form.reset();
        close(modal);
      }).catch(function onError() {
        showUploadError(form, "Upload failed. Check your connection and try again.");
      }).finally(function onFinally() {
        if (submit) {
          submit.disabled = false;
          submit.removeAttribute("aria-busy");
        }
      });
    });

    global.document.addEventListener("click", function onAssetPickerBackdrop(event) {
      var backdrop = closest(event.target, "[data-mc-asset-picker-backdrop]");
      if (!backdrop || event.target !== backdrop) {
        return;
      }
      var modal = global.document.getElementById(backdrop.getAttribute("data-mc-asset-picker-backdrop") || "");
      close(modal);
    });

    global.document.addEventListener("keydown", function onAssetPickerKeydown(event) {
      if (event.key !== "Escape") {
        return;
      }
      var modal = closest(event.target, "[data-mc-asset-picker-modal]");
      if (!modal || modal.hidden) {
        return;
      }
      event.preventDefault();
      close(modal);
    });
  }

  onReady(setupAssetPickers);
})(window);
