/** @type {import('postcss-load-config').Config} */
const postcss = require('postcss');

const buildFallbackSelectorGroup = decls => [
  '@layer base {',
  '*,::backdrop,:after,:before{',
  decls.join(';'),
  '}}',
].join('');

/**
 * This plugin converts @property to normal CSS variables.
 * @property is not yet fully supported by web components
 */
const propertyToCssVariablePolyfill = (pluginOptions = {}) => {
  return {
    postcssPlugin: 'postcss-property-to-variable',
    Once(root) {
      const fallbackVariableDecls = new Map();

      root.walkAtRules('property', (atRule) => {
        const cssVariableName = atRule.params.trim();

        atRule.walkDecls((decl) => {
          if (decl.prop === 'initial-value') {
            if (!fallbackVariableDecls.has(cssVariableName)) {
              fallbackVariableDecls.set(cssVariableName, decl.value);
            }
          }
        });
      });

      if (fallbackVariableDecls.size > 0) {
        const fallbackSelectors = buildFallbackSelectorGroup(
          Array.from(fallbackVariableDecls, ([key, value]) => `${key}:${value}`)
        );

        let sourceFile;
        if (root.source) {
          if (root.source.input) {
            sourceFile = root.source.input.file || root.source.input.from;
          }
        }
        const fallbackSelectorsAst = postcss.parse(fallbackSelectors, { from: sourceFile });

        let lastImportIndex = -1;
        for (const [i, node] of root.nodes.entries()) {
          if (node.type === 'atrule' && node.name === 'import') {
            lastImportIndex = i;
          }
        }

        lastImportIndex === -1
          ? root.prepend(fallbackSelectorsAst)
          : root.insertAfter(root.nodes[lastImportIndex], fallbackSelectorsAst);
      }
    },
  };
};

propertyToCssVariablePolyfill.postcss = true;

module.exports = propertyToCssVariablePolyfill;
