import type { Router } from 'vue-router';

/** 快捷入口一项：数据来自侧栏子菜单（叶子路由） */
export interface QuickEntryMenuOption {
	id: string;
	title: string;
	iconClass: string;
	/** 与菜单 web_path 一致，用于 router.push */
	path: string;
	/** 可选：无 path 时用组件路径匹配（一般不用） */
	viewImportHints?: string[];
}

/** 首页快捷入口格子数量（一排展示个数） */
export const QUICK_ENTRY_SLOT_COUNT = 5;

/** 升级后重新按默认五项初始化（修复旧版 path 匹配不到课表/全部用户时乱序填充的问题） */
export const QUICK_ENTRY_STORAGE_KEY = 'screenconsole_quick_entry_v2';

export interface QuickEntryPersistShape {
	/** 与 QuickEntryMenuOption.id 一致，当前实现为路由 path */
	menuIds: string[];
	highlightIndex: number;
}

/** 侧栏 meta.icon → 快捷卡片 `<i class="...">` */
export function mapSidebarIconToQuickClass(icon?: string): string {
	if (!icon || !String(icon).trim()) return 'fa fa-file-text-o';
	return icon.trim();
}

function resolveMenuTitle(item: RouteItem, translateTitle: (key: string) => string): string {
	const key = item.meta?.title;
	if (key) return translateTitle(key);
	if (typeof item.name === 'string' && item.name) return item.name;
	return item.path || '';
}

/**
 * 收集侧栏中可点击的叶子菜单（与 Vertical 菜单展示逻辑一致：有子则只下钻，无子则为页面）
 */
export function collectLeafMenuItems(routes: RouteItem[]): RouteItem[] {
	const out: RouteItem[] = [];

	for (const item of routes) {
		if (item.meta?.isHide) continue;

		const path = item.path || '';
		if (path === '/home' || path === '/') continue;

		/* 新窗口外链，与侧栏 a 标签行为一致，不参与 router 快捷跳转 */
		if (item.meta?.isLink && !item.meta?.isIframe) continue;

		const rawChildren = item.children || [];
		const children = rawChildren.filter((c) => !c.meta?.isHide);

		if (children.length > 0) {
			out.push(...collectLeafMenuItems(children));
			continue;
		}

		/* 仍有子项但均被隐藏：不把父级当成可跳转页 */
		if (rawChildren.length > 0 && children.length === 0) continue;

		if (!path) continue;

		out.push(item);
	}

	return out;
}

/**
 * 从当前项目 routesList（已按侧栏过滤）生成快捷入口下拉选项
 */
export function buildQuickMenuOptionsFromRoutes(
	routes: RouteItem[],
	translateTitle: (key: string) => string
): QuickEntryMenuOption[] {
	const leaves = collectLeafMenuItems(routes);
	const byPath = new Map<string, RouteItem>();

	for (const item of leaves) {
		if (!item.path || byPath.has(item.path)) continue;
		byPath.set(item.path, item);
	}

	return Array.from(byPath.values()).map((item) => ({
		id: item.path,
		path: item.path,
		title: resolveMenuTitle(item, translateTitle),
		iconClass: mapSidebarIconToQuickClass(item.meta?.icon),
	}));
}

/** 与后端 web_path 无关的小写归一化，仅用于片段匹配 */
function normalizeWebPathForMatch(path: string): string {
	return path.toLowerCase().replace(/\/+/g, '/').replace(/\/$/, '');
}

/**
 * 首次进入首页、且无本地缓存时的默认五个快捷项（顺序固定）：
 * 借用列表 → 设备列表 → 课表管理 → 全部用户 → 设备维修
 * 通过 path 片段匹配当前用户可见菜单中的对应页，避免写死完整 web_path。
 */
