import { readFile } from 'node:fs/promises';
import { pathToFileURL } from 'node:url';
import { resolveModulePath } from 'exsolve';
import { dirname, join } from 'pathe';
import { extractVariantBaseClasses, resolveVariantPrefixes } from './css-provider.mjs';
import { g as resolveVarsDeep, s as simplifyCss, p as postProcessStyles, l as loadLightningCss, e as extractCssVars, b as extractUniversalVars, c as extractPerClassVars, d as extractClassStyles } from '../shared/nuxt-og-image.CA6cPvTd.mjs';
import 'node:fs';
import '@nuxt/kit';
import 'defu';
import 'nuxt-site-config/kit';
import 'ohash';
import 'pkg-types';
import 'node:crypto';
import 'oxc-walker';
import 'nuxtseo-shared/kit';
import '../../dist/runtime/logger.js';
import 'chrome-launcher';
import 'std-env';
import 'nypm';
import 'nuxtseo-shared/devtools';
import 'unstorage';
import 'unstorage/drivers/fs-lite';
import '../../dist/runtime/server/og-image/utils/css.js';
import 'magic-string';
import 'strip-literal';
import 'ufo';
import 'unplugin';
import '@vue/compiler-sfc';
import 'ofetch';
import 'ultrahtml';
import '../../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js';
import '../shared/nuxt-og-image.CJa2KCie.mjs';
import 'magicast';
import 'magicast/helpers';

