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

import {
	EmptyState,
	ErrorToast,
	FilterTagsBar,
	MainWrapper,
	Notification,
	SearchTagsBar,
	TableList,
	Toast,
} from "@ax/components";
import { analyticsActions } from "@ax/containers/Analytics";
import { appActions } from "@ax/containers/App";
import { pageEditorActions } from "@ax/containers/PageEditor";
import {
	type ISetCurrentPageIDAction,
	type ISetCurrentPageNameAction,
	type ISetCurrentPageStatusAction,
	pageStatus,
} from "@ax/containers/PageEditor/interfaces";
import { sitesActions } from "@ax/containers/Sites";
import { structuredDataActions } from "@ax/containers/StructuredData";
import { getMaxColumns, updateColumns } from "@ax/helpers";
import { useBulkSelection, useCategoryColors, useModals, usePermissions, useToast, useWindowSize } from "@ax/hooks";
import type {
	ICheck,
	IColumn,
	IDataPack,
	IEmptyStateProps,
	IExportDataParams,
	IGetGlobalPagesParams,
	IGetStructuredDataParams,
	ILanguage,
	IPage,
	IQueryValue,
	IRootState,
	ISchemaField,
	IStructuredData,
	IStructuredDataContent,
	IStructuredDataFilter,
	IStructuredDataValue,
} from "@ax/types";

import { DeleteModal } from "./atoms";
import BulkHeader from "./BulkHeader";
import ContentFilters from "./ContentFilters";
import GlobalPageItem from "./GlobalPageItem";
import { useFilterQuery, useSortedListStatus } from "./hooks";
import NewContentModal from "./NewContentModal";
import StructuredDataItem from "./StructuredDataItem";
import {
	filterByStatus,
	getAllLangPagesIds,
	getColumns,
	getOptionFilters,
	getOptionValues,
	getSelectedValue,
	getSortedListStatus,
} from "./utils";

import * as S from "./style";

