import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
import { connect } from "react-redux";
import { useHistory, useLocation } from "react-router-dom";

import {
	EmptyState,
	ErrorToast,
	FilterTagsBar,
	FloatingNote,
	Loading,
	MainWrapper,
	Notification,
	SearchTagsBar,
	TableList,
	Toast,
} from "@ax/components";
import { appActions } from "@ax/containers/App";
import type { IError } from "@ax/containers/App/reducer";
import { integrationsActions } from "@ax/containers/Integrations";
import { navigationActions } from "@ax/containers/Navigation/Defaults";
import { pageEditorActions } from "@ax/containers/PageEditor";
import { INITIAL_TEMPLATE } from "@ax/containers/PageEditor/constants";
import {
	type ISetCurrentPageIDAction,
	type ISetCurrentPageNameAction,
	type ISetCurrentPageStatusAction,
	pageStatus,
} from "@ax/containers/PageEditor/interfaces";
import { dataPacksActions } from "@ax/containers/Settings";
import { sitesActions } from "@ax/containers/Sites";
import { structuredDataActions } from "@ax/containers/StructuredData";
import { getMaxColumns, updateColumns } from "@ax/helpers";
import { useBulkSelection, useCategoryColors, useModal, usePermission, useToast, useWindowSize } from "@ax/hooks";
import type {
	ICheck,
	IDataPack,
	IEmptyStateProps,
	IErrorItem,
	IExportDataParams,
	IGetSitePagesParams,
	IGetSitesParams,
	ILanguage,
	IPage,
	IPageLanguage,
	IQueryValue,
	IRootState,
	ISavePageParams,
	ISchemaField,
	ISite,
	ISiteRoles,
	IStructuredData,
	IStructuredDataContent,
	IUser,
} from "@ax/types";

import { config } from "components";

import StructuredDataItem from "./../StructuredData/StructuredDataList/StructuredDataItem";
import { DeleteModal } from "./atoms";
import BulkHeader from "./BulkHeader";
import ContentFilters from "./ContentFilters";
import { useFilterQuery, useSortedListStatus } from "./hooks";
import NewContentModal from "./NewContentModal";
import PageItem from "./PageItem";
import {
	filterByStatus,
	getColumns,
	getCurrentFilter,
	getOptionFilters,
	getOptionValues,
	getSortedListStatus,
} from "./utils";

import * as S from "./style";

const schemas = config.schemas.ui;

