import { Suspense, Transition, computed, defineComponent, h, inject, mergeProps, nextTick, onMounted, provide, ref, unref } from "vue";
import { _wrapIf } from "./utils.js";
import { useRoute } from "#app/composables/router";
import { useRoute as useVueRouterRoute } from "#build/pages";
import layouts from "#build/layouts";
import { appLayoutTransition as defaultLayoutTransition } from "#build/nuxt.config.mjs";
import { useNuxtApp } from "#app";
export const LayoutMetaSymbol = Symbol("layout-meta");
export default defineComponent({
  name: "NuxtLayout",
  inheritAttrs: false,
  props: {
    name: {
      type: [String, Boolean, Object],
      default: null
    }
  },
  setup(props, context) {
    const nuxtApp = useNuxtApp();
    const injectedRoute = inject("_route");
    const route = injectedRoute === useRoute() ? useVueRouterRoute() : injectedRoute;
    const layout = computed(() => unref(props.name) ?? route.meta.layout ?? "default");
    const layoutRef = ref();
    context.expose({ layoutRef });
    return () => {
      const done = nuxtApp.deferHydration();
      const hasLayout = layout.value && layout.value in layouts;
      if (process.dev && layout.value && !hasLayout && layout.value !== "default") {
        console.warn(`Invalid layout \`${layout.value}\` selected.`);
      }
      const transitionProps = route.meta.layoutTransition ?? defaultLayoutTransition;
      return _wrapIf(Transition, hasLayout && transitionProps, {
        default: () => h(Suspense, { suspensible: true, onResolve: () => {
          nextTick(done);
        } }, {
          default: () => _wrapIf(LayoutProvider, hasLayout && {
            layoutProps: mergeProps(context.attrs, { ref: layoutRef }),
            key: layout.value,
            name: layout.value,
            shouldProvide: !props.name,
            hasTransition: !!transitionProps
          }, context.slots).default()
        })
      }).default();
    };
  }
});
const LayoutProvider = defineComponent({
  name: "NuxtLayoutProvider",
  inheritAttrs: false,
  props: {
    name: {
      type: String
    },
    layoutProps: {
      type: Object
    },
    hasTransition: {
      type: Boolean
    },
    shouldProvide: {
      type: Boolean
    }
  },
  setup(props, context) {
    if (props.shouldProvide) {
      const name = props.name;
      provide(LayoutMetaSymbol, {
        isCurrent: (route) => name === (route.meta.layout ?? "default")
      });
    }
    let vnode;
    if (process.dev && process.client) {
      onMounted(() => {
        nextTick(() => {
          if (["#comment", "#text"].includes(vnode?.el?.nodeName)) {
            console.warn(`[nuxt] \`${props.name}\` layout does not have a single root node and will cause errors when navigating between routes.`);
          }
        });
      });
    }
    return () => {
      if (process.dev && process.client && props.hasTransition) {
        vnode = h(layouts[props.name], props.layoutProps, context.slots);
        return vnode;
      }
      return h(layouts[props.name], props.layoutProps, context.slots);
    };
  }
});
