const inflightRequests = new Map()
const sessionCache = new Map()

/**
 * 同一 key 在请求进行中只发起一次（并发去重）
 */
export function dedupeRequest(key, factory) {
	if (inflightRequests.has(key)) {
		return inflightRequests.get(key)
	}
	const promise = Promise.resolve()
		.then(factory)
		.finally(() => {
			inflightRequests.delete(key)
		})
	inflightRequests.set(key, promise)
	return promise
}

/**
 * 同一会话内同一 key 只请求一次（完成后也不会再发，除非 refresh）
 */
export function oncePerSession(key, factory, { refresh = false } = {}) {
	if (refresh) {
		clearDedupeKey(key)
	}
	if (sessionCache.has(key)) {
		return sessionCache.get(key)
	}
	const promise = dedupeRequest(key, factory).catch((err) => {
		sessionCache.delete(key)
		throw err
	})
	sessionCache.set(key, promise)
	return promise
}

export function clearDedupeKey(key) {
	inflightRequests.delete(key)
	sessionCache.delete(key)
}

export function clearSessionByPrefix(prefix) {
	const keys = new Set([
		...sessionCache.keys(),
		...inflightRequests.keys()
	])
	keys.forEach((key) => {
		if (key.startsWith(prefix)) {
			clearDedupeKey(key)
		}
	})
}
