import { readFile, writeFile } from 'fs/promises';
import nunjucks from 'nunjucks';
import * as prettier from 'prettier';
import prettierConfig from '../prettier.config.js';
import * as globalData from '../src/styles/data.js';

const prelude = inputFilename => `/* DO NOT EDIT THIS FILE. It is generated from "${inputFilename}" */`;

let env = nunjucks.configure({ autoescape: false });
let filenameVariables = Object.keys(globalData)
  .filter(key => key.endsWith('s'))
  .map(key => key.slice(0, -1));
let filenameVariablesRegex = RegExp(`\\{\\{\\s*(${filenameVariables.join('|')})\\s*\\}\\}`, 'g');

export async function preprocessStylesheet(inputPath) {
  const content = await readFile(inputPath, 'utf-8');
  let outputPath = inputPath.replace(/\.njk$/, '');
  let filename = outputPath.split('/').pop();

  if (filenameVariablesRegex.test(filename)) {
    // NOTE only supports a single variable right now
    filenameVariablesRegex.lastIndex = 0;
    let ret = [];

    for (let match of filename.matchAll(filenameVariablesRegex)) {
      let variable = match[1];
      let values = globalData[variable + 's'];

      for (let value of values) {
        let data = { [variable]: value };
        let css = await renderCSS(content, { data, inputPath, outputPath });

        // Now use Nunjucks *again*, to render the actual filename
        let localOutputFilePath = env.renderString(outputPath, data);

        ret.push(writeFile(localOutputFilePath, css, 'utf-8'));
      }
    }

    return Promise.all(ret);
  } else {
    let css = await renderCSS(content, { inputPath, outputPath });
    return writeFile(outputPath, css, 'utf-8');
  }

  // TODO add generated files to .gitignore?
}

export async function renderCSS(content, { data, inputPath, outputPath } = {}) {
  let inputFilename = inputPath.split('/').pop();
  data = data ? { ...globalData, ...data } : globalData;
  let css = env.renderString(content, data);

  if (prelude) {
    css = prelude(inputFilename) + '\n' + css;
  }

  css = await prettier.format(css, { ...prettierConfig, filepath: outputPath });

  return css;
}
