"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.parseXcss = void 0;
exports.xcss = xcss;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _react = require("@emotion/react");
var _mediaHelper = require("../responsive/media-helper");
var _styleMaps = require("./style-maps.partial");
/* eslint-disable @atlaskit/design-system/ensure-design-token-usage */

var tokensMap = {
  backgroundColor: _styleMaps.backgroundColorMap,
  blockSize: _styleMaps.dimensionMap,
  borderColor: _styleMaps.borderColorMap,
  borderRadius: _styleMaps.borderRadiusMap,
  borderWidth: _styleMaps.borderWidthMap,
  bottom: _styleMaps.spaceMap,
  boxShadow: _styleMaps.shadowMap,
  color: _styleMaps.textColorMap,
  columnGap: _styleMaps.spaceMap,
  gap: _styleMaps.spaceMap,
  height: _styleMaps.dimensionMap,
  inlineSize: _styleMaps.dimensionMap,
  inset: _styleMaps.spaceMap,
  insetBlock: _styleMaps.spaceMap,
  insetBlockEnd: _styleMaps.spaceMap,
  insetBlockStart: _styleMaps.spaceMap,
  insetInline: _styleMaps.spaceMap,
  insetInlineEnd: _styleMaps.spaceMap,
  insetInlineStart: _styleMaps.spaceMap,
  margin: _styleMaps.spaceMap,
  marginBlock: _styleMaps.spaceMap,
  marginBlockEnd: _styleMaps.spaceMap,
  marginBlockStart: _styleMaps.spaceMap,
  marginInline: _styleMaps.spaceMap,
  marginInlineEnd: _styleMaps.spaceMap,
  marginInlineStart: _styleMaps.spaceMap,
  left: _styleMaps.spaceMap,
  maxBlockSize: _styleMaps.dimensionMap,
  maxHeight: _styleMaps.dimensionMap,
  maxInlineSize: _styleMaps.dimensionMap,
  maxWidth: _styleMaps.dimensionMap,
  minBlockSize: _styleMaps.dimensionMap,
  minHeight: _styleMaps.dimensionMap,
  minInlineSize: _styleMaps.dimensionMap,
  minWidth: _styleMaps.dimensionMap,
  outlineOffset: _styleMaps.spaceMap,
  outlineWidth: _styleMaps.borderWidthMap,
  outlineColor: _styleMaps.borderColorMap,
  padding: _styleMaps.spaceMap,
  paddingBlock: _styleMaps.spaceMap,
  paddingBlockEnd: _styleMaps.spaceMap,
  paddingBlockStart: _styleMaps.spaceMap,
  paddingBottom: _styleMaps.spaceMap,
  paddingInline: _styleMaps.spaceMap,
  paddingInlineEnd: _styleMaps.spaceMap,
  paddingInlineStart: _styleMaps.spaceMap,
  paddingLeft: _styleMaps.spaceMap,
  paddingRight: _styleMaps.spaceMap,
  paddingTop: _styleMaps.spaceMap,
  right: _styleMaps.spaceMap,
  rowGap: _styleMaps.spaceMap,
  top: _styleMaps.spaceMap,
  width: _styleMaps.dimensionMap,
  zIndex: _styleMaps.layerMap
};
var uniqueSymbol = Symbol('UNSAFE_INTERNAL_styles');
var isSafeEnvToThrow = function isSafeEnvToThrow() {
  return (typeof process === "undefined" ? "undefined" : (0, _typeof2.default)(process)) === 'object' && (0, _typeof2.default)(process.env) === 'object' && process.env.NODE_ENV !== 'production';
};
var reNestedSelectors = /(\.|\s|&+|\*\>|#|\[.*\])/;
var rePseudos = /^::?.*$/;
var reMediaQuery = /^@media .*$/;

/**
 * Reduce our media queries into a safe string for regex comparison.
 */
var reValidMediaQuery = new RegExp("^(".concat(Object.values(_mediaHelper.media.above).map(function (mediaQuery) {
  return mediaQuery.replace(/[.()]/g, '\\$&');
} // Escape the ".", "(", and ")" in the media query syntax.
).join('|'), ")$"));
var transformStyles = function transformStyles(styleObj) {
  if (!styleObj || (0, _typeof2.default)(styleObj) !== 'object') {
    return styleObj;
  }

  // If styles are defined as a CSSObject[], recursively call on each element until we reach CSSObject
  if (Array.isArray(styleObj)) {
    return styleObj.map(transformStyles);
  }

  // Modifies styleObj in place. Be careful.
  Object.entries(styleObj).forEach(function (_ref) {
    var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
      key = _ref2[0],
      value = _ref2[1];
    if (isSafeEnvToThrow()) {
      // We don't support `.class`, `[data-testid]`, `> *`, `#some-id`
      if (reNestedSelectors.test(key) && !reValidMediaQuery.test(key)) {
        throw new Error("Styles not supported for key '".concat(key, "'."));
      }
    }

    // If key is a pseudo class or a pseudo element, then value should be an object.
    // So, call transformStyles on the value
    if (rePseudos.test(key)) {
      styleObj[key] = transformStyles(value);
      return;
    }
    if (reMediaQuery.test(key)) {
      // @ts-expect-error
      styleObj[key] = transformStyles(value);
      return;
    }

    // We have now dealt with all the special cases, so,
    // check whether what remains is a style property
    // that can be transformed.
    if (!(key in tokensMap)) {
      return;
    }
    var tokenValue = tokensMap[key][value];
    styleObj[key] = tokenValue !== null && tokenValue !== void 0 ? tokenValue : value;
  });
  return styleObj;
};
var baseXcss = function baseXcss(style) {
  var transformedStyles = transformStyles(style);
  return (0, _defineProperty2.default)({}, uniqueSymbol, (0, _react.css)(transformedStyles));
};

/**
 * @internal used in primitives
 * @returns a collection of styles that can be applied to the respective primitive
 */

var parseXcss = function parseXcss(args) {
  if (Array.isArray(args)) {
    return args.map(function (x) {
      return x && parseXcss(x);
    }).filter(Boolean);
  }
  var styles = args[uniqueSymbol];
  if ((typeof process === "undefined" ? "undefined" : (0, _typeof2.default)(process)) && process.env.NODE_ENV === 'development' && typeof styles === 'undefined') {
    throw new Error('Styles generated from unsafe source, use the `xcss` export from `@atlaskit/primitives`.');
  }
  return styles;
};

// Media queries should not contain nested media queries

// Pseudos should not contain nested pseudos, or media queries
exports.parseXcss = parseXcss;
// unused private functions only so we can extract the return type from a generic function
var boxWrapper = function boxWrapper(style) {
  return xcss(style);
};
var spaceWrapper = function spaceWrapper(style) {
  return xcss(style);
};
/**
 * ### xcss
 *
 * `xcss` is a safer, tokens-first approach to CSS-in-JS. It allows token-backed values for
 * CSS application.
 *
 * ```tsx
 * const styles = xcss({
 *   padding: 'space.100'
 * })
 * ```
 */
function xcss(style) {
  return baseXcss(style);
}