const StructuredDataList = (props: IProps): JSX.Element => {
	const {
		setHistoryPush,
		resetForm,
		currentStructuredData,
		currentDataContent,
		getStructuredDataContents,
		lang,
		globalLangs,
		setLanguage,
		totalItems,
		structuredData,
		currentSiteID,
		setSelectedStructuredData,
		deleteDataContent,
		restoreDataContent,
		activatedDataPacks,
		setDataStatus,
		filter,
		setFilter,
		isLoading,
		setCurrentPageID,
		addTemplate,
		template,
		setCurrentPageStatus,
		setCurrentPageName,
		getGlobalPages,
		currentSitePages,
		updatePageStatus,
		deleteBulk,
		restorePage,
		resetPageEditor,
		getAnalytics,
		setCurrentDataID,
		resetCurrentSiteErrorPages,
		currentSiteErrorPages,
		skipReviewOnPublish,
		setContentFilters,
		contentFilters,
		checkUserSession,
		currentSearch,
		updateCurrentSearch,
		resetCurrentData,
		exportDataContent,
	} = props;

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

	const [isScrolling, setIsScrolling] = useState(false);
	const [isBulkLoading, setIsBulkLoading] = useState(false);
	const [deletedItem, setDeletedItem] = useState<number | number[] | null>(null);
	const { isVisible: isDataToast, toggleToast: toggleDataToast, setIsVisible: setIsDataToast } = useToast();
	const { isVisible: isPageToast, toggleToast: togglePageToast, setIsVisible: setIsPageToast } = useToast();
	const tableRef = useRef<HTMLDivElement>(null);
	const wrapperRef = useRef<HTMLDivElement>(null);
	const [isEmpty, setIsEmpty] = useState(false);
	const [emptyStateProps, setEmptyStateProps] = useState<IEmptyStateProps>({});
	const { isOpen, toggleModal } = useModals(["new", "delete"]);
	const { sortedListStatus, setSortedListStatus } = useSortedListStatus();
	const {
		setFiltersSelection,
		filterValues,
		resetFilterQuery,
		query: currentFilterQuery,
	} = useFilterQuery(currentStructuredData, contentFilters);
	const history = useHistory();
	const { state: locationState } = useLocation<{ isFromEditor: boolean }>();
	const [isFirstRender, setIsFirstRender] = useState(true);
	const [deleteAllVersions, setDeleteAllVersions] = useState(false);
	const [arePagesTranslated, setArePagesTranslated] = useState(false);
	const { categoryColors, addCategoryColors } = useCategoryColors();
	const [notification, setNotification] = useState<{
		text: string;
		subErrors?: { id: number; error: string }[];
	} | null>(null);

	const isPrivateData = currentStructuredData?.private || false;

	const isAllowedTo = usePermissions({
		createPages: isPrivateData ? "global.content.createPrivateContentTypes" : "global.globalData.createAllGlobalData",
		export: isPrivateData ? "global.content.exportPrivateContentTypes" : "global.content.exportContentTypes",
	});

	const scope = currentSiteID ? "site" : "global";

	const isDataEditable = filter === "all-pages" || !currentStructuredData || currentStructuredData.editable;
	const isDataTranslatable = currentStructuredData?.translate;
	const isAllPages = filter === "all-pages";
	const isStructuredDataFromPage = !!currentStructuredData?.fromPage || isAllPages;
	const isDataExportable = currentStructuredData?.exportable || false;
	const dataIds = isStructuredDataFromPage
		? currentSitePages.map((page: IPage) => page.id)
		: currentDataContent.map((data: IStructuredDataContent) => data.id);

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

	const categoryColumns: ISchemaField[] = currentStructuredData?.schema
		? currentStructuredData.schema.fields.filter((field: ISchemaField) => field.showList)
		: [];

	const type = currentStructuredData ? currentStructuredData.id : "all";
	const [columnsState, setColumnsState] = useState<Record<string, IColumn[]>>({});

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

	const getParams = useCallback(() => {
		const params = {
			page,
			itemsPerPage,
			pagination: true,
			deleted: false,
			include_draft: true,
			query: currentSearch,
			format: "list",
			relatedFields: true,
		};

		return params;
	}, [page, currentSearch]);

	const getStructuredData = useCallback(
		async (id: string, filterQuery?: string) => {
			const params: IGetStructuredDataParams = { ...getParams(), dataID: null };
			params.dataID = id;
			params.filterQuery = filterQuery;
			await getStructuredDataContents(params);
		},
		[getParams, getStructuredDataContents],
	);

	const handleGetGlobalPages = async () => {
		const params: IGetGlobalPagesParams = getParams();
		params.filterStructuredData = isStructuredDataFromPage && !isAllPages && filter;
		await getGlobalPages(params, currentFilterQuery);
	};

	const handleGetStructuredData = () => getStructuredData(filter, currentFilterQuery);

	const handleGetData = () => {
		isStructuredDataFromPage ? handleGetGlobalPages() : handleGetStructuredData();
	};

	const resetFilter = () => {
		const isFromEditor = locationState?.isFromEditor === true;
		// Resetea si:
		// (1) Navegación hacia adelante (PUSH) sin venir del editor
		// (2) Back button (POP) y NO vienes del editor (para sincronizar Redux con URL)
		const shouldReset = (history.action === "PUSH" && !isFromEditor) || (history.action === "POP" && !isFromEditor);

		if (shouldReset) {
			setFilter("all-pages");
			resetCurrentData();
		}
	};

	const changeColumnsState = (updatedColumns: any) => {
		setColumnsState((state) => ({ ...state, [type]: updatedColumns }));
	};

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useLayoutEffect(() => {
		resetFilter();
		setIsFirstRender(false);
		resetPageEditor();
		resetCurrentSiteErrorPages();
		resetForm();
	}, []);

	// Guardar columnas calculadas en estado cuando cambia el tipo
	useEffect(() => {
		const cols = getColumns(categoryColumns, isStructuredDataFromPage, isAllPages, maxColumns.value);
		if (cols.length > 0) {
			setColumnsState((state) => {
				if (state[type]?.length > 0) return state; // Mantener si ya existen
				return { ...state, [type]: cols };
			});
		}
	}, [type, categoryColumns, isStructuredDataFromPage, isAllPages, maxColumns]);

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

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		handleGetData();
		if (tableRef.current) {
			tableRef.current.scrollTo(0, 0);
		}
	}, [lang.locale, page, currentSearch, filterValues, currentStructuredData]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		if (wrapperRef.current) {
			wrapperRef.current.scrollIntoView({ block: "start", behavior: "smooth" });
		}
	}, [currentDataContent]);

	const resetFilterValues = () => resetFilterQuery();

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		if (!isFirstRender && !isLoading) {
			const emptyState: IEmptyStateProps = {};
			const isSearching = currentSearch.length > 0;
			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 = isAllPages
					? "You don’t have pages with this content type yet."
					: isAllowedTo.createPages && isDataEditable
						? "To start using pages in your site, create as many pages as you need."
						: undefined;
				emptyState.button = isAllPages
					? "View all content"
					: isAllowedTo.createPages && isDataEditable
						? "Create the first page"
						: undefined;
				emptyState.action = isAllPages ? resetFilterValues : isDataEditable ? addNewAction : undefined;
			}
			const isEmpty = isStructuredDataFromPage ? !currentSitePages.length : !currentDataContent.length;
			setIsEmpty(isEmpty);
			setEmptyStateProps(emptyState);
		}
	}, [isLoading, currentSitePages, currentDataContent]);

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

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

	const handleClick = (isFromPage?: boolean, globalPage?: IPage, forceLive?: boolean) => {
		if (isFromPage && globalPage) {
			const pageID = globalPage.haveDraftPage && !forceLive ? globalPage.haveDraftPage : globalPage.id;
			setCurrentPageID(pageID);
		}
		const path = isFromPage ? "data/pages/editor" : `data/${currentStructuredData?.id}/editor`;
		setHistoryPush(path, isFromPage);
	};

	const handleMenuClick = async (dataID: string) => {
		if (dataID === "all-pages" || !isStructuredDataFromPage) {
			filterItems("filterSites", [{ value: "all", label: "All" }]);
		}
		setFilter(dataID);
		setSelectedStructuredData(dataID, scope);
		unselectAllItems();
		setPage(firstPage);
	};

	const createNewData = () => {
		setCurrentDataID(null);
		resetForm(true);
		handleClick();
	};

	const bulkDelete = async () => {
		setIsBulkLoading(true);
		const idsToBeDeleted = getAllLangPagesIds(currentSitePages, selectedItems, deleteAllVersions);
		const deleted = isStructuredDataFromPage
			? await deleteBulk(idsToBeDeleted)
			: await deleteDataContent(idsToBeDeleted);

		if (deleted) {
			setDeletedItem(idsToBeDeleted);
			isStructuredDataFromPage ? togglePageToast() : toggleDataToast();
		}

		const allPageItemsSelected = selectedItems.all.length >= currentSitePages.length;
		const previousPage = page - 1;
		page > 1 && (isLastItem || allPageItemsSelected)
			? setPage(previousPage)
			: isStructuredDataFromPage && handleGetGlobalPages();
		unselectAllItems();
		toggleModal("delete");
		setIsBulkLoading(false);
	};

	const handleBulkDelete = () => {
		const selectedPages = currentSitePages.filter((page) => selectedItems.all.includes(page.id));
		const hasTranslations = selectedPages.some((page) => page.pageLanguages.length > 1);
		setArePagesTranslated(hasTranslations);
		toggleModal("delete");
	};

	const bulkPublishPage = 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);
		}

		handleGetGlobalPages();
		unselectAllItems();
		setIsBulkLoading(false);
	};

	const bulkPublishData = (status: string) => {
		setIsBulkLoading(true);
		setDataStatus(selectedItems.all, status);
		unselectAllItems();
		setIsBulkLoading(false);
	};

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

	const handleAddToBulk = (item: ICheck) => addToBulkSelection(item, bulkFilter);

	const bulkPublish = async () => {
		isStructuredDataFromPage ? await bulkPublishPage(true) : await bulkPublishData("undraft");
	};

	const bulkUnpublish = async () =>
		isStructuredDataFromPage ? await bulkPublishPage(false) : await bulkPublishData("draft");

	const unselectAllItems = () => resetBulkSelection();

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

	const handleSelectAll = () => selectAllItems(bulkFilter);

	const onScroll = (e: React.UIEvent<HTMLElement>) => setIsScrolling(e.currentTarget.scrollTop > 0);

	const undoDeleteData = () => {
		if (deletedItem) {
			restoreDataContent(deletedItem);
		}
		setIsDataToast(false);
	};

	const undoDeletePage = async () => {
		setIsPageToast(false);
		if (deletedItem) {
			await restorePage(deletedItem);
			handleGetGlobalPages();
		}
	};

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

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

	const filterItems = async (filterPointer: string, filtersSelected: IQueryValue[]) => {
		setPage(firstPage);
		if (!isStructuredDataFromPage && filterPointer === "categories") filterPointer = "related";
		setFiltersSelection(filterPointer, filtersSelected);
	};

	const exportContent =
		isDataExportable && isAllowedTo.export
			? 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 currentDataColumnsState = useMemo(() => {
		const cols =
			columnsState[type] ?? getColumns(categoryColumns, isStructuredDataFromPage, isAllPages, maxColumns.value);
		return cols;
	}, [type, columnsState, categoryColumns, isStructuredDataFromPage, isAllPages, maxColumns]);

	const TableHeader = (
		<BulkHeader
			showBulk={areItemsSelected(dataIds)}
			bulkDelete={handleBulkDelete}
			bulkPublish={bulkPublish}
			bulkUnpublish={bulkUnpublish}
			selectAllItems={handleSelectAll}
			totalItems={totalItems}
			selectItems={selectItems}
			checkState={checkState}
			isScrolling={isScrolling}
			isEditable={isDataEditable}
			isLoading={isBulkLoading}
			isFromPage={isStructuredDataFromPage}
			sortItems={sortItems}
			sortedListStatus={sortedListStatus}
			filterItems={filterItems}
			filterValues={filterValues[type] ?? { categories: [], related: [], liveStatus: [], translated: [] }}
			isAllPages={isAllPages}
			categoryColumns={categoryColumns}
			columns={currentDataColumnsState}
			setColumns={changeColumnsState}
			maxColumns={maxColumns}
			exportAction={exportContent}
			setHoverCheck={setHoverCheck}
			selectedItems={selectedItems}
		/>
	);

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

	const addNewPage = (dataID?: string) => {
		if (dataID) {
			setSelectedStructuredData(dataID, scope);
			setCurrentDataID(null);
			resetForm(true);
			const path = `data/${dataID}/editor`;
			setHistoryPush(path, false);
		} else {
			addTemplate(template);
			setCurrentPageID(null);
			setCurrentPageStatus("offline");
			setCurrentPageName("New Global Page");
			const path = "/data/pages/editor/new";
			setHistoryPush(path, true);
		}
	};

	const addNewAction = isAllPages || isStructuredDataFromPage ? () => toggleModal("new") : createNewData;

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

	const options: { filters: IStructuredDataFilter[]; values: IStructuredDataValue[] } = {
		filters: getOptionFilters(structuredData.global, activatedDataPacks),
		values: getOptionValues(structuredData.global),
	};

	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 handleLanguage = (language: ILanguage) => {
		const { locale, id } = language;
		setLanguage({ locale, id });
	};

	const languageProps = {
		globalLangs: isAllPages || isDataTranslatable ? globalLangs : [],
		lang: isAllPages || isDataTranslatable ? lang : null,
		languageAction: isAllPages || isDataTranslatable ? handleLanguage : undefined,
	};

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

	const selectedValue = getSelectedValue(options, filter);

	const mapCurrentDataContent = () =>
		currentDataContent?.map((sData: IStructuredDataContent) => {
			const isItemSelected = isSelected(sData.id);
			return (
				<StructuredDataItem
					structuredData={sData}
					key={sData.id}
					handleClick={handleClick}
					languages={globalLangs}
					lang={lang}
					isSelected={isItemSelected}
					onChange={addToBulkSelection}
					toggleToast={toggleDataToast}
					setDeletedItem={setDeletedItem}
					isEditable={isDataEditable}
					activatedDataPacks={activatedDataPacks}
					categoryColumns={categoryColumns}
					columns={currentDataColumnsState}
					categoryColors={categoryColors}
					addCategoryColors={addCategoryColors}
					hoverCheck={checkState.hoverCheck}
				/>
			);
		});

	const mapGlobalPages = () =>
		currentSitePages?.map((globalPage: IPage) => {
			const isItemSelected = isSelected(globalPage.id);
			const relatedStructuredData = structuredData.global.find(
				(data: IStructuredData) => data.id === globalPage.structuredData,
			);
			const isTranslatable = relatedStructuredData?.translate;
			return (
				<GlobalPageItem
					key={globalPage.id}
					handleClick={handleClick}
					languages={globalLangs}
					lang={lang}
					isSelected={isItemSelected}
					onChange={handleAddToBulk}
					isEditable={isDataEditable}
					isTranslatable={isTranslatable}
					isAllPages={isAllPages}
					globalPage={globalPage}
					getGlobalPages={handleGetGlobalPages}
					toggleToast={togglePageToast}
					setDeletedItem={setDeletedItem}
					categoryColumns={categoryColumns}
					columns={currentDataColumnsState}
					categoryColors={categoryColors}
					addCategoryColors={addCategoryColors}
					skipReview={skipReviewOnPublish}
					hoverCheck={checkState.hoverCheck}
				/>
			);
		});

	const deletedCount = !deletedItem ? 0 : Array.isArray(deletedItem) ? deletedItem.length : 1;

	const content = isStructuredDataFromPage ? mapGlobalPages() : mapCurrentDataContent();

	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 labelCategory = isStructuredDataFromPage ? { categories: "Category" } : { related: "Category " };

	const filterLabels = {
		liveStatus: "Live",
		translated: "Translated",
		filterSites: "Site",
		...labelCategory,
	};

	return (
		<MainWrapper
			title="Global Content"
			rightButton={rightButtonProps}
			availableLanguages={languageProps.globalLangs}
			language={languageProps.lang}
			languageAction={languageProps.languageAction}
			searchAction={handleSearch}
			searchValue={currentSearch}
			exportAction={exportContent}
		>
			<S.StructuredDataWrapper ref={wrapperRef}>
				<ContentFilters
					current={filter}
					dynamicValues={structuredData.global}
					onClick={handleMenuClick}
					addNew={addNewAction}
					isAllowedToCreate={isAllowedTo.createPages}
				/>
				<S.TableListWrapper>
					{!isDataEditable && (
						<S.NotificationWrapper>
							<Notification type="info" text={notEditableText} closeButton={false} />
						</S.NotificationWrapper>
					)}
					{isPrivateData && (
						<S.NotificationWrapper>
							<Notification type="private" text={isPrivateText} closeButton={false} />
						</S.NotificationWrapper>
					)}
					<ErrorToast />
					{!!currentSiteErrorPages.length && <Notification type="error" text={errorPagesText} />}
					{notification && (
						<Notification
							type="warning"
							text={notification.text}
							subErrors={notification.subErrors}
							resetError={() => setNotification(null)}
						/>
					)}
					<TableList
						tableHeader={TableHeader}
						pagination={pagination}
						onScroll={onScroll}
						hasFixedHeader={true}
						tableRef={tableRef}
					>
						<>
							<S.SearchTags>
								<SearchTagsBar query={currentSearch} setQuery={handleSearch} />
								<FilterTagsBar
									filters={filterValues[currentStructuredData?.id || "all"]}
									setFilters={setFiltersSelection}
									labels={filterLabels}
									resetFilters={resetFilterQuery}
								/>
							</S.SearchTags>
							{!isEmpty ? (
								content
							) : (
								<S.EmptyWrapper>
									<EmptyState {...emptyStateProps} />
								</S.EmptyWrapper>
							)}
						</>
					</TableList>
				</S.TableListWrapper>
			</S.StructuredDataWrapper>
			{isOpen("new") && (
				<NewContentModal
					selectPage={addTemplate}
					filters={options.filters}
					values={options.values}
					selectedValue={selectedValue}
					isOpen={isOpen("new")}
					toggleModal={() => toggleModal("new")}
					addNewPage={addNewPage}
					structuredData={structuredData.global}
				/>
			)}
			<DeleteModal
				isOpen={isOpen("delete")}
				toggleModal={() => toggleModal("delete")}
				mainModalAction={{
					title: isBulkLoading ? "Deleting" : "Delete",
					onClick: bulkDelete,
					disabled: isBulkLoading,
				}}
				secondaryModalAction={{ title: "Cancel", onClick: () => toggleModal("delete") }}
				{...{ arePagesTranslated, deleteAllVersions, setDeleteAllVersions }}
			/>
			{isDataToast && <Toast action={undoDeleteData} setIsVisible={setIsDataToast} message={"Data deleted"} />}
			{isPageToast && (
				<Toast
					action={undoDeletePage}
					setIsVisible={setIsPageToast}
					message={`${deletedCount} Page${deletedCount > 1 ? "s" : ""} deleted`}
				/>
			)}
		</MainWrapper>
	);
};

