(() => {
  const previewCache = {};

  function assetLabel(asset) {
    if (asset && typeof asset === "object") {
      return String(asset.name || asset.id || "").trim() || "Custom asset";
    }
    const parts = String(asset || "").split(/[\\/]/).filter(Boolean);
    const file = parts[parts.length - 1] || asset;
    const group = parts[parts.length - 2] || "";
    const stem = file.replace(/\.texture$/i, "");
    return group ? `${group} / ${stem}` : stem;
  }

  function assetPath(asset) {
    if (asset && typeof asset === "object") {
      return String(asset.textureRel || asset.texture || asset.assetDir || asset.manifestPath || "");
    }
    return String(asset || "");
  }

  function assetPreviewPath(asset) {
    if (!asset || typeof asset !== "object") return "";
    return String(asset.sourcePngPath || "");
  }

  function assetStatus(asset) {
    if (!asset || typeof asset !== "object") return "Local";
    if (asset.status === "invalid") return asset.error || "Invalid manifest";
    if (asset.active && asset.needsRefresh) return "Active in game, refresh needed";
    return asset.active ? "Active in game" : "Local";
  }

  function renderAssetList(target, values, emptyLabel, actions = {}) {
    if (!target) return;
    target.innerHTML = "";
    const rows = [...(values || [])].sort((a, b) => assetLabel(a).localeCompare(assetLabel(b)));
    if (!rows.length) {
      const empty = document.createElement("div");
      empty.className = "chip";
      const strong = document.createElement("strong");
      strong.textContent = emptyLabel;
      empty.append(strong);
      target.append(empty);
      return;
    }
    for (const rel of rows) {
      const chip = document.createElement("div");
      chip.className = "chip numberplate-asset-card";
      const preview = document.createElement("img");
      preview.className = "numberplate-asset-preview";
      preview.alt = "";
      preview.src = "./assets/placeholder.png";
      preview.dataset.numberplatePreviewPath = assetPreviewPath(rel);
      const copy = document.createElement("div");
      copy.className = "numberplate-asset-copy";
      const title = document.createElement("strong");
      title.textContent = assetLabel(rel);
      const path = document.createElement("span");
      path.textContent = assetPath(rel);
      const status = document.createElement("span");
      status.textContent = assetStatus(rel);
      copy.append(title, path, status);
      if (rel && typeof rel === "object") {
        const actionsWrap = document.createElement("div");
        actionsWrap.className = "numberplate-asset-actions";
        if (actions.onActivate) {
          const activate = document.createElement("button");
          activate.type = "button";
          activate.className = "numberplate-asset-action";
          activate.textContent = rel.active ? (rel.needsRefresh ? "Refresh Needed" : "Refresh in Game") : "Activate in Game";
          activate.addEventListener("click", () => actions.onActivate(rel));
          actionsWrap.append(activate);
        }
        if (actions.onReplace) {
          const replace = document.createElement("button");
          replace.type = "button";
          replace.className = "numberplate-asset-action secondary";
          replace.textContent = "Replace PNG";
          replace.addEventListener("click", () => actions.onReplace(rel));
          actionsWrap.append(replace);
        }
        if (rel.active && actions.onDeactivate) {
          const deactivate = document.createElement("button");
          deactivate.type = "button";
          deactivate.className = "numberplate-asset-action secondary";
          deactivate.textContent = "Deactivate from Game";
          deactivate.addEventListener("click", () => actions.onDeactivate(rel));
          actionsWrap.append(deactivate);
        }
        copy.append(actionsWrap);
      }
      chip.append(preview, copy);
      target.append(chip);
    }
    hydrateAssetPreviews(target);
  }

  async function loadPreview(path) {
    const key = String(path || "").trim();
    if (!key || !window.pywebview?.api?.load_image_preview) return "";
    if (previewCache[key]) return previewCache[key];
    const result = await window.pywebview.api.load_image_preview(key, "numberplates");
    if (!result?.ok || !result.data?.data_url) return "";
    previewCache[key] = result.data.data_url;
    return result.data.data_url;
  }

  function clearPreviewCache(path = "") {
    const key = String(path || "").trim();
    if (key) {
      delete previewCache[key];
      return;
    }
    Object.keys(previewCache).forEach((cacheKey) => delete previewCache[cacheKey]);
  }

  function hydrateAssetPreviews(scope = document) {
    scope.querySelectorAll?.("img[data-numberplate-preview-path]")?.forEach((img) => {
      const path = img.dataset.numberplatePreviewPath || "";
      if (!path) return;
      loadPreview(path).then((src) => {
        if (src) img.src = src;
      }).catch(() => {});
    });
  }

  function renderAssetLibrary(templates = {}, actions = {}) {
    renderAssetList(
      document.getElementById("numberplateBackgroundLibrary"),
      templates.backgrounds || [],
      "No custom backgrounds yet",
      actions,
    );
    renderAssetList(
      document.getElementById("numberplateFontLibrary"),
      templates.fonts || [],
      "No custom fonts yet",
      actions,
    );
  }

  window.LiveryLabNumberplates = {
    renderAssetLibrary,
    hydrateAssetPreviews,
    clearPreviewCache,
  };
})();
