import { readFileSync, writeFileSync, existsSync } from 'fs-extra';
import viteConfig, { htmlConfig } from '../../vite.config';
import { getCwdPath, successConsole, errorConsole } from '../utils';
import { GLOB_CONFIG_FILE_NAME } from '../constant';
import { hmScript } from './hm';
import HtmlMinifier from 'html-minifier';
const pkg = require('../../package.json');

const { title, addHm, cdnConf, useCdn, minify } = htmlConfig;

function injectTitle(html: string, htmlTitle: string) {
  if (/<\/title>/.test(html)) {
    return html.replace(/<\/title>/, `${htmlTitle}</title>`);
  }
  return html;
}

function injectConfigScript(html: string) {
  const tag = `\t\t<script  src='${viteConfig.base || './'}${GLOB_CONFIG_FILE_NAME}?v=${
    pkg.version
  }-${new Date().getTime()}'></script>`;

  if (/<\/head>/.test(html)) {
    return html.replace(/<\/head>/, `${tag}\n\t\t</head>`);
  }
  return html;
}

function injectHmScript(html: string) {
  if (/<head>/.test(html)) {
    return html.replace(/<head>/, `<head>\n${hmScript}`);
  }
  return html;
}

function injectCdnCss(html: string) {
  if (!cdnConf) return html;
  const { css } = cdnConf;
  if (!css || css.length === 0) return html;

  let cdnCssTag = '';
  for (const cssLink of css) {
    cdnCssTag += `<link rel="stylesheet" href="${cssLink}">`;
  }
  if (/<\/head>/.test(html)) {
    return html.replace(/<\/head>/, `${cdnCssTag}\n\t\t</head>`);
  }
  return html;
}

function injectCdnjs(html: string) {
  if (!cdnConf) return html;
  const { js } = cdnConf;
  if (!js || js.length === 0) return html;

  let cdnJsTag = '';
  for (const src of js) {
    // TODO
    // <script type="importmap">
    // { "imports": {
    //   "vue":        "https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.0/vue.esm-browser.js",
    //   "vue-router": "https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.0.0-alpha.13/vue-router.esm.js",
    //   "vuex":       "https://cdnjs.cloudflare.com/ajax/libs/vuex/4.0.0-beta.2/vuex.esm-browser.js"
    // } }
    // </script>
    cdnJsTag += `\t<script type="text/javascript" src="${src}"></script>\n`;
  }
  if (/<\/body>/.test(html)) {
    return html.replace(/<\/body>/, `${cdnJsTag}\n</body>`);
  }
  return html;
}

export async function runUpdateHtml() {
  const outDir = viteConfig.outDir || 'dist';
  const indexPath = getCwdPath(outDir, 'index.html');
  if (!existsSync(indexPath)) return;
  try {
    let processedHtml = '';
    const rawHtml = readFileSync(indexPath, 'utf-8');
    processedHtml = rawHtml;
    processedHtml = injectTitle(processedHtml, title);
    processedHtml = injectConfigScript(processedHtml);
    if (addHm) {
      processedHtml = injectHmScript(processedHtml);
    }
    if (useCdn) {
      processedHtml = injectCdnCss(processedHtml);
      processedHtml = injectCdnjs(processedHtml);
    }
    if (minify) {
      const { enable, ...miniOpt } = minify;
      if (enable) {
        processedHtml = HtmlMinifier.minify(processedHtml, miniOpt);
      }
    }

    writeFileSync(indexPath, processedHtml);
    successConsole('Update Html Successfully!');
  } catch (error) {
    errorConsole('Update Html Error\n' + error);
  }
}
