import { navigation, pages, sites } from "@ax/api";
import { getStructuredDataTitle, isReqOk } from "@ax/helpers";
import { IFilterValue, IGetPagesParams, INavigation, IPage, ISite } from "@ax/types";

const getSite = async (siteID: number) => {
	try {
		const response: { status: number; data: ISite } = await sites.getSiteInfo(siteID);
		const { status, data } = response;
		if (isReqOk(status)) {
			return data;
		} else {
			return null;
		}
	} catch {
		return null;
	}
};

const getSiteOptions = (pages: IPage[]): IFilterValue[] => {
	const sites = pages.flatMap((page) => page.availableSites ?? []);
	const uniqueSites = new Map<number, IFilterValue>();

	for (const site of sites) {
		uniqueSites.set(site.id, {
			value: site.id.toString(),
			title: site.name,
			name: site.id,
		});
	}

	return Array.from(uniqueSites.values());
};

const addSiteOptions = async (baseOptions: IFilterValue[], siteIDs: number[]): Promise<IFilterValue[]> => {
	const existingIds = new Set(baseOptions.map((opt) => Number(opt.value)));
	const idsToAdd = siteIDs.filter((id) => !existingIds.has(id));

	if (idsToAdd.length === 0) return baseOptions;

	const newSites = await Promise.all(
		idsToAdd.map(async (id) => {
			try {
				const site = await getSite(id);
				if (!site) return null;
				return {
					value: site.id.toString(),
					title: site.name,
					name: site.id,
				} as IFilterValue;
			} catch (error) {
				console.error(`Error al obtener site ${id}:`, error);
				return null;
			}
		}),
	);

	const filteredNewSites = newSites.filter((s): s is IFilterValue => s !== null);
	if (filteredNewSites.length === 0) return baseOptions;

	return [...baseOptions, ...filteredNewSites];
};

const getStructuredDataOptions = (pages: IPage[]) => {
	return Object.values(
		pages.reduce((acc: Record<string, IFilterValue>, current) => {
			if (current.structuredData) {
				const option = {
					value: current.structuredData,
					title: getStructuredDataTitle(current.structuredData),
					name: current.structuredData,
				};
				acc = { ...acc, [option.value]: option };
			} else {
				acc = { unique: { value: "unique", title: "Base pages", name: "unique" }, ...acc };
			}
			return acc;
		}, {}),
	);
};

const getFilterSitesIds = (filters: { value: string; label: string }[]) =>
	filters
		.filter((item) => item.value !== "all")
		.map((item) => (typeof item.value === "string" ? parseInt(item.value) : item.value));

const getFilterDataIds = (filters: { value: string; label: string }[]) =>
	filters.filter((item) => item.value !== "all" && item.value !== "unique").map((item) => item.value);

const getNavigations = async (navigations: number[]) => {
	try {
		const response: { status: number; data: { items: INavigation[] } } = await navigation.getNavigations(navigations);
		const { status, data } = response;
		if (isReqOk(status)) {
			return data.items;
		} else {
			return [];
		}
	} catch {
		return [];
	}
};

const getPages = async (params: IGetPagesParams) => {
	try {
		const response: { status: number; data: { items: IPage[] } } = await pages.getPages(params);
		const { status, data } = response;
		if (isReqOk(status)) {
			return data.items;
		} else {
			return [];
		}
	} catch {
		return [];
	}
};

export {
	getSiteOptions,
	getStructuredDataOptions,
	getSite,
	addSiteOptions,
	getFilterSitesIds,
	getFilterDataIds,
	getNavigations,
	getPages,
};
