import { generateImports, resolveVuetifyBase, isObject, normalizePath, includes, transformAssetUrls } from '@vuetify/loader-shared';
export { transformAssetUrls } from '@vuetify/loader-shared';
import { createFilter } from 'vite';
import { URLSearchParams } from 'url';
import path from 'upath';
import fs from 'node:fs/promises';

function parseId(id) {
  const [pathname, query] = id.split("?");
  return {
    query: query ? Object.fromEntries(new URLSearchParams(query)) : null,
    path: pathname ?? id
  };
}
function importPlugin(options) {
  let filter;
  return {
    name: "vuetify:import",
    configResolved(config) {
      const vuetifyIdx = config.plugins.findIndex((plugin) => plugin.name === "vuetify:import");
      const vueIdx = config.plugins.findIndex((plugin) => plugin.name === "vite:vue");
      if (vuetifyIdx < vueIdx) {
        throw new Error("Vuetify plugin must be loaded after the vue plugin");
      }
      const vueOptions = config.plugins[vueIdx].api.options;
      filter = createFilter(vueOptions.include, vueOptions.exclude);
    },
    async transform(code, id) {
      const { query, path } = parseId(id);
      const isVueVirtual = query && "vue" in query;
      const isVueFile = !isVueVirtual && filter(path) && !/^import { render as _sfc_render } from ".*"$/m.test(code);
      const isVueTemplate = isVueVirtual && (query.type === "template" || query.type === "script" && query.setup === "true");
      if (isVueFile || isVueTemplate) {
        const { code: imports, source } = generateImports(code, options);
        return {
          code: source + imports,
          map: null
        };
      }
      return null;
    }
  };
}

function isSubdir(root, test) {
  const relative = path.relative(root, test);
  return relative && !relative.startsWith("..") && !path.isAbsolute(relative);
}
const PLUGIN_VIRTUAL_PREFIX = "virtual:";
const PLUGIN_VIRTUAL_NAME = "plugin-vuetify";
const VIRTUAL_MODULE_ID = `${PLUGIN_VIRTUAL_PREFIX}${PLUGIN_VIRTUAL_NAME}`;
function stylesPlugin(options) {
  const vuetifyBase = resolveVuetifyBase();
  let configFile;
  const tempFiles = /* @__PURE__ */ new Map();
  const mappings = /* @__PURE__ */ new Map();
  async function resolveCss(target) {
    let mapping = mappings.get(target);
    if (!mapping) {
      try {
        mapping = target.replace(/\.css$/, ".sass");
        await fs.access(mapping, fs.constants.R_OK);
      } catch (err) {
        if (!(err instanceof Error && "code" in err && err.code === "ENOENT"))
          throw err;
        mapping = target.replace(/\.css$/, ".scss");
      }
      mappings.set(target, mapping);
    }
    return mapping;
  }
  return {
    name: "vuetify:styles",
    enforce: "pre",
    configResolved(config) {
      if (isObject(options.styles)) {
        if (path.isAbsolute(options.styles.configFile)) {
          configFile = options.styles.configFile;
        } else {
          configFile = path.join(config.root || process.cwd(), options.styles.configFile);
        }
      }
    },
    async resolveId(source, importer, { custom }) {
      if (source === "vuetify/styles" || importer && source.endsWith(".css") && isSubdir(vuetifyBase, path.isAbsolute(source) ? source : importer)) {
        if (options.styles === "none") {
          return `${PLUGIN_VIRTUAL_PREFIX}__void__`;
        } else if (options.styles === "sass") {
          const target = await resolveCss(source);
          return this.resolve(target, importer, { skipSelf: true, custom });
        } else if (isObject(options.styles)) {
          const resolution = await this.resolve(source, importer, { skipSelf: true, custom });
          if (!resolution)
            return null;
          const target = await resolveCss(resolution.id);
          const file = path.relative(path.join(vuetifyBase, "lib"), target);
          const suffix = target.match(/\.scss/) ? ";\n" : "\n";
          const contents = `@use "${normalizePath(configFile)}"${suffix}@use "${normalizePath(target)}"${suffix}`;
          tempFiles.set(file, contents);
          return `${VIRTUAL_MODULE_ID}:${file}`;
        }
      } else if (source.startsWith(`/${PLUGIN_VIRTUAL_NAME}:`)) {
        return PLUGIN_VIRTUAL_PREFIX + source.slice(1);
      } else if (source.startsWith(`/@id/__x00__${PLUGIN_VIRTUAL_NAME}:`)) {
        return PLUGIN_VIRTUAL_PREFIX + source.slice(12);
      } else if (source.startsWith(`/${VIRTUAL_MODULE_ID}:`)) {
        return source.slice(1);
      }
      return null;
    },
    load(id) {
      if (new RegExp(`^${PLUGIN_VIRTUAL_PREFIX}__void__(\\?.*)?$`).test(id)) {
        return "";
      }
      if (id.startsWith(`${VIRTUAL_MODULE_ID}`)) {
        const file = new RegExp(`^${VIRTUAL_MODULE_ID}:(.*?)(\\?.*)?$`).exec(id)[1];
        return tempFiles.get(file);
      }
      return null;
    }
  };
}

function vuetify(_options = {}) {
  const options = {
    autoImport: true,
    styles: true,
    ..._options
  };
  const plugins = [];
  if (options.autoImport) {
    plugins.push(importPlugin(options));
  }
  if (includes(["none", "sass"], options.styles) || isObject(options.styles)) {
    plugins.push(stylesPlugin(options));
  }
  return plugins;
}
vuetify.transformAssetUrls = transformAssetUrls;

export { vuetify as default };