const RE_GRADIENT_STOP_PREFIX = /^(from|via|to)-/;
const RE_COLOR_SHADE = /^(.+)-(\d+)$/;
const RE_CSS_COLOR_VALUE = /color:([^;}]+)/;
const RE_TO_DIRECTION = /^to-(?:[tblr]|tl|tr|bl|br)$/;
const RE_FONT_VAR = /--font-([\w-]+)\s*:/g;
let compile;
let twColors;
async function loadTw4Deps() {
  if (!compile) {
    const [, tailwindModule, colorsModule] = await Promise.all([
      loadLightningCss(),
      import('tailwindcss'),
      import('tailwindcss/colors')
    ]);
    compile = tailwindModule.compile;
    twColors = colorsModule.default || colorsModule;
  }
}
function createModuleLoader(baseDir) {
  return async (id, base) => {
    const resolved = resolveModulePath(id, {
      from: base || baseDir,
      try: true,
      suffixes: ["", "/index"],
      extensions: [".js", ".mjs", ".cjs"]
    });
    if (resolved) {
      const module2 = await import(pathToFileURL(resolved).href).then((m) => m.default || m);
      return { path: resolved, base: dirname(resolved), module: module2 };
    }
    const relativePath = join(base || baseDir, id);
    const module = await import(pathToFileURL(relativePath).href).then((m) => m.default || m).catch(() => ({}));
    return { path: relativePath, base: dirname(relativePath), module };
  };
}
function createStylesheetLoader(baseDir) {
  return async (id, base) => {
    if (id === "tailwindcss") {
      const twPath = resolveModulePath("tailwindcss/index.css", { from: baseDir, try: true });
      if (twPath) {
        const content = await readFile(twPath, "utf-8").catch(() => "");
        if (content)
          return { path: twPath, base: dirname(twPath), content };
      }
      return {
        path: "virtual:tailwindcss",
        base,
        content: "@layer theme, base, components, utilities;\n@layer utilities { @tailwind utilities; }"
      };
    }
    if (id.startsWith("./") || id.startsWith("../")) {
      const resolved2 = join(base || baseDir, id);
      const content = await readFile(resolved2, "utf-8").catch(() => "");
      return { path: resolved2, base: dirname(resolved2), content };
    }
    const resolved = resolveModulePath(id, {
      from: base || baseDir,
      conditions: ["style"],
      try: true,
      suffixes: ["", "/index"],
      extensions: [".css", ".js", ".mjs"]
    });
    if (resolved) {
      const content = await readFile(resolved, "utf-8").catch(() => "");
      return { path: resolved, base: dirname(resolved), content };
    }
    return { path: id, base, content: "" };
  };
}
function buildNuxtUiVars(vars, nuxtUiColors) {
  const colors = twColors;
  const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
  for (const [semantic, colorName] of Object.entries(nuxtUiColors)) {
    for (const shade of shades) {
      const varName = `--ui-color-${semantic}-${shade}`;
      const value = colors[colorName]?.[shade];
      if (value && !vars.has(varName))
        vars.set(varName, value);
    }
    if (!vars.has(`--ui-${semantic}`))
      vars.set(`--ui-${semantic}`, colors[colorName]?.[500] || "");
  }
  const neutral = nuxtUiColors.neutral || "slate";
  const neutralColors = colors[neutral];
  const semanticVars = {
    // Dark mode text colors (inverted from light mode)
    "--ui-text-dimmed": neutralColors?.[500] || "",
    "--ui-text-muted": neutralColors?.[400] || "",
    "--ui-text-toned": neutralColors?.[300] || "",
    "--ui-text": neutralColors?.[200] || "",
    "--ui-text-highlighted": "#ffffff",
    "--ui-text-inverted": neutralColors?.[900] || "",
    // Dark mode backgrounds
    "--ui-bg": neutralColors?.[900] || "",
    "--ui-bg-muted": neutralColors?.[800] || "",
    "--ui-bg-elevated": neutralColors?.[800] || "",
    "--ui-bg-accented": neutralColors?.[700] || "",
    "--ui-bg-inverted": "#ffffff",
    // Dark mode borders
    "--ui-border": neutralColors?.[800] || "",
    "--ui-border-muted": neutralColors?.[700] || "",
    "--ui-border-accented": neutralColors?.[700] || "",
    "--ui-border-inverted": "#ffffff"
  };
  for (const [name, value] of Object.entries(semanticVars)) {
    if (value)
      vars.set(name, value);
  }
}
let cachedCompiler = null;
let cachedCssPath = null;
let cachedVars = null;
let pendingCompiler = null;
const resolvedStyleCache = /* @__PURE__ */ new Map();
function clearTw4UserVarsCache() {
  cachedVars = null;
  resolvedStyleCache.clear();
}
function clearTw4Cache() {
  cachedCompiler = null;
  cachedCssPath = null;
  cachedVars = null;
  pendingCompiler = null;
  resolvedStyleCache.clear();
}
async function getCompiler(cssPath, nuxtUiColors) {
  if (cachedCompiler && cachedCssPath === cssPath)
    return { compiler: cachedCompiler, vars: cachedVars };
  if (pendingCompiler)
    return pendingCompiler;
  pendingCompiler = (async () => {
    await loadTw4Deps();
    const userCss = await readFile(cssPath, "utf-8");
    const baseDir = dirname(cssPath);
    const compiler = await compile(userCss, {
      loadStylesheet: createStylesheetLoader(baseDir),
      loadModule: createModuleLoader(baseDir)
    });
    const vars = /* @__PURE__ */ new Map();
    if (nuxtUiColors)
      buildNuxtUiVars(vars, nuxtUiColors);
    cachedCompiler = compiler;
    cachedCssPath = cssPath;
    cachedVars = vars;
    resolvedStyleCache.clear();
    return { compiler, vars };
  })();
  const p = pendingCompiler;
  p.finally(() => {
    pendingCompiler = null;
  });
  return p;
}
async function parseCssOutput(rawCss, vars) {
  const css = await simplifyCss(rawCss);
  for (const [name, value] of extractCssVars(css)) {
    if (!vars.has(name))
      vars.set(name, value);
  }
  for (const [name, value] of extractUniversalVars(css)) {
    if (!vars.has(name))
      vars.set(name, value);
  }
  const perClassVars = extractPerClassVars(css);
  const classes = extractClassStyles(css, { skipPrefixes: ["--"], merge: true });
  return { classes, perClassVars };
}
const LINEAR_GRADIENT_DIRECTIONS = {
  "bg-gradient-to-t": "to top",
  "bg-gradient-to-tr": "to top right",
  "bg-gradient-to-r": "to right",
  "bg-gradient-to-br": "to bottom right",
  "bg-gradient-to-b": "to bottom",
  "bg-gradient-to-bl": "to bottom left",
  "bg-gradient-to-l": "to left",
  "bg-gradient-to-tl": "to top left"
};
const RADIAL_GRADIENT_SHAPES = {
  "bg-radial": "circle at center",
  "bg-radial-at-t": "circle at top",
  "bg-radial-at-tr": "circle at top right",
  "bg-radial-at-r": "circle at right",
  "bg-radial-at-br": "circle at bottom right",
  "bg-radial-at-b": "circle at bottom",
  "bg-radial-at-bl": "circle at bottom left",
  "bg-radial-at-l": "circle at left",
  "bg-radial-at-tl": "circle at top left",
  "bg-radial-at-c": "circle at center"
};
async function resolveGradientColor(cls, vars) {
  const colorName = cls.replace(RE_GRADIENT_STOP_PREFIX, "");
  const shadeMatch = colorName.match(RE_COLOR_SHADE);
  if (shadeMatch?.[1] && shadeMatch?.[2]) {
    const varName2 = `--color-${shadeMatch[1]}-${shadeMatch[2]}`;
    const value2 = vars.get(varName2);
    if (value2) {
      const resolved = await resolveVarsDeep(value2, vars);
      if (!resolved.includes("var(")) {
        const simplified = await simplifyCss(`.x{color:${resolved}}`);
        return simplified.match(RE_CSS_COLOR_VALUE)?.[1]?.trim() ?? resolved;
      }
    }
  }
  const varName = `--color-${colorName}`;
  const value = vars.get(varName);
  if (value) {
    const resolved = await resolveVarsDeep(value, vars);
    if (!resolved.includes("var(")) {
      const simplified = await simplifyCss(`.x{color:${resolved}}`);
      return simplified.match(RE_CSS_COLOR_VALUE)?.[1]?.trim() ?? resolved;
    }
  }
  return null;
}
async function buildGradient(classes, vars) {
  const linearDir = classes.find((c) => LINEAR_GRADIENT_DIRECTIONS[c]);
  const radialShape = classes.find((c) => RADIAL_GRADIENT_SHAPES[c]);
  const fromClass = classes.find((c) => c.startsWith("from-"));
  const viaClass = classes.find((c) => c.startsWith("via-"));
  const toClass = classes.find((c) => c.startsWith("to-") && !RE_TO_DIRECTION.test(c));
  if (!linearDir && !radialShape)
    return null;
  if (!fromClass && !toClass)
    return null;
  const fromColor = fromClass ? await resolveGradientColor(fromClass, vars) : null;
  const viaColor = viaClass ? await resolveGradientColor(viaClass, vars) : null;
  const toColor = toClass ? await resolveGradientColor(toClass, vars) : null;
  if (!fromColor && !toColor)
    return null;
  const stops = [fromColor, viaColor, toColor].filter(Boolean).join(", ");
  const colorClasses = [fromClass, viaClass, toClass].filter((c) => !!c);
  if (linearDir) {
    const direction = LINEAR_GRADIENT_DIRECTIONS[linearDir];
    return {
      gradientClass: linearDir,
      value: `linear-gradient(${direction}, ${stops})`,
      colorClasses
    };
  }
  if (radialShape) {
    const shape = RADIAL_GRADIENT_SHAPES[radialShape];
    return {
      gradientClass: radialShape,
      value: `radial-gradient(${shape}, ${stops})`,
      colorClasses
    };
  }
  return null;
}
async function resolveClassesToStyles(classes, options, context) {
  const { compiler, vars } = await getCompiler(options.cssPath, options.nuxtUiColors);
  const uncached = classes.filter((c) => !resolvedStyleCache.has(c));
  if (uncached.length > 0) {
    const outputCss = compiler.build(uncached);
    const { classes: parsedClasses, perClassVars } = await parseCssOutput(outputCss, vars);
    for (const [className, rawStyles] of parsedClasses) {
      const classVars = perClassVars.get(className);
      const mergedVars = classVars ? new Map([...vars, ...classVars]) : vars;
      const styles = await postProcessStyles(rawStyles, mergedVars, void 0, context);
      if (!styles && className.startsWith("bg-gradient-")) {
        resolvedStyleCache.set(className, rawStyles);
      } else {
        resolvedStyleCache.set(className, styles);
      }
    }
    for (const c of uncached) {
      if (!resolvedStyleCache.has(c))
        resolvedStyleCache.set(c, null);
    }
  }
  const result = {};
  for (const cls of classes) {
    const resolved = resolvedStyleCache.get(cls);
    if (resolved)
      result[cls] = resolved;
  }
  const gradient = await buildGradient(classes, vars);
  if (gradient) {
    result[gradient.gradientClass] = { "background-image": gradient.value };
    for (const colorClass of gradient.colorClasses) {
      result[colorClass] = {};
    }
  }
  return result;
}
async function extractTw4Metadata(options) {
  const { compiler, vars } = await getCompiler(options.cssPath, options.nuxtUiColors);
  const userCss = await readFile(options.cssPath, "utf-8");
  const fontCandidates = Array.from(userCss.matchAll(RE_FONT_VAR), (m) => `font-${m[1]}`);
  const themeCss = compiler.build(fontCandidates);
  await parseCssOutput(themeCss, vars);
  const fontVars = {};
  const breakpoints = {};
  const colors = {};
  for (const [name, value] of vars) {
    const resolvedValue = await resolveVarsDeep(value, vars);
    if (name.startsWith("--font-")) {
      fontVars[name.slice(2)] = resolvedValue;
    } else if (name.startsWith("--breakpoint-")) {
      const px = Number.parseInt(resolvedValue.replace("px", ""), 10);
      if (!Number.isNaN(px))
        breakpoints[name.slice(13)] = px;
    } else if (name.startsWith("--color-") && !resolvedValue.includes("var(")) {
      const colorPath = name.slice(8);
      const shadeMatch = colorPath.match(RE_COLOR_SHADE);
      const simplified = await simplifyCss(`.x{color:${resolvedValue}}`);
      const hexValue = simplified.match(RE_CSS_COLOR_VALUE)?.[1]?.trim() ?? resolvedValue;
      if (shadeMatch) {
        const [, colorName, shade] = shadeMatch;
        if (colorName) {
          if (!colors[colorName])
            colors[colorName] = {};
          if (typeof colors[colorName] === "object")
            colors[colorName][shade] = hexValue;
        }
      } else {
        colors[colorPath] = hexValue;
      }
    }
  }
  return { fontVars, breakpoints, colors };
}
function createTw4Provider(options) {
  let cssPath;
  let initPromise;
  let initialized = false;
  async function init() {
    if (initialized)
      return;
    if (initPromise)
      return initPromise;
    initPromise = (async () => {
      cssPath = await options.resolveCssPath();
      if (!cssPath) {
        initialized = true;
        return;
      }
      const content = await readFile(cssPath, "utf-8");
      if (!content.includes("@theme") && !content.includes('@import "tailwindcss"'))
        cssPath = void 0;
      initialized = true;
    })();
    return initPromise;
  }
  return {
    name: "tailwind",
    async resolveClassesToStyles(classes, context) {
      await init();
      if (!cssPath)
        return {};
      const baseClasses = extractVariantBaseClasses(classes);
      const classesToResolve = [.../* @__PURE__ */ new Set([...classes, ...baseClasses])];
      const nuxtUiColors = await options.loadNuxtUiColors();
      const tw4Resolved = await resolveClassesToStyles(classesToResolve, {
        cssPath,
        nuxtUiColors
      }, context);
      const resolvedMap = new Map(Object.entries(tw4Resolved));
      return resolveVariantPrefixes(classes, resolvedMap);
    },
    async extractMetadata() {
      await init();
      if (!cssPath)
        return { fontVars: {}, breakpoints: {}, colors: {} };
      const nuxtUiColors = await options.loadNuxtUiColors();
      return extractTw4Metadata({ cssPath, nuxtUiColors });
    },
    async getVars() {
      await init();
      if (!cssPath)
        return /* @__PURE__ */ new Map();
      const nuxtUiColors = await options.loadNuxtUiColors();
      const { vars } = await getCompiler(cssPath, nuxtUiColors);
      return vars;
    },
    clearUserVarsCache: clearTw4UserVarsCache,
    clearCache: clearTw4Cache
  };
}

export { buildNuxtUiVars, clearTw4Cache, clearTw4UserVarsCache, createModuleLoader, createStylesheetLoader, createTw4Provider, extractTw4Metadata, resolveClassesToStyles };