// TODO: Make this monster manageable
const Content = (props: IProps): JSX.Element => {
	const {
		currentSiteInfo,
		filter,
		template,
		currentSitePages,
		allSitePages,
		totalItems,
		lang,
		siteLanguages,
		errors,
		setCurrentPageID,
		setCurrentPageStatus,
		setCurrentPageName,
		addTemplate,
		getSitePages,
		getAllSitePages,
		updatePageStatus,
		deletePage,
		setLanguage,
		getStructuredDataContents,
		setHistoryPush,
		structuredData,
		currentStructuredData,
		currentDataContent,
		setSelectedStructuredData,
		resetForm,
		deleteBulk,
		getPage,
		duplicatePage,
		validatePage,
		activatedDataPacks,
		activatedTemplates,
		deleteDataContent,
		restoreDataContent,
		setFilter,
		setDataStatus,
		isLoading,
		resetPageEditor,
		removePageFromSite,
		importPageFromGlobal,
		restorePage,
		getDataPack,
		resetCurrentSiteErrorPages,
		currentSiteErrorPages,
		getSitesByLang,
		sitesByLang,
		user,
		skipReviewOnPublish,
		getIntegrations,
		setContentFilters,
		contentFilters,
		deleteAndRemoveFromSiteBulk,
		checkUserSession,
		getDefaults,
		getAvailableSiteDataPacks,
		error,
		currentSearch,
		updateCurrentSearch,
		exportDataContent,
	} = props;

	const itemsPerPage = 50;
	const firstPage = 1;

	const tableRef = useRef<HTMLDivElement>(null);
	const errorRef = useRef<HTMLDivElement>(null);
	const { isOpen: isNewOpen, toggleModal: toggleNewModal } = useModal();
	const { isOpen: isDeleteOpen, toggleModal: toggleDeleteModal } = useModal();
	const { sortedListStatus, setSortedListStatus } = useSortedListStatus();
	const {
		setFiltersSelection,
		resetFilterQuery,
		filterValues,
		query: currentFilterQuery,
	} = useFilterQuery(contentFilters);
	const { state: locationState } = useLocation<{ isFromEditor: boolean }>();
	const [notification, setNotification] = useState<{
		text: string;
		subErrors?: { id: number; error: string }[];
	} | null>(null);

	const currentFilter = getCurrentFilter(structuredData, filter);
	const checkFromPage = currentFilter ? currentFilter.fromPage : undefined;
	const baseFilters = ["unique-pages", "basic", "list", "static"];
	const isStructuredData = !baseFilters.includes(filter) && !checkFromPage;
	const isGlobalPages = !baseFilters.includes(filter) && checkFromPage;
	const isDataEditable = (!isStructuredData || currentStructuredData?.editable) ?? null;
	const isDataPrivate = currentStructuredData?.private || false;
	const isDataExportable = currentStructuredData?.exportable || false;
	const title = currentSiteInfo ? currentSiteInfo.name : `Site Content`;
	const isSiteLlmsHidden = currentSiteInfo.hidden;

	const pagesIds = currentSitePages?.map((page) => page.id);
	const dataIds = currentDataContent?.map((data) => data.id);
	const contentIds = isStructuredData ? dataIds : pagesIds;
	const currentSitePagesTemplatesIds = allSitePages?.map((page) => page.templateId);
	const currentSitesByLang = sitesByLang?.filter(
		(site: ISite) =>
			user?.isSuperAdmin ||
			user?.roles.find((siteRole: ISiteRoles) => siteRole.siteId === site.id || siteRole.siteId === "all"),
	);
	const categoryColumns: ISchemaField[] = currentStructuredData?.schema
		? currentStructuredData.schema.fields.filter((field: ISchemaField) => field.showList)
		: [];

	const [page, setPage] = useState(firstPage);
	const lastPage = Math.ceil(totalItems / itemsPerPage);
	const isLastItem = page === lastPage && currentSitePages.length === 1;

	const [isScrolling, setIsScrolling] = useState(false);
	const [deletedItem, setDeletedItem] = useState<number | number[] | null>(null);
	const [pagesToImport, setPagesToImport] = useState<number[]>([]);
	const [isEmpty, setIsEmpty] = useState(false);
	const [emptyStateProps, setEmptyStateProps] = useState<IEmptyStateProps>({});
	const [removedPage, setRemovedPage] = useState<number | number[] | null>(null);
	const [deleteAllVersions, setDeleteAllVersions] = useState(false);
	const [arePagesTranslated, setArePagesTranslated] = useState(false);
	const [templateInstanceError, setTemplateInstanceError] = useState({ error: false, templateName: "" });
	const [pagesSelected, setPagesSelected] = useState<any[]>([]);
	const [selectedOption, setSelectedOption] = useState<string | null>(null);
	const history = useHistory();

	const [windowWidth] = useWindowSize();
	const maxColumns = getMaxColumns(windowWidth, isStructuredData);

	const initialColumns = getColumns(categoryColumns, isStructuredData, isGlobalPages, maxColumns.value);
	const [columnsState, setColumnsState] = useState(initialColumns);

	const [isDeleting, setIsDeleting] = useState<boolean>(false);
	const [isBulkLoading, setIsBulkLoading] = useState<boolean>(false);

	const createPermission = isDataPrivate ? "content.createPrivateContentTypes" : "content.createPages";
	const exportPermission = isDataPrivate ? "content.exportPrivateContentTypes" : "content.exportContentTypes";
	const isAllowedToCreatePages = usePermission(createPermission);
	const isAllowedToExport = usePermission(exportPermission);

	const {
		resetBulkSelection,
		selectedItems,
		isSelected,
		areItemsSelected,
		checkState,
		addToBulkSelection,
		selectAllItems,
		setHoverCheck,
	} = useBulkSelection(contentIds);

	const { isVisible, toggleToast, setIsVisible } = useToast();
	const {
		isVisible: isVisibleRemovedToast,
		toggleToast: toggleRemovedToast,
		setIsVisible: setIsVisibleRemovedToast,
	} = useToast();
	const {
		isVisible: isVisibleDeletedToast,
		toggleToast: toggleDeletedToast,
		setIsVisible: setIsVisibleDeletedToast,
	} = useToast();

	const { categoryColors, addCategoryColors } = useCategoryColors();
	const {
		isVisible: isVisibleCopiedToast,
		toggleToast: toggleCopiedToast,
		setIsVisible: setIsVisibleCopiedToast,
	} = useToast();

	const getParams = useCallback(() => {
		const siteID = currentSiteInfo.id;
		const params = isStructuredData
			? {
					siteID,
					dataID: typeof filter === "object" ? filter.value : filter,
					page,
					itemsPerPage,
					pagination: true,
					deleted: false,
					include_draft: true,
					query: currentSearch,
					format: "list",
				}
			: {
					siteID,
					deleted: false,
					page,
					itemsPerPage,
					query: currentSearch,
					format: "list",
				};

		return params;
	}, [filter, currentSiteInfo, isStructuredData, page, currentSearch]);

	const getPages = async (params: IGetSitePagesParams, filterQuery?: string) => {
		const isStructuredDataPage = !baseFilters.includes(filter);
		const pageFilter = isStructuredDataPage ? filter : undefined;
		await getSitePages(params, pageFilter, filterQuery);
	};

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	const getSiteContent = useCallback(
		async (filterQuery?: string) => {
			const params = getParams();
			isStructuredData && params.siteID
				? await getStructuredDataContents({ ...params, filterQuery }, params.siteID)
				: getPages(params, filterQuery);
		},
		[getParams, getSitePages, getStructuredDataContents, currentSiteInfo, isStructuredData, lang],
	);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix
	useEffect(() => {
		currentSiteInfo && getSiteContent(currentFilterQuery);
		if (baseFilters.includes(filter)) {
			addTemplate(INITIAL_TEMPLATE);
		}
		if (tableRef.current) {
			tableRef.current.scrollTo(0, 0);
		}
	}, [page, filter, currentFilterQuery, currentSearch, lang]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useLayoutEffect(() => {
		setPage(firstPage);
		const initialColumns = getColumns(categoryColumns, isStructuredData, isGlobalPages, maxColumns.value);
		setColumnsState(initialColumns);
	}, [filter]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		const updatedColumns = updateColumns(columnsState, maxColumns.value);
		setColumnsState(updatedColumns);
	}, [windowWidth]);

	const params = { language: lang.id, recentSitesNumber: 7 };
	const fetchSitesByLang = async () => await getSitesByLang(params);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useLayoutEffect(() => {
		checkUserSession();
		const isFromEditor = locationState?.isFromEditor === true;
		const hasFilterSet = filter && filter !== "unique-pages";
		// Only reset filter if:
		// - Not a POP navigation (back button) - preserve filter when going back
		// - Not coming from editor - preserve filter when returning from editor
		// - If POP without filter set and not from editor, reset to default
		if (history.action !== "POP" && !isFromEditor) {
			setFilter("unique-pages");
		} else if (history.action === "POP" && !hasFilterSet && !isFromEditor) {
			// Only reset on POP if no filter was set and not coming from editor
			setFilter("unique-pages");
		}
		resetPageEditor();
		resetCurrentSiteErrorPages();
		fetchSitesByLang();
		getIntegrations(currentSiteInfo.id, {}, true);
		getDefaults();
		getAvailableSiteDataPacks(null, false);
		resetForm();
	}, []);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		if (!isLoading) {
			const isContentType = !baseFilters.includes(filter);
			const emptyState: IEmptyStateProps = {};
			const { liveStatus, translated, type } = filterValues;
			const isSearching =
				currentSearch.length > 0 ||
				(liveStatus.length && liveStatus[0].value !== "all") ||
				(translated.length && translated[0].value !== "all") ||
				(type.length && type[0].value !== "all");

			if (isSearching) {
				emptyState.icon = "search";
				emptyState.title = "Oh! No Results Found";
				emptyState.message = "We couldn’t find what you are looking for. Please, try another search.";
			} else {
				emptyState.message = isContentType
					? "You don’t have pages with this content type yet."
					: isAllowedToCreatePages
						? "To start using pages in your site, create as many pages as you need."
						: undefined;
				emptyState.button = isContentType
					? "View all content"
					: isAllowedToCreatePages
						? "Create the first page"
						: undefined;
				emptyState.action = isContentType ? () => setFilter("unique-pages") : toggleNewModal;
			}
			setIsEmpty(!content.length);
			setEmptyStateProps(emptyState);
		}
	}, [isLoading, currentSitePages]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		setContentFilters(filterValues);
	}, [filterValues]);

	useEffect(() => {
		const errorCode = error?.code ?? undefined;
		if (errorCode === 400 && errorRef.current) {
			errorRef.current.scrollIntoView({
				behavior: "smooth",
				block: "start",
			});
		}
	}, [error]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		const params = getParams();
		getAllSitePages(params);
	}, [lang]);

	const bulkFilter = (bulkSelection: number[]) => filterByStatus(bulkSelection, currentSitePages);

	const handleAddToBulk = (item: ICheck) => {
		const page = currentSitePages.find((page: IPage) => page.id === item.value);

		item.isChecked && !pagesSelected.includes(item)
			? setPagesSelected((pagesSelected) => [...pagesSelected, page])
			: setPagesSelected(pagesSelected.filter((page: IPage) => page.id !== item.value));

		addToBulkSelection(item, bulkFilter);
	};

	const handleSelectAll = () => {
		selectAllItems(bulkFilter);
		setPagesSelected(isStructuredData ? currentDataContent : currentSitePages);
	};

	const unselectAllItems = () => {
		resetBulkSelection();
		setPagesSelected([]);
	};

	const selectItems = () => (checkState.isAllSelected ? unselectAllItems() : handleSelectAll());

	const addNewData = () => {
		resetForm(true);
		const path = `/sites/data/${currentStructuredData?.id}/editor`;
		setHistoryPush(path, false);
	};

	const addNewPage = (template: string) => {
		const selectedTemplate = schemas?.templates[template];
		const { singleInstance, displayName } = selectedTemplate || {};
		const isAlreadyActive = currentSitePagesTemplatesIds.includes(template);

		if (singleInstance && isAlreadyActive) {
			setTemplateInstanceError({ error: true, templateName: displayName || "" });
			toggleNewModal();
		} else {
			setTemplateInstanceError({ error: false, templateName: "" });
			setCurrentPageID(null);
			setCurrentPageStatus("offline");
			setCurrentPageName("New Page");
			const path = "/sites/pages/editor/new";
			setHistoryPush(path, true);
		}
	};

	const createContent = (isStructuredData: boolean, value: string) => {
		if (isStructuredData) {
			setSelectedStructuredData(value, "site");
			addNewData();
		} else {
			addTemplate(value);
			addNewPage(value);
		}
	};

	const goToPage = (page: IPage) => () => {
		const pageID = page.haveDraftPage ? page.haveDraftPage : page.id;
		setCurrentPageID(pageID);
	};

	const handleBulkDelete = async (pageIds: number[]) => {
		const globalPageIds = pagesSelected
			.filter((page: IPage) => pageIds.includes(page.id) && page.origin === "GLOBAL")
			.map((page: IPage) => page.id);

		const filteredPageIds = pagesSelected
			.filter((page: IPage) => pageIds.includes(page.id) && page.origin !== "GLOBAL")
			.map((page: IPage) => page.id);

		const globalPageTranslatedIds = pagesSelected.flatMap((page: IPage) => {
			return page.origin === "GLOBAL"
				? page.pageLanguages.filter((trans) => pageIds.includes(trans.pageId)).map((trans) => trans.pageId)
				: [];
		});

		const filteredPageTranslatedIds = pagesSelected.flatMap((page: IPage) => {
			return page.origin !== "GLOBAL"
				? page.pageLanguages.filter((trans) => pageIds.includes(trans.pageId)).map((trans) => trans.pageId)
				: [];
		});

		const deleted = deleteAllVersions
			? await deleteAndRemoveFromSiteBulk(filteredPageTranslatedIds, globalPageTranslatedIds)
			: await deleteAndRemoveFromSiteBulk(filteredPageIds, globalPageIds);

		if (deleted) {
			setDeletedItem(pageIds);
			toggleDeletedToast();
		}
	};

	const bulkDelete = async () => {
		let allPageVersions: number[] = [];
		setIsBulkLoading(true); // se podría usar setIsDeleting pero por seguridad prefiero usar uno propio
		setIsDeleting(true);
		if (deleteAllVersions) {
			const selectedPages = currentSitePages.filter((page) => selectedItems.all.includes(page.id));
			const pageLanguages = selectedPages.map((element) => element.pageLanguages);
			pageLanguages.forEach((element) => {
				const ids = element.map((lang: IPageLanguage) => lang.pageId);
				allPageVersions = [...allPageVersions, ...ids];
			});
		}

		isStructuredData
			? await deleteDataContent(selectedItems.all).then((deleted: boolean) => {
					if (deleted) {
						deleteAllVersions ? setDeletedItem(allPageVersions) : setDeletedItem(selectedItems.all);
						toggleToast();
					}
				})
			: deleteAllVersions
				? await handleBulkDelete(allPageVersions)
				: await handleBulkDelete(selectedItems.all);
		toggleDeleteModal();
		const allPageItemsSelected = selectedItems.all.length >= currentSitePages.length;
		const previousPage = page - 1;
		page > 1 && (isLastItem || allPageItemsSelected) ? setPage(previousPage) : getSiteContent();
		unselectAllItems();
		setIsBulkLoading(false);
		setIsDeleting(false);
	};

	const handleToggleDeleteModal = () => {
		const selectedPages = currentSitePages.filter((page) => selectedItems.all.includes(page.id));
		const hasTranslations = selectedPages.some((page) => page.pageLanguages.length > 1);
		setArePagesTranslated(hasTranslations);
		toggleDeleteModal();
	};

	const bulkPublishAction = async (isPublish: boolean) => {
		setIsBulkLoading(true);
		const { notPublished, published, drafts } = selectedItems;

		if (drafts && drafts.length > 0) {
			const multiplePages = drafts.length > 1;
			const getPage = (id: number) => currentSitePages.find((page) => page.id === id);
			const getPageWarning = (pageId: number) =>
				`The '${getPage(pageId)?.title}' page has a draft version. To publish it, you must do it from the editor.`;
			const text = multiplePages
				? `There are ${drafts.length} pages that cannot be published.`
				: getPageWarning(drafts[0]);
			const subErrors = multiplePages && drafts.map((draft) => ({ id: draft, error: getPageWarning(draft) }));
			setNotification({ text, ...(subErrors && { subErrors }) });
		}

		const status = isPublish ? pageStatus.UPLOAD_PENDING : pageStatus.OFFLINE_PENDING;

		if (notPublished.length > 0) {
			isPublish
				? await updatePageStatus(notPublished, status, true)
				: await updatePageStatus(notPublished, pageStatus.OFFLINE, true);
		}

		if (published.length > 0 && !isPublish) {
			await updatePageStatus(published, status, true);
		}

		getSiteContent();
		unselectAllItems();
		setIsBulkLoading(false);
	};

	const bulkPublish = () => {
		if (isStructuredData) {
			setIsBulkLoading(true);
			setDataStatus(selectedItems.all, "undraft");
			unselectAllItems();
			setIsBulkLoading(false);
		} else {
			bulkPublishAction(true);
		}
	};

	const bulkUnpublish = () => {
		if (isStructuredData) {
			setIsBulkLoading(true);
			setDataStatus(selectedItems.all, "draft");
			unselectAllItems();
			setIsBulkLoading(false);
		} else {
			bulkPublishAction(false);
		}
	};

	const sortItems = (orderPointer: IQueryValue[], isAscending: boolean) => {
		setPage(firstPage);
		const sortedState = getSortedListStatus(orderPointer[0].value.toString(), isAscending);
		setSortedListStatus(sortedState);

		setFiltersSelection("order", orderPointer, isAscending);
	};

	const filterItems = (filterPointer: string, filtersSelected: IQueryValue[]) => {
		setPage(firstPage);
		setFiltersSelection(filterPointer, filtersSelected);
	};

	const exportContent =
		isDataExportable && isAllowedToExport
			? async (formats: (number | string)[]) => {
					if (currentStructuredData && formats.length) {
						const ids = selectedItems.all.length ? selectedItems.all : undefined;
						await exportDataContent(currentStructuredData?.id, { format: formats as string[], ids });
					}
				}
			: undefined;

	const Header = (
		<BulkHeader
			showBulk={areItemsSelected(contentIds)}
			bulkDelete={handleToggleDeleteModal}
			bulkPublish={bulkPublish}
			bulkUnpublish={bulkUnpublish}
			selectAllItems={handleSelectAll}
			totalItems={totalItems}
			selectItems={selectItems}
			checkState={checkState}
			isScrolling={isScrolling}
			isStructuredData={isStructuredData}
			sortItems={sortItems}
			sortedListStatus={sortedListStatus}
			filterItems={filterItems}
			isEditable={isDataEditable}
			isLoading={isBulkLoading}
			filterValues={filterValues}
			categoryColumns={categoryColumns}
			columns={columnsState}
			setColumns={setColumnsState}
			isGlobalPages={isGlobalPages}
			siteID={currentSiteInfo.id}
			maxColumns={maxColumns}
			exportAction={exportContent}
			setHoverCheck={setHoverCheck}
			selectedItems={selectedItems}
			checkFromPage={checkFromPage}
		/>
	);

	const goToData = (item: IStructuredDataContent) => {
		const isFromPage = !!item.relatedPage;
		let path: string;

		if (isFromPage) {
			setCurrentPageID(item.relatedPage?.pageId || null);
			path = "/sites/pages/editor";
		} else {
			setSelectedStructuredData(item.structuredData, "site");
			path = `/sites/data/${item.structuredData}/editor`;
		}

		setHistoryPush(path, isFromPage);
	};

	const mapStructuredData = () =>
		currentDataContent?.map((item) => {
			const handleClick = () => goToData(item);
			const isItemSelected = isSelected(item.id);
			return (
				<StructuredDataItem
					structuredData={item}
					key={item.id}
					handleClick={handleClick}
					languages={siteLanguages}
					lang={lang}
					isSelected={isItemSelected}
					onChange={addToBulkSelection}
					toggleToast={toggleToast}
					setDeletedItem={setDeletedItem}
					isEditable={isDataEditable}
					activatedDataPacks={activatedDataPacks}
					categoryColumns={categoryColumns}
					columns={columnsState}
					categoryColors={categoryColors}
					addCategoryColors={addCategoryColors}
					hoverCheck={checkState.hoverCheck}
				/>
			);
		});

	const mapPages = () =>
		currentSitePages?.map((pageItem) => {
			const isItemSelected = isSelected(pageItem.id);
			const selectedTemplate = schemas?.templates[pageItem.templateId];
			const { singleInstance } = selectedTemplate || {};
			const isAlreadyActive = currentSitePagesTemplatesIds.includes(template);
			const isDuplicable = !singleInstance || (singleInstance && !isAlreadyActive);

			const item = {
				isSelected: isItemSelected,
				page: pageItem,
				site: currentSiteInfo,
				lang,
				siteLanguages,
				isDuplicable,
			};

			const deleteCurrentPage = async () => {
				const { site } = item;
				const deletePageParams: ISavePageParams = {
					site,
					page: item.page,
				};
				const previousPage = page - 1 || 1;

				const deleted = await deletePage(deletePageParams);
				if (deleted) {
					setDeletedItem(item.page.id);
					toggleDeletedToast();
				}
				isLastItem && previousPage !== 1 ? setPage(previousPage) : getSiteContent();
			};

			const deleteCurrentPageBulk = async (ids: number[]) => {
				const previousPage = page - 1 || 1;

				const deleted = await deleteBulk(ids);
				if (deleted) {
					setDeletedItem(ids);
					toggleDeletedToast();
				}
				isLastItem && previousPage !== 1 ? setPage(previousPage) : getSiteContent();
			};

			const pageItemFunctions = {
				onClick: goToPage(pageItem),
				onCheck: handleAddToBulk,
				updatePageStatus,
				deletePage: deleteCurrentPage,
				getSiteContent,
				setHistoryPush,
				setCurrentPageID,
				duplicatePage,
				removePageFromSite,
				deleteBulk: deleteCurrentPageBulk,
				getDataPack: getDataPack,
				setTemplateInstanceError,
				toggleCopiedToast,
				validatePage,
				getPage,
			};

			return (
				<PageItem
					item={item}
					key={pageItem.id}
					functions={pageItemFunctions}
					sites={currentSitesByLang}
					activatedTemplates={activatedTemplates}
					toggleToast={toggleRemovedToast}
					setRemovedPage={setRemovedPage}
					categoryColumns={categoryColumns}
					columns={columnsState}
					categoryColors={categoryColors}
					addCategoryColors={addCategoryColors}
					dataPacks={activatedDataPacks}
					skipReview={skipReviewOnPublish}
					hoverCheck={checkState.hoverCheck}
				/>
			);
		});

	const undoAction = () => {
		if (deletedItem && isStructuredData) {
			restoreDataContent(deletedItem);
		}
		setIsVisible(false);
	};

	const toastProps = {
		action: () => undoAction(),
		setIsVisible,
		message: deletedItem ? `Data deleted` : "",
	};

	const undoRemoveAction = () => {
		if (removedPage) {
			importPageFromGlobal(removedPage);
		}
		setIsVisible(false);
	};

	const removedToastProps = {
		action: () => undoRemoveAction(),
		setIsVisible: setIsVisibleRemovedToast,
		message: removedPage ? `Page removed` : "",
	};

	const content = isStructuredData ? mapStructuredData() : mapPages();

	const options = {
		filters: getOptionFilters(structuredData, activatedDataPacks),
		values: getOptionValues(structuredData),
	};

	const pagination = {
		setPage,
		itemsPerPage,
		totalItems,
		currPage: page,
	};

	const onScroll = (e: any) => setIsScrolling(e.target.scrollTop > 0);

	const importPage = async () => {
		toggleNewModal();
		if (pagesToImport.length > 0) {
			await importPageFromGlobal(pagesToImport);
		}
	};

	const handleLanguage = (language: ILanguage) => {
		const { locale, id } = language;
		setLanguage({ locale, id });
		setPage(firstPage);
		resetBulkSelection();
	};

	const resetFilter = () => resetFilterQuery();


	const undoDeleteAction = async () => {
		if (deletedItem) {
			await restorePage(deletedItem);
			getSiteContent();
		}
		setIsVisible(false);
	};

	const deletedToastProps = {
		action: () => undoDeleteAction(),
		setIsVisible: setIsVisibleDeletedToast,
		message: "Page deleted.",
	};

	const copiedToastProps = {
		setIsVisible: setIsVisibleCopiedToast,
		message: "1 Page copied to another Site",
	};

	const addNewAction = baseFilters.includes(filter) || isGlobalPages ? toggleNewModal : addNewData;

	const handleSearch = (query: string) => {
		updateCurrentSearch(query);
		setPage(1);
	};

	const handleGoToSettings = () => {
		const path = `/sites/settings/globals`;
		setHistoryPush(path, false);
	};

	const rightButtonProps = isAllowedToCreatePages
		? {
				label: "New",
				action: addNewAction,
				disabled: !isDataEditable,
			}
		: undefined;

	const errorPagesText =
		currentSiteErrorPages.length > 1
			? "These pages contains some errors, so you can not publish them yet. Please, review the errors on the pages."
			: "This page contains some errors, so you can not publish it yet. Please, review the errors on the page.";

	const notEditableText =
		"Sorry, this content cannot be edited because it comes from an external source or belongs to a preconfigured system.";

	const isPrivateText = "This content is private and will not be available for display in any distributor.";

	const filterLabels = {
		liveStatus: "Live",
		translated: "Translated",
		categories: "Category",
	};

	return (
		<MainWrapper
			title={title}
			language={lang}
			languageAction={handleLanguage}
			availableLanguages={siteLanguages}
			rightButton={rightButtonProps}
			searchAction={handleSearch}
			errors={errors}
			searchValue={currentSearch}
			exportAction={exportContent}
			showTagHidden={isSiteLlmsHidden}
		>
			<S.ContentListWrapper>
				<ContentFilters
					current={filter}
					dynamicValues={structuredData}
					resetFilter={resetFilter}
					setFilter={filterItems}
					isAllowedToCreate={isAllowedToCreatePages}
					addNew={addNewAction}
					typeFilters={filterValues.type}
					setSelectedOption={setSelectedOption}
				/>
				<S.TableWrapper>
					<ErrorToast ref={errorRef} />
					{!isDataEditable && !baseFilters.includes(filter) && (
						<S.NotificationWrapper>
							<Notification type="info" text={notEditableText} closeButton={false} />
						</S.NotificationWrapper>
					)}
					{isDataPrivate && !baseFilters.includes(filter) && (
						<S.NotificationWrapper>
							<Notification type="private" text={isPrivateText} closeButton={false} />
						</S.NotificationWrapper>
					)}
					{templateInstanceError.error && (
						<Notification
							type="error"
							text={`There can be only one ${templateInstanceError.templateName} page and you already have it.`}
						/>
					)}
					{(!!currentSiteErrorPages.length || errors.length > 0) && <Notification type="error" text={errorPagesText} />}
					{notification && (
						<Notification
							type="warning"
							text={notification.text}
							subErrors={notification.subErrors}
							resetError={() => setNotification(null)}
						/>
					)}
					{isSiteLlmsHidden && (
						<S.NoteWrapper>
							<FloatingNote
								icon="working"
								message={
									<>
										Please note that this is site is <strong>hidden from search engines and AI models</strong>. To index
										it, go to <strong>General Settings</strong>.
									</>
								}
								btnText="Go to Settings"
								onClick={handleGoToSettings}
							/>
						</S.NoteWrapper>
					)}
					<TableList
						tableHeader={Header}
						pagination={pagination}
						onScroll={onScroll}
						hasFixedHeader={true}
						tableRef={tableRef}
					>
						<S.SearchTags>
							<SearchTagsBar query={currentSearch} setQuery={handleSearch} />
							<FilterTagsBar
								filters={filterValues}
								setFilters={setFiltersSelection}
								resetFilters={resetFilterQuery}
								labels={filterLabels}
							/>
						</S.SearchTags>
						{isLoading ? (
							<S.LoadingWrapper>
								<Loading />
							</S.LoadingWrapper>
						) : isEmpty ? (
							<S.EmptyWrapper>
								<EmptyState {...emptyStateProps} />
							</S.EmptyWrapper>
						) : (
							<>{content}</>
						)}
					</TableList>
				</S.TableWrapper>
			</S.ContentListWrapper>
			{isNewOpen && (
				<NewContentModal
					filters={options.filters}
					values={options.values}
					selectedValue={selectedOption}
					theme={currentSiteInfo.theme}
					isOpen={isNewOpen}
					toggleModal={toggleNewModal}
					createContent={createContent}
					setPagesToImport={setPagesToImport}
					importPage={importPage}
				/>
			)}
			<DeleteModal
				isOpen={isDeleteOpen}
				toggleModal={toggleDeleteModal}
				onDelete={bulkDelete}
				isDeleting={isDeleting}
				{...{ isTranslated: arePagesTranslated, deleteAllVersions, setDeleteAllVersions }}
			/>
			{isVisible && <Toast {...toastProps} />}
			{isVisibleRemovedToast && <Toast {...removedToastProps} />}
			{isVisibleDeletedToast && <Toast {...deletedToastProps} />}
			{isVisibleCopiedToast && <Toast {...copiedToastProps} />}
		</MainWrapper>
	);
};