export function pickPreferredQuickSlotIds(opts: QuickEntryMenuOption[]): string[] {
	const used = new Set<string>();
	const out: string[] = [];

	const pick = (predicate: (normPath: string) => boolean) => {
		const o = opts.find((x) => !used.has(x.id) && predicate(normalizeWebPathForMatch(x.path)));
		if (o) {
			out.push(o.id);
			used.add(o.id);
		}
	};

	/** path 或侧栏展示标题（已 i18n）任一命中即可，避免后端 web_path 不含英文片段时匹配失败 */
	const pickPathOrTitle = (pathOk: (p: string) => boolean, titleOk: (title: string) => boolean) => {
		const o = opts.find(
			(x) =>
				!used.has(x.id) &&
				(pathOk(normalizeWebPathForMatch(x.path)) || titleOk((x.title || '').trim()))
		);
		if (o) {
			out.push(o.id);
			used.add(o.id);
		}
	};

	// 1. 借用列表（主列表页，排除审批/流程等子模块）
	pickPathOrTitle(
		(p) =>
			(p.includes('borrow/index') || /\/borrow$/i.test(p)) &&
			!p.includes('approval') &&
			!p.includes('workflow') &&
			!p.includes('processcreate') &&
			!p.includes('borrowingnotice'),
		(t) => t.includes('借用') || t.includes('借还')
	);

	// 2. 设备列表（排除维修、分类、标签等其它 device-* 页）
	pickPathOrTitle(
		(p) =>
			(p.includes('device/index') || /\/device$/.test(p)) &&
			!p.includes('devicemaintenance') &&
			!p.includes('deviceclass') &&
			!p.includes('devicepreserve') &&
			!p.includes('devicelabel') &&
			!p.includes('devicedamage') &&
			!p.includes('devicemanual'),
		(t) => t === '设备列表' || (t.includes('设备') && t.includes('列表') && !t.includes('维修'))
	);

	// 3. 课表管理（path 常见：timetablemanage / timetable / schedule）
	pickPathOrTitle(
		(p) =>
			p.includes('timetable') ||
			p.includes('schedule') ||
			p.includes('curriculum') ||
			p.includes('课表'),
		(t) => t.includes('课表') || /schedule|timetable/i.test(t)
	);

	// 4. 全部用户
	pickPathOrTitle(
		(p) =>
			p.includes('allusers') ||
			p.includes('all-user') ||
			((p.includes('/users') || p.endsWith('/users')) &&
				!p.includes('studentinfo') &&
				!p.includes('deptuser') &&
				!p.includes('role') &&
				!p.includes('account')),
		(t) => t.includes('全部用户') || /all\s*users/i.test(t)
	);

	// 5. 设备维修
	pickPathOrTitle(
		(p) => p.includes('devicemaintenance') || p.includes('device/maintenance'),
		(t) => t.includes('设备维修') || /device\s*(maintenance|repair)/i.test(t)
	);

	while (out.length < QUICK_ENTRY_SLOT_COUNT) {
		const fill = opts.find((o) => !used.has(o.id));
		if (!fill) break;
		out.push(fill.id);
		used.add(fill.id);
	}

	return out.slice(0, QUICK_ENTRY_SLOT_COUNT);
}

export function loadQuickEntryPrefs(): QuickEntryPersistShape {
	try {
		const raw = localStorage.getItem(QUICK_ENTRY_STORAGE_KEY);
		if (!raw) return { menuIds: [], highlightIndex: 0 };
		const parsed = JSON.parse(raw) as QuickEntryPersistShape;
		return {
			menuIds: Array.isArray(parsed.menuIds) ? parsed.menuIds : [],
			highlightIndex: typeof parsed.highlightIndex === 'number' ? parsed.highlightIndex : 0,
		};
	} catch {
		return { menuIds: [], highlightIndex: 0 };
	}
}

export function saveQuickEntryPrefs(data: QuickEntryPersistShape) {
	localStorage.setItem(QUICK_ENTRY_STORAGE_KEY, JSON.stringify(data));
}

/**
 * 解析可跳转 path（优先菜单 path，其次组件路径 hint 兜底）
 */
export function resolvePathForQuickOption(router: Router, option: QuickEntryMenuOption): string | null {
	if (option.path) {
		try {
			const resolved = router.resolve(option.path);
			if (resolved.matched.length) return option.path;
		} catch {
			/* 继续 hint 匹配 */
		}
	}
	const hints = (option.viewImportHints || []).map((h) => h.replace(/^\//, '').replace(/\.vue$/i, ''));
	if (!hints.length) return null;
	for (const r of router.getRoutes()) {
		if (r.meta?.isHide) continue;
		const comp = r.components?.default as unknown;
		if (typeof comp === 'function') {
			const str = Function.prototype.toString.call(comp);
			for (const hint of hints) {
				if (str.includes(hint)) return r.path;
			}
		}
	}
	return null;
}
