import type { IStructuredData, ITemplateOption } from "@ax/types";
import type { IOptionFilter } from ".";

const filterOptionsByDataPack = (items: ITemplateOption[], value: string) =>
	items.filter(
		(item) =>
			item.editable !== false && (item.dataPacks ? item.dataPacks.includes(value.toUpperCase()) : item.type === value),
	);

const sortByTitle = <T extends { title?: string }>(items: T[]) =>
	[...items].sort((a, b) =>
		(a.title ?? "").localeCompare(b.title ?? "", undefined, {
			sensitivity: "base",
		}),
	);

// detail duplicates = same content type with different detail templates
const removeDetailDuplicates = (arr: ITemplateOption[]) => {
	const seen = new Set();
	return arr.filter((item) => {
		const key = `${item.type}::${item.mode}`;
		if (item.mode === "detail" && seen.has(key)) {
			return false;
		}
		seen.add(key);
		return true;
	});
};

const getOptionsByDataPacks = (
	filters: IOptionFilter[],
	items: ITemplateOption[],
	structuredData: IStructuredData[],
) => {
	return filters.reduce<Record<string, ITemplateOption[]>>((acc, pack) => {
		const packItems = filterOptionsByDataPack(items, pack.value);
		const mappedPackItems = packItems.map((option) => {
			if (option.mode !== "detail") return option;
			const structuredDataItem = structuredData.find((data) => data.id.toLowerCase() === option.type.toLowerCase());
			if (structuredDataItem) {
				const title = !structuredDataItem.local
					? `Get ${structuredDataItem.title} from Global`
					: structuredDataItem?.title;
				return { ...option, title: title || "" };
			}
			return option;
		});
		const uniquePackItems = removeDetailDuplicates(mappedPackItems);

		const simpleData = uniquePackItems.filter((obj) => obj.isData);
		const pageData = uniquePackItems.filter((obj) => !obj.isData);

		acc[pack.value] = [...sortByTitle(pageData), ...sortByTitle(simpleData)];
		return acc;
	}, {});
};

export { getOptionsByDataPacks };
