import { hasProtocol, joinURL } from "ufo";
import { parse } from "devalue";
import { useHead } from "@unhead/vue";
import { getCurrentInstance } from "vue";
import { useNuxtApp, useRuntimeConfig } from "../nuxt.js";
import { renderJsonPayloads } from "#build/nuxt.config.mjs";
export function loadPayload(url, opts = {}) {
  if (process.server) {
    return null;
  }
  const payloadURL = _getPayloadURL(url, opts);
  const nuxtApp = useNuxtApp();
  const cache = nuxtApp._payloadCache = nuxtApp._payloadCache || {};
  if (cache[payloadURL]) {
    return cache[payloadURL];
  }
  cache[payloadURL] = _importPayload(payloadURL).then((payload) => {
    if (!payload) {
      delete cache[payloadURL];
      return null;
    }
    return payload;
  });
  return cache[payloadURL];
}
export function preloadPayload(url, opts = {}) {
  const payloadURL = _getPayloadURL(url, opts);
  useHead({
    link: [
      { rel: "modulepreload", href: payloadURL }
    ]
  });
}
const extension = renderJsonPayloads ? "json" : "js";
function _getPayloadURL(url, opts = {}) {
  const u = new URL(url, "http://localhost");
  if (u.search) {
    throw new Error("Payload URL cannot contain search params: " + url);
  }
  if (u.host !== "localhost" || hasProtocol(u.pathname, { acceptRelative: true })) {
    throw new Error("Payload URL must not include hostname: " + url);
  }
  const hash = opts.hash || (opts.fresh ? Date.now() : "");
  return joinURL(useRuntimeConfig().app.baseURL, u.pathname, hash ? `_payload.${hash}.${extension}` : `_payload.${extension}`);
}
async function _importPayload(payloadURL) {
  if (process.server) {
    return null;
  }
  try {
    return renderJsonPayloads ? parsePayload(await fetch(payloadURL).then((res) => res.text())) : await import(
      /* webpackIgnore: true */
      /* @vite-ignore */
      payloadURL
    ).then((r) => r.default || r);
  } catch (err) {
    console.warn("[nuxt] Cannot load payload ", payloadURL, err);
  }
  return null;
}
export function isPrerendered() {
  const nuxtApp = useNuxtApp();
  return !!nuxtApp.payload.prerenderedAt;
}
let payloadCache = null;
export async function getNuxtClientPayload() {
  if (process.server) {
    return;
  }
  if (payloadCache) {
    return payloadCache;
  }
  const el = document.getElementById("__NUXT_DATA__");
  if (!el) {
    return {};
  }
  const inlineData = parsePayload(el.textContent || "");
  const externalData = el.dataset.src ? await _importPayload(el.dataset.src) : void 0;
  payloadCache = {
    ...inlineData,
    ...externalData,
    ...window.__NUXT__
  };
  return payloadCache;
}
export function parsePayload(payload) {
  return parse(payload, useNuxtApp()._payloadRevivers);
}
export function definePayloadReducer(name, reduce) {
  if (process.server) {
    useNuxtApp().ssrContext._payloadReducers[name] = reduce;
  }
}
export function definePayloadReviver(name, revive) {
  if (process.dev && getCurrentInstance()) {
    console.warn("[nuxt] [definePayloadReviver] This function must be called in a Nuxt plugin that is `unshift`ed to the beginning of the Nuxt plugins array.");
  }
  if (process.client) {
    useNuxtApp()._payloadRevivers[name] = revive;
  }
}