const mapStateToProps = (state: IRootState) => ({
	structuredData: state.structuredData.structuredData,
	currentDataContent: state.structuredData.currentDataContent,
	currentStructuredData: state.structuredData.currentStructuredData,
	filter: state.structuredData.currentFilter,
	totalItems: state.sites.totalItems,
	lang: state.app.lang,
	globalLangs: state.app.globalLangs,
	currentSiteID: state.sites.currentSiteInfo?.id || null,
	activatedDataPacks: state.dataPacks.activated,
	isLoading: state.app.isLoading,
	template: state.pageEditor.template,
	currentSitePages: state.sites.currentSitePages,
	currentSiteErrorPages: state.sites.currentSiteErrorPages,
	skipReviewOnPublish: state.app.globalSettings.skipReviewOnPublish,
	contentFilters: state.structuredData.contentFilters,
	currentSearch: state.structuredData.currentSearch,
});

const mapDispatchToProps = {
	setLanguage: appActions.setLanguage,
	setHistoryPush: appActions.setHistoryPush,
	getStructuredDataContents: structuredDataActions.getStructuredDataContents,
	resetForm: structuredDataActions.resetForm,
	setSelectedStructuredData: structuredDataActions.setSelectedStructuredData,
	deleteDataContent: structuredDataActions.deleteStructuredDataContent,
	restoreDataContent: structuredDataActions.restoreStructuredDataContent,
	setDataStatus: structuredDataActions.setStatusStructuredDataContent,
	setFilter: structuredDataActions.setFilter,
	setCurrentPageID: pageEditorActions.setCurrentPageID,
	addTemplate: pageEditorActions.addTemplate,
	setCurrentPageStatus: pageEditorActions.setCurrentPageStatus,
	setCurrentPageName: pageEditorActions.setCurrentPageName,
	getGlobalPages: sitesActions.getGlobalPages,
	updatePageStatus: pageEditorActions.updatePageStatus,
	deleteBulk: pageEditorActions.deleteBulk,
	restorePage: pageEditorActions.restorePage,
	resetPageEditor: pageEditorActions.resetPageEditor,
	getAnalytics: analyticsActions.getAnalytics,
	setCurrentDataID: structuredDataActions.setCurrentDataID,
	resetCurrentSiteErrorPages: sitesActions.resetCurrentSiteErrorPages,
	setContentFilters: structuredDataActions.setContentFilters,
	checkUserSession: appActions.checkUserSession,
	updateCurrentSearch: structuredDataActions.updateCurrentSearch,
	resetCurrentData: structuredDataActions.resetCurrentData,
	exportDataContent: structuredDataActions.exportDataContent,
};

