import { createResolver } from "@nuxt/kit";
import type { NuxtConfig } from "@nuxt/schema";
import { defineNuxtConfig } from "nuxt/config";
import type { LoggingFunction, RollupLog } from "rollup";

const { resolve: resolveLayer } = createResolver(import.meta.url);

export default defineNuxtConfig({
  // @tresjs/nuxt is not included here because SwMedia3D is excluded from auto-import
  // to prevent bundling heavy 3D libraries in the initial bundle.
  // If you need 3D support, add "@tresjs/nuxt" to your app's nuxt.config.ts modules array
  // and dynamically import SwMedia3D using defineAsyncComponent.
  //
  // @unocss/nuxt is not included here either. This layer only ships CMS components,
  // the UnoCSS setup lives in @shopware/unocss-design-tokens-layer (or your own config),
  // so apps that don't use UnoCSS can still extend this layer.
  modules: ["@nuxt/image"],

  hooks: {
    "components:extend"(components) {
      // Exclude SwMedia3D from auto-import to prevent bundling heavy 3D libraries
      // It should be dynamically imported when needed using defineAsyncComponent.
      const index = components.findIndex(
        (c) =>
          c.pascalName === "SwMedia3D" ||
          c.kebabName === "sw-media3-d" ||
          c.filePath?.includes("SwMedia3D.vue"),
      );
      if (index > -1) {
        components.splice(index, 1);
      }
    },
  },

  // @ts-ignore - @nuxt/image config may not be typed in some layer contexts
  image: {
    quality: 90,
    format: ["webp", "avif", "jpg"],
    // Custom Shopware provider that maps Nuxt Image modifiers to Shopware query parameters
    provider: "shopware",
    providers: {
      shopware: {
        name: "shopware",
        provider: resolveLayer("./app/providers/shopware.ts"),
      },
    },

    // Responsive breakpoints matching UnoCSS
    screens: {
      xs: 320,
      sm: 640,
      md: 768,
      lg: 1024,
      xl: 1280,
      xxl: 1536,
    },

    // Presets for common CMS use cases
    presets: {
      productCard: {
        modifiers: {
          format: "webp",
          quality: 90,
          fit: "cover",
        },
      },
      productDetail: {
        modifiers: {
          format: "webp",
          quality: 90,
          fit: "contain",
        },
      },
      thumbnail: {
        modifiers: {
          format: "webp",
          quality: 90,
          width: 150,
          height: 150,
          fit: "cover",
        },
      },
      hero: {
        modifiers: {
          format: "webp",
          quality: 95,
          fit: "cover",
        },
      },
    },
  },

  components: [
    {
      path: resolveLayer("./app/components"),
      pattern: "Sw*",
      extensions: [".vue"],
      global: true,
    },
    {
      path: resolveLayer("./app/components/ui"),
      extensions: [".vue"],
      prefix: "Sw",
      global: true,
    },
    {
      path: resolveLayer("./app/components/public"),
      pathPrefix: false,
      global: true,
      extensions: [".vue"],
    },
  ],
  alias: {
    "@cms-assets": resolveLayer("./app/assets"),
  },
  build: {
    transpile: ["@shopware/cms-base-layer"],
  },
  vite: {
    optimizeDeps: {
      include: ["xss"],
    },
    build: {
      // Async SwMedia3D/three chunk is ~977 kB after minify; that split is intentional.
      chunkSizeWarningLimit: 1000,
    },
  },
  nitro: {
    rollupConfig: {
      // @vueuse/shared still embeds @__NO_SIDE_EFFECTS__ inside JSDoc (injectLocal).
      // Nitro/Rollup treats that as a misplaced annotation. Track upstream vueuse.
      onwarn(warning: RollupLog, warn: LoggingFunction) {
        if (
          warning.message?.includes("annotation that Rollup cannot interpret")
        ) {
          return;
        }
        warn(warning);
      },
    },
  },
  telemetry: {
    enabled: false,
  },
}) as NuxtConfig;