const mapStateToProps = (state: IRootState) => ({
	currentSiteInfo: state.sites.currentSiteInfo!,
	currentSitePages: state.sites.currentSitePages,
	allSitePages: state.sites.allSitePages,
	filter: state.sites.currentFilter,
	template: state.pageEditor.template,
	totalItems: state.sites.totalItems,
	lang: state.app.lang,
	pageLanguages: state.pageEditor.currentPageLanguages,
	errors: state.pageEditor.errors,
	siteLanguages: state.sites.currentSiteLanguages,
	structuredData: state.structuredData.structuredData.site,
	currentDataContent: state.structuredData.currentDataContent,
	currentStructuredData: state.structuredData.currentStructuredData,
	activatedDataPacks: state.dataPacks.activated,
	activatedTemplates: state.dataPacks.templates,
	isLoading: state.app.isLoading,
	currentSiteErrorPages: state.sites.currentSiteErrorPages,
	sitesByLang: state.sites.sitesByLang,
	user: state.users.currentUser,
	skipReviewOnPublish: state.app.globalSettings.skipReviewOnPublish,
	contentFilters: state.sites.contentFilters,
	error: state.app.error,
	currentSearch: state.sites.currentSearch,
});

interface IDispatchProps {
	updateForm: (form: any) => void;
	setSelectedStructuredData: (id: string, scope: "global" | "site") => void;
	setCurrentPageID(currentPageID: number | null): ISetCurrentPageIDAction;
	setCurrentPageStatus(currentPageStatus: string | null): ISetCurrentPageStatusAction;
	setCurrentPageName(currentPageName: string): ISetCurrentPageNameAction;
	addTemplate(template: string): void;
	getSitePages(params: IGetSitePagesParams, structuredData?: string | undefined, filterQuery?: string): Promise<void>;
	getAllSitePages(params: IGetSitePagesParams): Promise<void>;
	updatePageStatus(ids: number[], status: string, updatePageStatus?: boolean): Promise<boolean>;
	deletePage(params?: ISavePageParams): Promise<boolean>;
	setHistoryPush(page: string, isEditor: boolean): Promise<void>;
	setLanguage(lang: { locale: string; id: number | null }): void;
	getFilteredContent(filter: string | null): void;
	getStructuredDataContents(params: any, siteID: number): Promise<void>;
	resetForm(setDefault?: boolean): void;
	deleteBulk(ids: any): Promise<boolean>;
	duplicatePage(pageID: number, data?: any, siteID?: number): Promise<boolean>;
	getPage(pageID?: number, global?: boolean): Promise<void>;
	validatePage(publish?: boolean, browserRef?: any, currentPage?: IPage): Promise<boolean>;
	deleteDataContent(dataID: number[]): Promise<boolean>;
	restoreDataContent(catID: number | number[]): void;
	setFilter(value: string): void;
	setDataStatus(dataID: number[], status: string): void;
	resetPageEditor(): Promise<void>;
	removePageFromSite(pageID: number | number[], refresh?: boolean): Promise<boolean>;
	importPageFromGlobal(pageID: number | number[]): Promise<boolean>;
	restorePage(id: number | number[]): Promise<boolean>;
	getDataPack: (id: string) => Promise<void>;
	resetCurrentSiteErrorPages: () => Promise<void>;
	getIntegrations(site: number, params?: any, skipLoading?: boolean): Promise<void>;
	getSitesByLang(params: IGetSitesParams): Promise<void>;
	setContentFilters(contentFilters: Record<string, IQueryValue[]> | null): void;
	deleteAndRemoveFromSiteBulk(pageIds: number[], globalPageIds: number[]): Promise<boolean>;
	checkUserSession(): Promise<void>;
	getDefaults(): Promise<void>;
	getAvailableSiteDataPacks(queryParams: string | null, loading?: boolean): Promise<void>;
	updateCurrentSearch(query: string): Promise<void>;
	exportDataContent(structuredDataID: string, data: IExportDataParams): Promise<void>;
}

