"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.genJSTemplate = exports.AutoSetRootFontSizePlugin = exports.DEFAULT_OPTIONS = exports.getRootPixelCode = void 0;
const path_1 = __importDefault(require("path"));
// @ts-expect-error
const webpack_sources_1 = require("webpack-sources");
const logger_1 = require("../logger");
const url_1 = require("../url");
const util_1 = require("./util");
async function getRootPixelCode(options, isCompress = false) {
    const code = (0, exports.genJSTemplate)(options);
    if (!isCompress) {
        return code;
    }
    const { minify } = await Promise.resolve().then(() => __importStar(require('terser')));
    const { code: minifiedRuntimeCode } = await minify({
        RootPixelCode: code,
    }, {
        ecma: 5,
    });
    return minifiedRuntimeCode;
}
exports.getRootPixelCode = getRootPixelCode;
exports.DEFAULT_OPTIONS = {
    screenWidth: 375,
    rootFontSize: 50,
    maxRootFontSize: 64,
    widthQueryKey: '',
    rootFontSizeVariableName: 'ROOT_FONT_SIZE',
    excludeEntries: [],
    inlineRuntime: true,
    supportLandscape: false,
    useRootFontSizeBeyondMax: false,
};
class AutoSetRootFontSizePlugin {
    constructor(options, entries, HtmlPlugin, distDir) {
        this.name = 'AutoSetRootFontSizePlugin';
        this.options = { ...exports.DEFAULT_OPTIONS, ...(options || {}) };
        this.scriptPath = '';
        this.distDir = distDir;
        this.webpackEntries = entries;
        this.HtmlPlugin = HtmlPlugin;
    }
    async getScriptPath() {
        if (!this.scriptPath) {
            const version = await (0, util_1.getBuilderVersion)();
            this.scriptPath = path_1.default.join(this.distDir, `convert-rem.${version}.js`);
        }
        return this.scriptPath;
    }
    apply(compiler) {
        let runtimeCode;
        const getRuntimeCode = async () => {
            if (!runtimeCode) {
                const isCompress = process.env.NODE_ENV === 'production';
                runtimeCode = await getRootPixelCode(this.options, isCompress);
            }
            return runtimeCode;
        };
        if (!this.options.inlineRuntime) {
            compiler.hooks.thisCompilation.tap(this.name, (compilation) => {
                compilation.hooks.processAssets.tapPromise({
                    name: this.name,
                    stage: util_1.COMPILATION_PROCESS_STAGE.PROCESS_ASSETS_STAGE_PRE_PROCESS,
                }, async (assets) => {
                    const scriptPath = await this.getScriptPath();
                    assets[scriptPath] = new webpack_sources_1.RawSource(await getRuntimeCode(), false);
                });
            });
        }
        compiler.hooks.compilation.tap(this.name, compilation => {
            this.HtmlPlugin.getHooks(compilation).afterTemplateExecution.tapPromise(this.name, async (data) => {
                const isExclude = this.options.excludeEntries.find((item) => {
                    if (!this.webpackEntries.includes(item)) {
                        logger_1.logger.error(`convertToRem: can't find the entryName: ${item}`);
                        return false;
                    }
                    const reg = new RegExp(`(/${item}/index.html)|(/${item}.html)`, 'gi');
                    return reg.test(data.outputName);
                });
                if (isExclude) {
                    return data;
                }
                const scriptTag = (0, util_1.generateScriptTag)();
                if (this.options.inlineRuntime) {
                    data.headTags.unshift({
                        ...scriptTag,
                        innerHTML: await getRuntimeCode(),
                    });
                }
                else {
                    const publicPath = (0, util_1.getPublicPathFromCompiler)(compiler);
                    const url = (0, url_1.withPublicPath)(await this.getScriptPath(), publicPath);
                    data.headTags.unshift({
                        ...scriptTag,
                        attributes: {
                            ...scriptTag.attributes,
                            src: url,
                        },
                    });
                }
                return data;
            });
        });
    }
}
exports.AutoSetRootFontSizePlugin = AutoSetRootFontSizePlugin;
const genJSTemplate = (opts) => `function setRootPixel() {
  function getQuery(name) {
    return (new RegExp('[?&]' + name + '=([^&#\\b]+)').exec(location.search || '') || [])[1];
  }

  function setRootFontSize() {
    var widthQueryKey = '${opts.widthQueryKey}';
    var rem2px = ${opts.rootFontSize};
    var clientWidth;
    var docEl = document.documentElement;
    if (widthQueryKey && (+getQuery(widthQueryKey))) {
      clientWidth = +getQuery(widthQueryKey);
    } else {
      clientWidth = window.innerWidth && docEl.clientWidth ?
        Math.min(window.innerWidth, docEl.clientWidth) :
        (window.innerWidth || docEl.clientWidth || (document.body && document.body.clientWidth) || ${opts.screenWidth});
        ${opts.supportLandscape
    ? `
        var isLandscape = ((screen.orientation && screen.orientation.angle) || window.orientation) / 90 % 2;
        if (isLandscape) {
          var clientHeight = window.innerHeight && docEl.clientHeight ?
          Math.min(window.innerHeight, docEl.clientHeight) :
          (window.innerHeight || docEl.clientHeight || (document.body && document.body.clientHeight) || ${opts.screenWidth});

          clientWidth = Math.max(clientHeight, 350);
        }`
    : ''}
    }

    var htmlFontSizePx = (clientWidth * rem2px) / ${opts.screenWidth};
    var maxRootFontSize = ${opts.maxRootFontSize};

    ${opts.useRootFontSizeBeyondMax
    ? `htmlFontSizePx = htmlFontSizePx < maxRootFontSize ? htmlFontSizePx : rem2px ;`
    : `htmlFontSizePx = Math.min(htmlFontSizePx, maxRootFontSize);`}

    window.${opts.rootFontSizeVariableName} = htmlFontSizePx;
    docEl.style.fontSize = htmlFontSizePx + 'px';
  }

  function adjust(immediate) {
    if (immediate) {
      setRootFontSize();
      return;
    }
    setTimeout(setRootFontSize, 30);
  }

  adjust(true);

  window.addEventListener('resize', adjust, false);

  if ('onorientationchange' in window) {
    window.addEventListener('orientationchange', adjust, false);
  }
}

typeof window !== 'undefined' && setRootPixel();`;
exports.genJSTemplate = genJSTemplate;
