import { memo, useEffect } from "react";
import { connect } from "react-redux";

import { pageEditorActions } from "@ax/containers/PageEditor";
import {
	areEqual,
	filterThemeModules,
	getFormTemplate,
	getTemplate,
	isModuleDisabled,
	isTemplateExcludedFromTheme,
	slugify,
} from "@ax/helpers";
import type { IRootState } from "@ax/types";

import Field from "./Field";
import TemplateManager from "./TemplateManager";

const PageConnectedField = (props: any): JSX.Element => {
	const {
		whiteList,
		objKey,
		selectedTab,
		field,
		selectedContent,
		goTo,
		updateEditorContent,
		overwriteHeaderConfig,
		selectedEditorID,
		pages,
		actions,
		setCurrentPageName,
		site,
		lang,
		getPageBreadcrumb,
		activatedTemplates,
		templateConfig,
		activatedModules,
		componentType,
		errors,
		deleteError,
		isGlobal,
		theme,
		moduleCopy,
		availableDataPacks,
		template,
		setHistoryPush,
		siteLanguages,
		globalLanguages,
		isReadOnly,
		themeElements,
		scrollEditorID,
		oldConfig,
		setOldConfig,
	} = props;

	const isTemplate = field.type === "template";
	const isFormTemplate = field.type === "formTemplate";

	const overrideableFields = ["header", "footer"];
	const isOverride = selectedContent.type && overrideableFields.includes(selectedContent.type);
	const isPageHome = componentType === "page" && selectedContent.isHome;
	const isNewPage = componentType === "page" && !selectedContent.id;
	const error = errors.find((err: any) => err.editorID === selectedEditorID && err.key === objKey);
	const isFormPage = selectedContent.component === "FormPage";
	const languages = site ? siteLanguages : globalLanguages;

	let isTemplateActivated = true;
	if (selectedContent.template && !isGlobal && !isFormTemplate) {
		isTemplateActivated = !!(
			activatedTemplates.find((temp: any) => temp.id === selectedContent.template.templateType) &&
			!isTemplateExcludedFromTheme(themeElements, selectedContent.template.templateType)
		);
	}

	const parentIsReadOnly =
		(componentType === "page" &&
			objKey === "parent" &&
			isTemplateActivated &&
			templateConfig &&
			templateConfig.modifiableOnPage === false &&
			templateConfig.defaultParent) ||
		isReadOnly;

	const defaultParent =
		isTemplateActivated && templateConfig && templateConfig.defaultParent ? templateConfig.defaultParent : null;

	const hasDefaultIndex = isTemplateActivated && templateConfig && templateConfig.indexDefault !== undefined;

	const isFieldReadOnly = (["parent", "slug"].includes(objKey) && isPageHome) || parentIsReadOnly || field.readonly;

	const filteredActivatedModules = filterThemeModules(themeElements, activatedModules);
	const filteredWhiteList = whiteList ? filterThemeModules(themeElements, whiteList) : whiteList;

	const isDisabled =
		(!isGlobal &&
			(isModuleDisabled(selectedContent.component, componentType, filteredActivatedModules) || !isTemplateActivated)) ||
		isFieldReadOnly ||
		field.disabled;

	const isMetaTitleModified = selectedContent.metaTitle && selectedContent.metaTitle !== selectedContent.title;

	const setDefaultValues = (defaultParent: number | null, hasDefaultIndex: boolean) => {
		defaultParent && updateValue("parent", defaultParent);
		hasDefaultIndex && updateValue("isIndexed", templateConfig.indexDefault);
	};

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		isNewPage && setDefaultValues(defaultParent, hasDefaultIndex);
	}, [isPageHome]);

	let updateValue = (key: string, value: any, templateID?: number, slugTo?: string) => {
		if (key === "parent") {
			getPageBreadcrumb(value);
		}

		const editorID = templateID ? templateID : selectedEditorID;
		updateEditorContent(editorID, key, value);

		if (slugTo) {
			const slugValue = typeof value === "object" && value.content ? value.content : value;
			updateEditorContent(selectedEditorID, slugTo, slugify(slugValue));
		}

		if (key === "isHome") {
			if (value) {
				setOldConfig({ slug: selectedContent.slug, parent: selectedContent.parent });
				updateEditorContent(selectedEditorID, ["parent", "slug"], [null, "/"]);
			} else {
				const slugValue = oldConfig ? oldConfig.slug : slugify(selectedContent.title);
				const parentValue = oldConfig ? oldConfig.parent : null;
				updateEditorContent(selectedEditorID, ["parent", "slug"], [parentValue, slugValue]);
				setOldConfig(null);
			}
		}

		const isPageTitle = ["Page", "GlobalPage"].includes(selectedContent.component) && key === "title";
		if (isPageTitle) {
			setCurrentPageName(value);

			const canModifySlug = !selectedContent.id && !selectedContent.isHome;
			if (canModifySlug) {
				updateEditorContent(selectedEditorID, "slug", slugify(value));
			}

			if (!isMetaTitleModified) {
				updateEditorContent(selectedEditorID, "metaTitle", value.trim());
			}
		}

		const isComponentImage = ["LinkableImage", "Image"].includes(selectedContent.component) && key === "file";
		if (isComponentImage) {
			updateEditorContent(selectedEditorID, ["title", "alt"], [value.title, value.alt]);
		}
	};

	if (isOverride) {
		if (!field.modifiable) return <></>;

		updateValue = (key: string, value: any) => {
			updateEditorContent(selectedEditorID, key, value);
			const id = selectedContent.id;
			const params = { id, key, value };
			overwriteHeaderConfig(params);
		};
	}

	if (isTemplate || isFormTemplate) {
		const templateType = selectedContent[field.key]?.templateType;
		const template = isFormTemplate ? getFormTemplate(templateType) : getTemplate(templateType);

		if (!template) {
			return <></>;
		}

		return (
			<TemplateManager
				template={template}
				updateValue={updateValue}
				goTo={goTo}
				objKey={objKey}
				pages={pages}
				selectedTab={selectedTab}
				selectedContent={selectedContent}
				actions={actions}
				site={site}
				disabled={isDisabled}
				isTemplateActivated={isTemplateActivated}
				deleteError={deleteError}
				errors={errors}
				theme={theme}
				moduleCopy={moduleCopy}
				setHistoryPush={setHistoryPush}
				lang={lang.id}
				activatedModules={filteredActivatedModules}
				isForm={isFormTemplate}
				languages={languages}
			/>
		);
	}

	if (isFormPage) {
		return <></>;
	}

	return (
		<Field
			whiteList={filteredWhiteList}
			objKey={objKey}
			field={field}
			selectedContent={selectedContent}
			goTo={goTo}
			updateValue={updateValue}
			pages={pages}
			actions={actions}
			site={site}
			lang={lang.id}
			disabled={isDisabled}
			readonly={isFieldReadOnly}
			activatedModules={filteredActivatedModules}
			isTemplateActivated={isTemplateActivated}
			error={error}
			deleteError={deleteError}
			errors={errors}
			theme={theme}
			moduleCopy={moduleCopy}
			availableDataPacks={availableDataPacks}
			template={template}
			setHistoryPush={setHistoryPush}
			languages={languages}
			scrollEditorID={scrollEditorID}
		/>
	);
};

