import type { Audience, Tour } from "@circuy/contracts";
import type { IdentifyAttributes } from "./types.js";

export function matchPath(pattern: string, path: string): boolean {
	const escaped = pattern
		.replace(/[.+?^${}()|[\]\\]/g, "\\$&")
		.replaceAll("*", ".*");
	return new RegExp(`^${escaped}$`).test(path);
}

export function matchAudience(
	audience: Audience | undefined,
	attrs: IdentifyAttributes,
): boolean {
	if (!audience) return true;
	if (audience.locales && audience.locales.length > 0) {
		const locale = attrs.locale;
		if (!locale || !audience.locales.includes(locale)) return false;
	}
	if (audience.match) {
		for (const [key, values] of Object.entries(audience.match)) {
			const actual = attrs[key];
			if (!actual || !values.includes(actual)) return false;
		}
	}
	return true;
}

export function pickTour(
	tours: Tour[],
	path: string,
	attrs: IdentifyAttributes,
	isSeen: (tourId: string) => boolean,
): Tour | undefined {
	const matching = tours.filter((tour) => {
		if (!matchPath(tour.trigger.urlPattern, path)) return false;
		if (!matchAudience(tour.audience, attrs)) return false;
		const frequency = tour.trigger.frequency ?? "once";
		if (frequency === "once" && isSeen(tour.id)) return false;
		return true;
	});
	matching.sort((a, b) => a.id.localeCompare(b.id));
	return matching[0];
}