const mapDispatchToProps = {
	setHistoryPush: appActions.setHistoryPush,
	setLanguage: appActions.setLanguage,
	getSitePages: sitesActions.getSitePages,
	getAllSitePages: sitesActions.getAllSitePages,
	setCurrentPageID: pageEditorActions.setCurrentPageID,
	setCurrentPageStatus: pageEditorActions.setCurrentPageStatus,
	setCurrentPageName: pageEditorActions.setCurrentPageName,
	addTemplate: pageEditorActions.addTemplate,
	updatePageStatus: pageEditorActions.updatePageStatus,
	deletePage: pageEditorActions.deletePage,
	deleteBulk: pageEditorActions.deleteBulk,
	duplicatePage: pageEditorActions.duplicatePage,
	getPage: pageEditorActions.getPage,
	validatePage: pageEditorActions.validatePage,
	getStructuredDataContents: structuredDataActions.getStructuredDataContents,
	setSelectedStructuredData: structuredDataActions.setSelectedStructuredData,
	updateForm: structuredDataActions.updateForm,
	resetForm: structuredDataActions.resetForm,
	deleteDataContent: structuredDataActions.deleteStructuredDataContent,
	restoreDataContent: structuredDataActions.restoreStructuredDataContent,
	setFilter: sitesActions.setFilter,
	setDataStatus: structuredDataActions.setStatusStructuredDataContent,
	resetPageEditor: pageEditorActions.resetPageEditor,
	removePageFromSite: sitesActions.removePageFromSite,
	importPageFromGlobal: sitesActions.importPageFromGlobal,
	restorePage: pageEditorActions.restorePage,
	getDataPack: dataPacksActions.getSiteDataPack,
	resetCurrentSiteErrorPages: sitesActions.resetCurrentSiteErrorPages,
	getSitesByLang: sitesActions.getSitesByLang,
	getIntegrations: integrationsActions.getIntegrations,
	setContentFilters: sitesActions.setContentFilters,
	deleteAndRemoveFromSiteBulk: sitesActions.deleteAndRemoveFromSiteBulk,
	checkUserSession: appActions.checkUserSession,
	getDefaults: navigationActions.getDefaults,
	getAvailableSiteDataPacks: dataPacksActions.getAvailableSiteDataPacks,
	updateCurrentSearch: sitesActions.updateCurrentSearch,
	exportDataContent: structuredDataActions.exportDataContent,
};

interface IPagesProps {
	currentSiteInfo: ISite;
	currentSitePages: IPage[];
	allSitePages: IPage[];
	filter: any;
	template: string;
	totalItems: number;
	lang: { locale: string; id: number };
	langID?: number;
	pageLanguages: IPageLanguage[];
	errors: IErrorItem[];
	siteLanguages: ILanguage[];
	structuredData: IStructuredData[];
	currentStructuredData: IStructuredData | null;
	currentDataContent: IStructuredDataContent[];
	isFromEditor: boolean;
	activatedDataPacks: IDataPack[];
	activatedTemplates: any[];
	isLoading: boolean;
	currentSiteErrorPages: number[];
	sites: ISite[];
	sitesByLang: ISite[];
	user: IUser | null;
	skipReviewOnPublish?: boolean;
	contentFilters: Record<string, IQueryValue[]> | null;
	error: IError;
	currentSearch: string;
}

type IProps = IPagesProps & IDispatchProps;

export default connect(mapStateToProps, mapDispatchToProps)(Content);
