'use strict';

const promises = require('node:fs/promises');
const node_url = require('node:url');
const exsolve = require('exsolve');
const pathe = require('pathe');
const cssProvider = require('./css-provider.cjs');
const module$1 = require('../shared/nuxt-og-image.DVJetxwr.cjs');
require('node:fs');
require('@nuxt/kit');
require('defu');
require('nuxt-site-config/kit');
require('ohash');
require('pkg-types');
require('node:crypto');
require('oxc-walker');
require('nuxtseo-shared/kit');
require('../../dist/runtime/logger.js');
require('chrome-launcher');
require('std-env');
require('nypm');
require('nuxtseo-shared/devtools');
require('unstorage');
require('unstorage/drivers/fs-lite');
require('../../dist/runtime/server/og-image/utils/css.js');
require('magic-string');
require('strip-literal');
require('ufo');
require('unplugin');
require('@vue/compiler-sfc');
require('ofetch');
require('ultrahtml');
require('../../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js');
require('../shared/nuxt-og-image.CMYbz66P.cjs');
require('magicast');
require('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([
      module$1.loadLightningCss(),
      import('tailwindcss'),
      import('tailwindcss/colors')
    ]);
    compile = tailwindModule.compile;
    twColors = colorsModule.default || colorsModule;
  }
}
function createModuleLoader(baseDir) {
  return async (id, base) => {
    const resolved = exsolve.resolveModulePath(id, {
      from: base || baseDir,
      try: true,
      suffixes: ["", "/index"],
      extensions: [".js", ".mjs", ".cjs"]
    });
    if (resolved) {
      const module2 = await import(node_url.pathToFileURL(resolved).href).then((m) => m.default || m);
      return { path: resolved, base: pathe.dirname(resolved), module: module2 };
    }
    const relativePath = pathe.join(base || baseDir, id);
    const module = await import(node_url.pathToFileURL(relativePath).href).then((m) => m.default || m).catch(() => ({}));
    return { path: relativePath, base: pathe.dirname(relativePath), module };
  };
}
function createStylesheetLoader(baseDir) {
  return async (id, base) => {
    if (id === "tailwindcss") {
      const twPath = exsolve.resolveModulePath("tailwindcss/index.css", { from: baseDir, try: true });
      if (twPath) {
        const content = await promises.readFile(twPath, "utf-8").catch(() => "");
        if (content)
          return { path: twPath, base: pathe.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 = pathe.join(base || baseDir, id);
      const content = await promises.readFile(resolved2, "utf-8").catch(() => "");
      return { path: resolved2, base: pathe.dirname(resolved2), content };
    }
    const resolved = exsolve.resolveModulePath(id, {
      from: base || baseDir,
      conditions: ["style"],
      try: true,
      suffixes: ["", "/index"],
      extensions: [".css", ".js", ".mjs"]
    });
    if (resolved) {
      const content = await promises.readFile(resolved, "utf-8").catch(() => "");
      return { path: resolved, base: pathe.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 promises.readFile(cssPath, "utf-8");
    const baseDir = pathe.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 module$1.simplifyCss(rawCss);
  for (const [name, value] of module$1.extractCssVars(css)) {
    if (!vars.has(name))
      vars.set(name, value);
  }
  for (const [name, value] of module$1.extractUniversalVars(css)) {
    if (!vars.has(name))
      vars.set(name, value);
  }
  const perClassVars = module$1.extractPerClassVars(css);
  const classes = module$1.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 module$1.resolveVarsDeep(value2, vars);
      if (!resolved.includes("var(")) {
        const simplified = await module$1.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 module$1.resolveVarsDeep(value, vars);
    if (!resolved.includes("var(")) {
      const simplified = await module$1.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 module$1.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 promises.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 module$1.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 module$1.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 promises.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 = cssProvider.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 cssProvider.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
  };
}

exports.buildNuxtUiVars = buildNuxtUiVars;
exports.clearTw4Cache = clearTw4Cache;
exports.clearTw4UserVarsCache = clearTw4UserVarsCache;
exports.createModuleLoader = createModuleLoader;
exports.createStylesheetLoader = createStylesheetLoader;
exports.createTw4Provider = createTw4Provider;
exports.extractTw4Metadata = extractTw4Metadata;
exports.resolveClassesToStyles = resolveClassesToStyles;
