import { Recordable, formatBytes, sum } from '@pureadmin/utils';
import { readdir, stat } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';

/** 启动`node`进程时所在工作目录的绝对路径 */
const root: string = process.cwd();

const fileListTotal: number[] = [];

/** 获取指定文件夹中所有文件的总大小 */
const getPackageSize = (options: any) => {
	const { folder = 'dist', callback, format = true } = options;
	readdir(folder, (err, files: string[]) => {
		if (err) throw err;
		let count = 0;
		const checkEnd = () => {
			++count == files.length && callback(format ? formatBytes(sum(fileListTotal)) : sum(fileListTotal));
		};
		files.forEach((item: string) => {
			stat(`${folder}/${item}`, async (err, stats) => {
				if (err) throw err;
				if (stats.isFile()) {
					fileListTotal.push(stats.size);
					checkEnd();
				} else if (stats.isDirectory()) {
					getPackageSize({
						folder: `${folder}/${item}/`,
						callback: checkEnd,
					});
				}
			});
		});
		files.length === 0 && callback(0);
	});
};

/**
 * @description 根据可选的路径片段生成一个新的绝对路径
 * @param dir 路径片段，默认`build`
 * @param metaUrl 模块的完整`url`，如果在`build`目录外调用必传`import.meta.url`
 */
const pathResolve = (dir = '.', metaUrl = import.meta.url) => {
	// 当前文件目录的绝对路径
	const currentFileDir = dirname(fileURLToPath(metaUrl));
	// build 目录的绝对路径
	const buildDir = resolve(currentFileDir, 'build');
	// 解析的绝对路径
	const resolvedPath = resolve(currentFileDir, dir);
	// 检查解析的绝对路径是否在 build 目录内
	if (resolvedPath.startsWith(buildDir)) {
		// 在 build 目录内，返回当前文件路径
		return fileURLToPath(metaUrl);
	}
	// 不在 build 目录内，返回解析后的绝对路径
	return resolvedPath;
};

/** 处理环境变量 */
const wrapperEnv = (envConf: Recordable): any => {
	// TODO 默认值
	const ret: any = {
		VITE_BASE_API: '',
		VITE_MOCK_BASE_API: '',
		VITE_PORT: 6262,
		VITE_APP_URL: '',
		VITE_APP_MOCK_URL: '',
		VITE_CDN: false,
	};

	for (const envName of Object.keys(envConf)) {
		let realName = envConf[envName].replace(/\\n/g, '\n');
		realName = realName === 'true' ? true : realName === 'false' ? false : realName;

		if (envName === 'VITE_PORT') {
			realName = Number(realName);
		}
		ret[envName] = realName;
		if (typeof realName === 'string') {
			process.env[envName] = realName;
		} else if (typeof realName === 'object') {
			process.env[envName] = JSON.stringify(realName);
		}
	}

	return ret;
};

export { getPackageSize, pathResolve, root, wrapperEnv };