interface IDispatchProps {
	setHistoryPush(route: string, isEditor?: boolean): void;
	resetForm(setDefault?: boolean): void;
	setLanguage(lang: { locale: string; id: number }): void;
	getStructuredDataContents(params: IGetStructuredDataParams): Promise<void>;
	setSelectedStructuredData(id: string, scope: string): void;
	deleteDataContent(dataID: number[]): Promise<boolean>;
	restoreDataContent(dataID: number | number[]): Promise<boolean>;
	setDataStatus(dataID: number[], status: string): void;
	setFilter(filter: string | null): void;
	setCurrentPageID(currentPageID: number | null): ISetCurrentPageIDAction;
	addTemplate(template: string): void;
	setCurrentPageStatus(currentPageStatus: string | null): ISetCurrentPageStatusAction;
	setCurrentPageName(currentPageName: string): ISetCurrentPageNameAction;
	getGlobalPages(params: IGetGlobalPagesParams, currentFilterQuery: string): Promise<void>;
	updatePageStatus(ids: number[], status: string, updatePageStatus?: boolean): Promise<boolean>;
	deleteBulk(ids: number[]): Promise<boolean>;
	restorePage(id: number | number[]): Promise<boolean>;
	resetPageEditor(): Promise<void>;
	getAnalytics(siteId?: number | null): Promise<void>;
	setCurrentDataID(id: number | null): void;
	resetCurrentSiteErrorPages: () => Promise<void>;
	setContentFilters(contentFilters: Record<string, Record<string, IQueryValue[]>> | null): void;
	checkUserSession(): Promise<void>;
	updateCurrentSearch(query: string): Promise<void>;
	resetCurrentData(): void;
	exportDataContent(structuredDataID: string, data: IExportDataParams): Promise<void>;
}

interface ICategoriesProps {
	structuredData: { global: IStructuredData[]; site: IStructuredData[] };
	currentDataContent: IStructuredDataContent[];
	currentStructuredData: IStructuredData | null;
	filter: string;
	totalItems: number;
	lang: { locale: string; id: number | null };
	globalLangs: ILanguage[];
	currentSiteID: number | null;
	activatedDataPacks: IDataPack[];
	isLoading: boolean;
	template: string;
	currentSitePages: IPage[];
	currentSiteErrorPages: number[];
	skipReviewOnPublish?: boolean;
	contentFilters: Record<string, Record<string, IQueryValue[]>> | null;
	currentSearch: string;
}

type IProps = ICategoriesProps & IDispatchProps;

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