import { pageStatus } from "@ax/containers/PageEditor/interfaces";
import { arrayInsert, getActivatedDataPacksIds } from "@ax/helpers";
import type { IColumn, IDataPack, IPage, ISchemaField, IStructuredData } from "@ax/types";

import { config } from "components";

const schemas = config.schemas.ui;

const getTemplatesFilters = (activatedDataPacks: IDataPack[]) => {
	const activatedDataPacksIds = getActivatedDataPacksIds(activatedDataPacks);
	const { templates } = schemas;

	const staticFilters: { label: string; value: string; mode?: string }[] = Object.keys(templates)
		.filter((templateName: string) => !Array.isArray(templates[templateName].dataPacks))
		.map((templateName: string) => templates[templateName].type);

	const uniqueStaticFilters = [...new Map(staticFilters.map((item: any) => [item.value, item])).values()];
	const sortedUniqueFilters = uniqueStaticFilters.sort((a, b) => a.label.localeCompare(b.label));

	const dataPackFilters: { label: string; value: string; mode?: string }[] = [];

	Object.keys(templates)
		.filter((templateName: string) => Array.isArray(templates[templateName].dataPacks))
		.forEach((templateName: string) => {
			const { type, dataPacks } = templates[templateName];
			const isActivated = activatedDataPacksIds.some((id: string) => dataPacks.indexOf(id) >= 0);

			if (isActivated) {
				dataPacks.forEach((dataPack: string) => {
					const currentDataPack = activatedDataPacks.find(
						(activatedDataPack: IDataPack) => dataPack === activatedDataPack.id,
					);

					if (currentDataPack) {
						dataPackFilters.push({
							label: currentDataPack?.title,
							value: currentDataPack?.id,
							mode: type.mode,
						});
					}
				});
			}
		});

	return { staticFilters: sortedUniqueFilters, dataPackFilters };
};

const mapStructuredOptions = (options: any[]) => {
	const pureOptions = options.filter((option: any) => !option.fromPage);

	return pureOptions.map((option: any) => {
		const { id, title, dataPacks, editable } = option;
		return {
			name: id,
			value: id,
			title,
			type: id,
			isData: true,
			dataPacks,
			editable,
		};
	});
};

const getOptionValues = (options: IStructuredData[]) => {
	const templatesOptionsValues: any = [];
	const { templates } = schemas;

	if (!templates) return [];

	Object.keys(templates).forEach((schema: any) => {
		const currSchema = templates[schema];
		const { component, displayName, dataPacks } = currSchema;
		const type = currSchema.type?.value?.toLowerCase();
		const mode = currSchema.type?.mode;

		!!currSchema.type &&
			templatesOptionsValues.push({
				name: component,
				title: displayName,
				type,
				value: component,
				mode,
				dataPacks,
			});
	});

	return [...templatesOptionsValues, ...mapStructuredOptions(options)];
};

const getOptionFilters = (options: IStructuredData[], activatedDataPacks: IDataPack[]) => {
	const pureOptions = options.filter((option: IStructuredData) => !option.fromPage);
	const { staticFilters, dataPackFilters } = getTemplatesFilters(activatedDataPacks);
	const activatedDataPacksIds = getActivatedDataPacksIds(activatedDataPacks);

	const mappedOptions = pureOptions.flatMap((option: IStructuredData) =>
		option.dataPacks.reduce((acc: { label: string; value: string; isData: boolean }[], current: string) => {
			if (activatedDataPacksIds.includes(current)) {
				const currentDataPack = activatedDataPacks.find(
					(activatedDataPack: IDataPack) => current === activatedDataPack.id,
				);
				if (currentDataPack) {
					const option = {
						label: currentDataPack.title,
						value: currentDataPack.id,
						isData: true,
					};
					acc.push(option);
					return acc;
				}
			}
			return acc;
		}, []),
	);

	const filters = [...dataPackFilters, ...mappedOptions];
	const uniqueFilters = [...new Map(filters.map((item: any) => [item.value, item])).values()];
	const sortedUniqueFilters = uniqueFilters.sort((a, b) => a.label.localeCompare(b.label));
	return [...staticFilters, ...sortedUniqueFilters];
};

const getCurrentFilter = (structuredData: any, filter: any) =>
	structuredData.filter((dataObj: any) => dataObj.id === filter)[0];

const filterByStatus = (bulkSelection: number[], currentSitePages: IPage[]): Record<string, number[]> => {
	const notPublishedItems: number[] = [];
	const publishedItems: number[] = [];
	const draftItems: number[] = [];

	currentSitePages.forEach((page: IPage) => {
		const { id, liveStatus, haveDraftPage } = page;
		if (bulkSelection.includes(id)) {
			switch (liveStatus.status) {
				case pageStatus.OFFLINE_PENDING:
				case pageStatus.OFFLINE:
				case pageStatus.UPLOAD_PENDING:
					haveDraftPage ? draftItems.push(id) : notPublishedItems.push(id);
					break;
				case pageStatus.PUBLISHED:
					haveDraftPage ? draftItems.push(id) : publishedItems.push(id);
					break;
			}
		}
	});

	const filteredItems = {
		all: bulkSelection,
		notPublished: notPublishedItems,
		published: publishedItems,
		drafts: draftItems,
	};

	return filteredItems;
};

const getSortedListStatus = (orderPointer: string, isAscending: boolean) => {
	const sortedListStatus = {
		isAscending,
		sortedByTitle: orderPointer === "title",
		sortedByURL: orderPointer === "slug",
		sortedByDate: orderPointer === "modified",
	};

	return sortedListStatus;
};

const getColumns = (
	categoryColumns: ISchemaField[],
	isStructuredData: boolean,
	isGlobalPages: boolean,
	maxColumns: number,
): IColumn[] => {
	let defaultColumns: IColumn[] = [
		{ id: "live", title: "Live", show: true, default: true },
		{ id: "status", title: "Status", show: true, default: true },
		{ id: "translation", title: "Trans.", show: true, default: true },
	];

	if (!isStructuredData) {
		defaultColumns = [
			{ id: "type", title: "Types", show: true, default: true },
			...defaultColumns,
			{ id: "seo", title: "SEO", show: true, default: true },
		];
	}

	let availableColumns = maxColumns - defaultColumns.length;

	const extraColumns = categoryColumns.reduce((acc: IColumn[], cur: ISchemaField) => {
		acc.push({ id: cur.key, title: cur.title, show: availableColumns > 0, default: false });
		availableColumns = availableColumns - 1;
		return acc;
	}, []);

	const position = isGlobalPages ? 2 : 1;
	const columns = arrayInsert(defaultColumns, position, extraColumns);
	return columns;
};

export { filterByStatus, getColumns, getCurrentFilter, getOptionFilters, getOptionValues, getSortedListStatus };
