import {
  isThemeColorToken,
  resolveDocumentColorToCss,
  themeColorTokenToCssVar
} from "./../../_shared/theme-color-token.js";
import { FALLBACK_COLOR_BRIGHT_DEFAULT, FALLBACK_COLOR_DEFAULT } from "../theme-constants.js";
function rgbaToHexA(rgbaArr, withAlpha) {
  const rgba = rgbaArr.map((r2, index) => {
    if (r2.indexOf("%") > -1) {
      const p = parseFloat(r2.substr(0, r2.length - 1)) / 100;
      if (index < 3) {
        return Math.round(p * 255);
      }
      return p;
    }
    return parseFloat(r2);
  });
  let r = Number(rgba[0]).toString(16), g = Number(rgba[1]).toString(16), b = Number(rgba[2]).toString(16), a = Math.round(Number(rgba[3]) * 255).toString(16);
  if (r.length === 1) {
    r = "0" + r;
  }
  if (g.length === 1) {
    g = "0" + g;
  }
  if (b.length === 1) {
    b = "0" + b;
  }
  if (a.length === 1) {
    a = "0" + a;
  }
  const isDefaultOpacity = a.toLowerCase() === "ff";
  return "#" + r + g + b + (withAlpha && !isDefaultOpacity ? a : "");
}
function srgbColorFunctionToHex(color) {
  const match = /^color\(\s*srgb\s+([^)]+)\)$/i.exec(color);
  if (!match) {
    return null;
  }
  const [rgbPart, alphaPart] = match[1].split("/").map((s) => s.trim());
  const components = rgbPart.split(/\s+/);
  if (components.length !== 3) {
    return null;
  }
  const clamp = (n, min, max) => Math.max(min, Math.min(max, n));
  const parseAlpha = (s) => s.endsWith("%") ? parseFloat(s.slice(0, -1)) / 100 : parseFloat(s);
  const channels = components.map((c) => clamp(Math.round(parseFloat(c) * 255), 0, 255));
  const alpha = alphaPart === void 0 ? 1 : clamp(parseAlpha(alphaPart), 0, 1);
  if (channels.some((n) => Number.isNaN(n)) || Number.isNaN(alpha)) {
    return null;
  }
  return rgbaToHexA([...channels.map(String), String(alpha)], true);
}
function toHexFormat(color) {
  if (isThemeColorToken(color)) {
    return color;
  }
  if (color === "transparent") {
    return FALLBACK_COLOR_BRIGHT_DEFAULT + "00";
  }
  if ((color.startsWith("rgb(") || color.startsWith("rgba(")) && color.endsWith(")")) {
    const rgba = color.replace(/^(rgba\()|^(rgb\()|(\s)|(\))$/g, "").split(",");
    if (rgba.length === 4) {
      return rgbaToHexA(rgba, true);
    } else if (rgba.length === 3) {
      return rgbaToHexA(rgba);
    } else {
      throw Error("[ricos-common] themeUtils.ts: Bad RGB / RGBA value: " + color);
    }
  }
  if (color.startsWith("color(")) {
    const hex = srgbColorFunctionToHex(color);
    if (hex) {
      return hex;
    }
  }
  if (!color.startsWith("#")) {
    throw Error(
      `[ricos-common] themeUtils.ts: Bad Hex (${color}).
      Ricos color can only accept "transparent" or a HEX formatted color as its value`
    );
  }
  return color;
}
function canTransformToHex(color) {
  if (isThemeColorToken(color)) {
    return false;
  }
  if (color === "transparent") {
    return true;
  }
  if ((color.startsWith("rgb(") || color.startsWith("rgba(")) && color.endsWith(")")) {
    const rgba = color.replace(/^(rgba\()|^(rgb\()|(\s)|(\))$/g, "").split(",");
    return rgba.length === 4 || rgba.length === 3;
  }
  if (color.startsWith("color(") && srgbColorFunctionToHex(color) !== null) {
    return true;
  }
  if (!color.startsWith("#")) {
    return false;
  }
  return true;
}
function getBrightness(hexCode) {
  const _hexCode = hexCode.replace("#", "");
  const r = parseInt(_hexCode.substr(0, 2), 16);
  const g = parseInt(_hexCode.substr(2, 2), 16);
  const b = parseInt(_hexCode.substr(4, 2), 16);
  return (r * 299 + g * 587 + b * 114) / 1e3;
}
function isBright(hexColor) {
  if (!hexColor || isThemeColorToken(hexColor)) {
    return false;
  }
  return getBrightness(hexColor) > 150;
}
function adaptForeground(actionColor, fallbackColor) {
  if (!actionColor) {
    return void 0;
  }
  return getBrightness(actionColor) < 150 ? actionColor : fallbackColor || FALLBACK_COLOR_DEFAULT;
}
function hexToRgbA(hexColor) {
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(
    hexColor.toLowerCase()
  );
  if (result) {
    return {
      r: parseInt(result[1], 16),
      g: parseInt(result[2], 16),
      b: parseInt(result[3], 16),
      a: parseInt(result[4], 16)
    };
  }
  console.error("Bad Hex");
  return void 0;
}
function toRgbTuple(hexColor) {
  if (!hexColor) {
    return void 0;
  }
  const rgb = hexToRgbA(hexColor);
  if (!rgb) {
    return void 0;
  }
  const { r, g, b } = rgb;
  return `${r}, ${g}, ${b}`;
}
function toCssRgbA(hexColor, opacity) {
  if (!hexColor) {
    return hexColor;
  }
  if (/^#([A-Fa-f\d]{2}){1,4}$/.test(hexColor)) {
    const rgb = hexToRgbA(hexColor);
    if (!rgb) {
      return void 0;
    }
    const { r, g, b, a } = rgb;
    return `rgba(${r}, ${g}, ${b}, ${opacity * (a || 1)})`;
  }
  throw new Error("[ricos-common] themeUtils.ts: Bad Hex");
}
function toCssRgb(rgbTuple) {
  return `rgb(${rgbTuple})`;
}
const toDashedKey = (str) => str.replace(/([A-Z])/g, (all, letter) => "-" + letter.toLowerCase());
const spacing = " ".repeat(4);
const toVarStrings = (varsObject) => {
  const convertToRicosKey = (key) => "--ricos-" + toDashedKey(key);
  const cleanFromSemicolons = (value) => typeof value === "string" ? value.split(";")[0] : value;
  return Object.entries(varsObject).filter((entry) => !!entry[1]).map((entry) => convertToRicosKey(entry[0]) + ": " + cleanFromSemicolons(entry[1]) + ";\n").join(spacing);
};
const buildCssVars = (parentClass, ...varObjects) => `
  ${parentClass ? `.${parentClass}` : "*"} {
    ${varObjects.map(toVarStrings).join(spacing).replace(/[\s\t]+$/, "")}
  }
`;
const buildCssVarsObj = (varObject) => {
  const convertToRicosKey = (key) => "--ricos-" + toDashedKey(key);
  return Object.entries(varObject).reduce(
    (acc, [key, value]) => ({ ...acc, [convertToRicosKey(key)]: value }),
    {}
  );
};
const anyCssColorToHex = (color, element) => {
  if (isThemeColorToken(color)) {
    return anyCssColorToHex(
      resolveDocumentColorToCss(color) ?? themeColorTokenToCssVar(color),
      element
    );
  }
  const resolvedColor = resolveCSSVar(color, element);
  if (isRgbaTuple(resolvedColor)) {
    return rgbaToHexA(resolvedColor.split(","), true);
  }
  if (isRgbTuple(resolvedColor)) {
    return rgbaToHexA(resolvedColor.split(","));
  }
  return toHexFormat(resolvedColor);
};
const resolveCSSVar = (value, element) => {
  const maxDepth = 5;
  let resolved = value;
  let depth = 0;
  const cssVarRe = /var\((--[^,\s)]+)(?:,\s*([^)]+))?\)/g;
  while (resolved.includes("var(") && depth++ < maxDepth) {
    const next = resolved.replace(cssVarRe, (match, varName, fallback) => {
      const varValue = getCssCustomPropertyValue(element, varName);
      return varValue || fallback?.trim() || match;
    });
    if (next === resolved) {
      break;
    }
    resolved = next;
  }
  return resolved;
};
const getCssCustomPropertyValue = (element, varName) => {
  let current = element;
  while (current) {
    const value = getComputedStyle(current).getPropertyValue(varName).trim();
    if (value) {
      return value;
    }
    current = current.parentElement;
  }
  return "";
};
const isRgbaTuple = (color) => {
  return color.match(/^\d{1,3},\d{1,3},\d{1,3},\d{1,3}$/) !== null;
};
const isRgbTuple = (color) => {
  return color.match(/^\d{1,3},\d{1,3},\d{1,3}$/) !== null;
};
export {
  adaptForeground,
  anyCssColorToHex,
  buildCssVars,
  buildCssVarsObj,
  canTransformToHex,
  isBright,
  toCssRgb,
  toCssRgbA,
  toDashedKey,
  toHexFormat,
  toRgbTuple,
  toVarStrings
};
//# sourceMappingURL=theme-utils.js.map
