import { ICodeResource, EResourceType, ECodeType } from '@cloudbase/cals';
import less from 'less';
import postcss from 'postcss';
import pxToRem from 'postcss-pxtorem';

export const remConfig = {
  rootValue: 28,
  propList: ['*'],
  unitPrecision: 5,
  selectorBlackList: [],
  replace: true,
  mediaQuery: false,
  minPixelValue: 0,
};

export async function generateStyleModule(
  modules: ICodeResource[] = [],
  cssContextWrapper?: string
) {
  const codeModules = modules.filter(
    (item) => item.type === EResourceType.CODE
  );
  const themeModuels = codeModules.filter(
    (item) => item.codeType === ECodeType.THEME
  );
  const styleModuels = codeModules.filter(
    (item) => item.codeType === ECodeType.STYLE
  );
  let processedModules = await Promise.all(
    styleModuels.map(async (module) => {
      try {
        let cssCode = module.code;
        if (cssContextWrapper) {
          cssCode = `${cssContextWrapper} { ${module.code} }`;
        } else if (themeModuels[0]?.code) {
          cssCode = themeModuels[0]?.code + cssCode;
        }
        const { css } = await less.render(cssCode, { compress: true });
        const { css: remCss } = await postcss([pxToRem(remConfig)]).process(
          css
        );
        return remCss ? { ...module, code: remCss } : null;
      } catch (e) {
        console.error(module.name, 'applyLessCodeStyle error', e);
      }
    })
  );
  return processedModules.filter((item) => !!item);
}

export async function generateStyleModuleMap(moduleMap: {
  [key: string]: {
    resources: ICodeResource[];
    cssContextWrapper?: string;
  };
}): Promise<{
  [key: string]: ICodeResource & {
    code: string;
  };
}> {
  let resultMap = {};
  let promises = [];
  const { global } = moduleMap;
  const themeModuels =
    global.resources?.filter?.((item) => item.codeType === ECodeType.THEME) ||
    [];
  for (const key in moduleMap) {
    promises.push(
      generateStyleModule(
        moduleMap[key].resources?.concat?.(
          key === 'global' ? [] : themeModuels
        ) || [],
        moduleMap[key].cssContextWrapper
      ).then((res) => {
        if (res) {
          resultMap[key] = res;
        }
      })
    );
  }
  await Promise.all(promises);
  return resultMap;
}