const mapStateToProps = (state: IRootState) => ({
	selectedEditorID: state.pageEditor.selectedEditorID,
	selectedContent: { ...state.pageEditor.selectedContent },
	pages: state.sites.currentSitePages,
	site: state.sites.currentSiteInfo,
	lang: state.app.lang,
	activatedTemplates: state.dataPacks.templates,
	templateConfig: state.pageEditor.templateConfig,
	activatedModules: state.dataPacks.modules,
	errors: state.pageEditor.errors,
	moduleCopy: state.pageEditor.moduleCopy,
	availableDataPacks: state.dataPacks.available,
	template: state.pageEditor.template,
	siteLanguages: state.sites.currentSiteLanguages,
	globalLanguages: state.app.globalLangs,
	themeElements: state.sites.themeElements,
	scrollEditorID: state.pageEditor.scrollEditorID,
});

const mapDispatchToProps = {
	updateEditorContent: pageEditorActions.updateEditorContent,
	overwriteHeaderConfig: pageEditorActions.overwriteHeaderConfig,
	setCurrentPageName: pageEditorActions.setCurrentPageName,
	getPageBreadcrumb: pageEditorActions.getPageBreadcrumb,
	deleteError: pageEditorActions.deleteError,
};

export default connect(
	mapStateToProps,
	mapDispatchToProps,
)(memo(PageConnectedField, areEqual) as typeof PageConnectedField);
