import {promises as fsp} from 'fs';
import {join} from 'path';
// @ts-ignore
import htmlclean from 'htmlclean';
import nunjucks from 'nunjucks';
import sass from 'sass';
import tar from 'tar';
import {generateLove, LoveVariant} from './love';

export async function entry(): Promise<void> {
  // Create all required directories for the website.
  await fsp.mkdir(join(__dirname, '../../public/css/'), {recursive: true});
  await fsp.mkdir(join(__dirname, '../../public/fonts/'), {recursive: true});
  await fsp.mkdir(join(__dirname, '../../public/images/'), {recursive: true});

  // Configure Nunjucks to use the templates for `source/pages/`.
  nunjucks.configure(join(__dirname, '../pages/'), {
    lstripBlocks: true,
    trimBlocks: true,
    throwOnUndefined: true
  });

  const love: LoveVariant[] = generateLove();

  // Write the colors to file.
  await writeJSON(join(__dirname, '../../public/love.json'), love);

  // Render the Sass to CSS.
  let css: string = sass
    .renderSync({
      file: join(__dirname, '../pages/scss/style.scss'),
      sourceMap: false
    })
    .css.toString();

  // Generate the CSS custom properties.
  const cssProperties = `:root {
  --foreground-1: ${love[0].colors.foreground1};
  --foreground-2: ${love[0].colors.foreground2};
  --background-1: ${love[0].colors.background1};
  --background-2: ${love[0].colors.background2};
${love[0].colors.accents
  .map((value, index) => `  --dark-accent-${index + 1}: ${value};`)
  .join('\n')}
${love[0].colors.grays
  .map((value, index) => `  --dark-gray-${index + 1}: ${value};`)
  .join('\n')}
${love[1].colors.accents
  .map((value, index) => `  --light-accent-${index + 1}: ${value};`)
  .join('\n')}
${love[1].colors.grays
  .map((value, index) => `  --light-gray-${index + 1}: ${value};`)
  .join('\n')}
}\n`;

  // Replace the predefined `:root` location with our properties.
  css = css.replace(/\/\* :root-insert \*\//, cssProperties);

  // Write the CSS to file.
  await fsp.writeFile(join(__dirname, '../../public/css/style.css'), css);

  // Render and write the `index.html` file.
  await fsp.writeFile(
    join(__dirname, '../../public/index.html'),
    htmlclean(nunjucks.render('index.html', {love}))
  );

  // Extract the fonts to file.
  await tar.extract({
    file: join(__dirname, '../pages/assets/Inter.tar'),
    cwd: join(__dirname, '../../public/fonts/')
  });
  await tar.extract({
    file: join(__dirname, '../pages/assets/Hasklig.tar'),
    cwd: join(__dirname, '../../public/fonts/')
  });

  console.log('Lovely!');
}

// Utility helper function to write some data to file as JSON.
export async function writeJSON(path: string, data: unknown): Promise<void> {
  await fsp.writeFile(path, JSON.stringify(data, null, 2));
}

if (require.main === module) {
  entry();
}
