// lib/index.ts
import Color from "color";
import plugin from "tailwindcss/plugin";
import forEach from "lodash.foreach";
import flatten from "flat";
var SCHEME = Symbol("color-scheme");
var emptyConfig = {};
var resolveTwcConfig = (config = emptyConfig, {
  produceCssVariable = defaultProduceCssVariable,
  produceThemeClass = defaultProduceThemeClass,
  produceThemeVariant = produceThemeClass,
  defaultTheme,
  strict = false
} = {}) => {
  const resolved = {
    variants: [],
    utilities: {},
    colors: {}
  };
  const configObject = typeof config === "function" ? config({ dark, light }) : config;
  forEach(configObject, (colors, themeName) => {
    const themeClassName = produceThemeClass(themeName);
    const themeVariant = produceThemeVariant(themeName);
    const flatColors = flattenColors(colors);
    resolved.variants.push({
      name: themeVariant,
      // tailwind will generate only the first matched definition
      definition: [
        generateVariantDefinitions(`.${themeClassName}`),
        generateVariantDefinitions(`[data-theme='${themeName}']`),
        generateRootVariantDefinitions(themeName, defaultTheme)
      ].flat()
    });
    const cssSelector = `.${themeClassName},[data-theme="${themeName}"]`;
    resolved.utilities[cssSelector] = colors[SCHEME] ? { "color-scheme": colors[SCHEME] } : {};
    forEach(flatColors, (colorValue, colorName) => {
      if (colorName === SCHEME)
        return;
      const safeColorName = escapeChars(colorName, "/");
      let [h, s, l, defaultAlphaValue] = [0, 0, 0, 1];
      try {
        [h, s, l, defaultAlphaValue] = toHslaArray(colorValue);
      } catch (error) {
        const message = `\r
Warning - In theme "${themeName}" color "${colorName}". ${error.message}`;
        if (strict) {
          throw new Error(message);
        }
        return console.error(message);
      }
      const twcColorVariable = produceCssVariable(safeColorName);
      const twcOpacityVariable = `${produceCssVariable(safeColorName)}-opacity`;
      const hslValues = `${h} ${s}% ${l}%`;
      resolved.utilities[cssSelector][twcColorVariable] = hslValues;
      addRootUtilities(resolved.utilities, {
        key: twcColorVariable,
        value: hslValues,
        defaultTheme,
        themeName
      });
      if (typeof defaultAlphaValue === "number") {
        const alphaValue = defaultAlphaValue.toFixed(2);
        resolved.utilities[cssSelector][twcOpacityVariable] = alphaValue;
        addRootUtilities(resolved.utilities, {
          key: twcOpacityVariable,
          value: alphaValue,
          defaultTheme,
          themeName
        });
      }
      resolved.colors[colorName] = ({ opacityVariable, opacityValue }) => {
        if (!isNaN(+opacityValue)) {
          return `hsl(var(${twcColorVariable}) / ${opacityValue})`;
        }
        if (opacityVariable) {
          return `hsl(var(${twcColorVariable}) / var(${twcOpacityVariable}, var(${opacityVariable})))`;
        }
        return `hsl(var(${twcColorVariable}) / var(${twcOpacityVariable}, 1))`;
      };
    });
  });
  return resolved;
};
var createThemes = (config = emptyConfig, options = {}) => {
  const resolved = resolveTwcConfig(config, options);
  return plugin(
    ({ addUtilities, addVariant }) => {
      addUtilities(resolved.utilities);
      resolved.variants.forEach(({ name, definition }) => addVariant(name, definition));
    },
    // extend the colors config
    {
      theme: {
        extend: {
          // @ts-ignore tailwind types are broken
          colors: resolved.colors
        }
      }
    }
  );
};
function escapeChars(str, ...chars) {
  let result = str;
  for (let char of chars) {
    const regexp = new RegExp(char, "g");
    result = str.replace(regexp, "\\" + char);
  }
  return result;
}
function flattenColors(colors) {
  const flatColorsWithDEFAULT = flatten(colors, {
    safe: true,
    delimiter: "-"
  });
  return Object.entries(flatColorsWithDEFAULT).reduce((acc, [key, value]) => {
    acc[key.replace(/\-DEFAULT$/, "")] = value;
    return acc;
  }, {});
}
function toHslaArray(colorValue) {
  return Color(colorValue).hsl().round(1).array();
}
function defaultProduceCssVariable(themeName) {
  return `--twc-${themeName}`;
}
function defaultProduceThemeClass(themeName) {
  return themeName;
}
function dark(colors) {
  return {
    ...colors,
    [SCHEME]: "dark"
  };
}
function light(colors) {
  return {
    ...colors,
    [SCHEME]: "light"
  };
}
function generateVariantDefinitions(selector) {
  return [
    `${selector}&`,
    `:is(${selector} > &:not([data-theme]))`,
    `:is(${selector} &:not(${selector} [data-theme]:not(${selector}) * ))`,
    `:is(${selector}:not(:has([data-theme])) &:not([data-theme]))`
  ];
}
function generateRootVariantDefinitions(themeName, defaultTheme) {
  const baseDefinitions = [
    `:root&`,
    `:is(:root > &:not([data-theme]))`,
    `:is(:root &:not([data-theme] *):not([data-theme]))`
  ];
  if (typeof defaultTheme === "string" && themeName === defaultTheme) {
    return baseDefinitions;
  }
  if (typeof defaultTheme === "object" && themeName === defaultTheme.light) {
    return baseDefinitions.map(
      (definition) => `@media (prefers-color-scheme: light){${definition}}`
    );
  }
  if (typeof defaultTheme === "object" && themeName === defaultTheme.dark) {
    return baseDefinitions.map(
      (definition) => `@media (prefers-color-scheme: dark){${definition}}`
    );
  }
  return [];
}
function addRootUtilities(utilities, {
  key,
  value,
  defaultTheme,
  themeName
}) {
  if (!defaultTheme)
    return;
  if (typeof defaultTheme === "string") {
    if (themeName === defaultTheme) {
      if (!utilities[":root"]) {
        utilities[":root"] = {};
      }
      utilities[":root"][key] = value;
    }
  } else if (themeName === defaultTheme.light) {
    if (!utilities["@media (prefers-color-scheme: light)"]) {
      utilities["@media (prefers-color-scheme: light)"] = {
        ":root": {}
      };
    }
    utilities["@media (prefers-color-scheme: light)"][":root"][key] = value;
  } else if (themeName === defaultTheme.dark) {
    if (!utilities["@media (prefers-color-scheme: dark)"]) {
      utilities["@media (prefers-color-scheme: dark)"] = {
        ":root": {}
      };
    }
    utilities["@media (prefers-color-scheme: dark)"][":root"][key] = value;
  }
}
export {
  createThemes,
  resolveTwcConfig
};
//# sourceMappingURL=index.mjs.map