/**
 * 从两套 iconfont CDN CSS（与 setIconfont 历史配置一致）合并类名与 unicode，
 * 生成 iconfont.json + 双字体 iconfont.css，并下载 woff2/ttf 到 src/assets/iconfont。
 * 规则顺序：2298093 为基础，3882322 覆盖同名类（与页面先插 229 再插 388 时一致）。
 *
 * 使用：node scripts/merge-iconfont-from-cdn.mjs
 */
import fs from 'node:fs';
import path from 'node:path';
import https from 'node:https';
import { fileURLToPath } from 'node:url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const root = path.resolve(__dirname, '..');
const outDir = path.join(root, 'src', 'assets', 'iconfont');

const URL_229_CSS = 'https://at.alicdn.com/t/font_2298093_y6u00apwst.css';
const URL_388_CSS = 'https://at.alicdn.com/t/c/font_3882322_9ah7y8m9175.css';

const FONT_FILES = [
	{ url: 'https://at.alicdn.com/t/font_2298093_y6u00apwst.woff2?t=1627014681704', name: 'font-2298093.woff2' },
	{ url: 'https://at.alicdn.com/t/font_2298093_y6u00apwst.ttf?t=1627014681704', name: 'font-2298093.ttf' },
	{ url: 'https://at.alicdn.com/t/c/font_3882322_9ah7y8m9175.woff2?t=1676037377315', name: 'font-3882322.woff2' },
	{ url: 'https://at.alicdn.com/t/c/font_3882322_9ah7y8m9175.ttf?t=1676037377315', name: 'font-3882322.ttf' },
];

function fetchText(url) {
	return new Promise((resolve, reject) => {
		https
			.get(url, (res) => {
				if (res.statusCode === 301 || res.statusCode === 302) {
					fetchText(res.headers.location).then(resolve).catch(reject);
					return;
				}
				if (res.statusCode !== 200) {
					reject(new Error(`GET ${url} ${res.statusCode}`));
					return;
				}
				const chunks = [];
				res.on('data', (c) => chunks.push(c));
				res.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
			})
			.on('error', reject);
	});
}

function downloadFile(url, dest) {
	return new Promise((resolve, reject) => {
		const file = fs.createWriteStream(dest);
		https
			.get(url, (res) => {
				if (res.statusCode === 301 || res.statusCode === 302) {
					file.close();
					fs.unlink(dest, () => {});
					downloadFile(res.headers.location, dest).then(resolve).catch(reject);
					return;
				}
				if (res.statusCode !== 200) {
					file.close();
					fs.unlink(dest, () => {});
					reject(new Error(`GET ${url} ${res.statusCode}`));
					return;
				}
				res.pipe(file);
				file.on('finish', () => file.close(resolve));
			})
			.on('error', (e) => {
				file.close();
				fs.unlink(dest, () => {});
				reject(e);
			});
	});
}

/** @returns {Map<string, string>} className (e.g. icon-foo) -> hex 如 e670（无反斜杠） */
function parseIconRules(css) {
	const map = new Map();
	const re = /\.(icon-[a-zA-Z0-9_-]+):before\s*\{[^}]*?content:\s*"([^"]+)"/g;
	let m;
	while ((m = re.exec(css))) {
		let hex = m[2].replace(/^\\+/, '');
		map.set(m[1], hex);
	}
	return map;
}

/** 合并：388 覆盖 229 */
function mergeMaps(base229, overlay388) {
	const unicode = new Map(base229);
	const source = new Map();
	for (const k of base229.keys()) source.set(k, '2298093');
	for (const [k, v] of overlay388) {
		unicode.set(k, v);
		source.set(k, '3882322');
	}
	return { unicode, source };
}

function buildCss({ unicode, source }) {
	const lines = [
		'/* 由 scripts/merge-iconfont-from-cdn.mjs 生成；双字体与历史双 CDN 叠加顺序一致（388 覆盖同名类） */',
		'@font-face {',
		'  font-family: "iconfont-2298093";',
		"  src: url('./font-2298093.woff2') format('woff2'),",
		"       url('./font-2298093.ttf') format('truetype');",
		'}',
		'@font-face {',
		'  font-family: "iconfont-3882322";',
		"  src: url('./font-3882322.woff2') format('woff2'),",
		"       url('./font-3882322.ttf') format('truetype');",
		'}',
		'.iconfont {',
		'  font-size: 16px;',
		'  font-style: normal;',
		'  -webkit-font-smoothing: antialiased;',
		'  -moz-osx-font-smoothing: grayscale;',
		'}',
		'',
	];
	const sorted = [...unicode.entries()].sort((a, b) => a[0].localeCompare(b[0]));
	for (const [cls, hex] of sorted) {
		const fam = source.get(cls) === '3882322' ? 'iconfont-3882322' : 'iconfont-2298093';
		const short = cls.replace(/^icon-/, '');
		lines.push(`.${cls}:before {`);
		lines.push(`  font-family: "${fam}" !important;`);
		lines.push(`  content: "\\${hex}";`);
		lines.push('}');
		lines.push('');
	}
	return lines.join('\n');
}

function buildJson({ unicode, source }) {
	const glyphs = [...unicode.entries()]
		.sort((a, b) => a[0].localeCompare(b[0]))
		.map(([cls, hex], idx) => {
			const font_class = cls.replace(/^icon-/, '');
			const dec = parseInt(hex, 16);
			return {
				icon_id: String(100000 + idx),
				name: font_class,
				font_class,
				unicode: hex,
				unicode_decimal: dec,
				_source_project: source.get(cls),
			};
		});
	// e-icon-picker / 后端若校验字段，去掉非标准字段
	for (const g of glyphs) delete g._source_project;

	return {
		id: 'merged-2298093-3882322',
		name: 'dvadmin3-merged',
		font_family: 'iconfont',
		css_prefix_text: 'icon-',
		description: '合并自 iconfont 项目 2298093 + 3882322，与菜单 icon 字段一致',
		glyphs,
	};
}

async function main() {
	fs.mkdirSync(outDir, { recursive: true });
	console.log('Fetching CSS…');
	const [css229, css388] = await Promise.all([fetchText(URL_229_CSS), fetchText(URL_388_CSS)]);
	const map229 = parseIconRules(css229);
	const map388 = parseIconRules(css388);
	const merged = mergeMaps(map229, map388);
	console.log(`Icons: 2298093=${map229.size}, 3882322=${map388.size}, merged=${merged.unicode.size}`);

	console.log('Downloading font files…');
	for (const f of FONT_FILES) {
		const dest = path.join(outDir, f.name);
		await downloadFile(f.url, dest);
		console.log('  saved', f.name);
	}

	const cssOut = buildCss(merged);
	const jsonOut = buildJson(merged);
	fs.writeFileSync(path.join(outDir, 'iconfont.css'), cssOut, 'utf8');
	fs.writeFileSync(path.join(outDir, 'iconfont.json'), JSON.stringify(jsonOut, null, 2), 'utf8');
	console.log('Wrote iconfont.css, iconfont.json');
}

main().catch((e) => {
	console.error(e);
	process.exit(1);
});
