import fs from "node:fs";
import path from "node:path";
import { normalizePath } from "vite";
const getConfigAlias = (settings) => {
  const { tsConfig, tsConfigPath } = settings;
  if (!tsConfig || !tsConfigPath || !tsConfig.compilerOptions) return null;
  const { baseUrl, paths } = tsConfig.compilerOptions;
  const effectiveBaseUrl = baseUrl ?? (paths ? "." : void 0);
  if (!effectiveBaseUrl) return null;
  const resolvedBaseUrl = path.resolve(path.dirname(tsConfigPath), effectiveBaseUrl);
  const aliases = [];
  if (paths) {
    for (const [alias, values] of Object.entries(paths)) {
      const find = new RegExp(
        `^${[...alias].map(
          (segment) => segment === "*" ? "(.+)" : segment.replace(/[\\^$*+?.()|[\]{}]/, "\\$&")
        ).join("")}$`
      );
      for (const value of values) {
        let matchId = 0;
        const replacement = [...normalizePath(path.resolve(resolvedBaseUrl, value))].map((segment) => segment === "*" ? `$${++matchId}` : segment === "$" ? "$$" : segment).join("");
        aliases.push({ find, replacement });
      }
    }
  }
  if (baseUrl) {
    aliases.push({
      find: /^(?!\.*\/|\.*$|\w:)(.+)$/,
      replacement: `${[...normalizePath(resolvedBaseUrl)].map((segment) => segment === "$" ? "$$" : segment).join("")}/$1`
    });
  }
  return aliases;
};
const getViteResolveAlias = (settings) => {
  const { tsConfig, tsConfigPath } = settings;
  if (!tsConfig || !tsConfigPath || !tsConfig.compilerOptions) return [];
  const { baseUrl, paths } = tsConfig.compilerOptions;
  const effectiveBaseUrl = baseUrl ?? (paths ? "." : void 0);
  if (!effectiveBaseUrl) return [];
  const resolvedBaseUrl = path.resolve(path.dirname(tsConfigPath), effectiveBaseUrl);
  const aliases = [];
  if (paths) {
    for (const [aliasPattern, values] of Object.entries(paths)) {
      const resolvedValues = values.map((v) => path.resolve(resolvedBaseUrl, v));
      const customResolver = (id) => {
        for (const resolvedValue of resolvedValues) {
          const resolved = resolvedValue.replace("*", id);
          const stats = fs.statSync(resolved, { throwIfNoEntry: false });
          if (stats && stats.isFile()) {
            return normalizePath(resolved);
          }
        }
        return null;
      };
      aliases.push({
        // Build regex from alias pattern (e.g., '@styles/*' -> /^@styles\/(.+)$/)
        // First, escape special regex chars. Then replace * with a capture group (.+)
        find: new RegExp(
          `^${aliasPattern.replace(/[\\^$+?.()|[\]{}]/g, "\\$&").replace(/\*/g, "(.+)")}$`
        ),
        replacement: aliasPattern.includes("*") ? "$1" : aliasPattern,
        customResolver
      });
    }
  }
  return aliases;
};
function configAliasVitePlugin({
  settings
}) {
  const configAlias = getConfigAlias(settings);
  if (!configAlias) return null;
  const plugin = {
    name: "astro:tsconfig-alias",
    // use post to only resolve ids that all other plugins before it can't
    enforce: "post",
    config() {
      return {
        resolve: {
          alias: getViteResolveAlias(settings)
        }
      };
    },
    resolveId: {
      filter: {
        id: {
          include: configAlias.map((alias) => alias.find),
          exclude: /(?:\0|^virtual:|^astro:)/
        }
      },
      async handler(id, importer, options) {
        for (const alias of configAlias) {
          if (alias.find.test(id)) {
            const updatedId = id.replace(alias.find, alias.replacement);
            if (updatedId.includes("*")) {
              return updatedId;
            }
            const resolved = await this.resolve(updatedId, importer, {
              skipSelf: true,
              ...options
            });
            if (resolved) return resolved;
          }
        }
      }
    }
  };
  return plugin;
}
export {
  configAliasVitePlugin as default
};
