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

import { FieldContainer } from "@ax/components";
import { navigationActions } from "@ax/containers/Navigation";
import { getInnerFields } from "@ax/forms";
import { areEqual, filterThemeModules, getFormTemplate } from "@ax/helpers";
import type { IRootState, ISchemaField } from "@ax/types";

const NavConnectedField = (props: any): JSX.Element => {
	const {
		whiteList,
		objKey,
		field,
		selectedContent,
		goTo,
		updateEditorContent,
		selectedEditorID,
		pages,
		actions,
		site,
		lang,
		currentDefaultsContent,
		activatedTemplates,
		menus,
		theme,
		disabled,
		moduleCopy,
		themeElements,
		isReadOnly,
		tab,
	} = props;

	const updateValue = (key: string, value: any, templateID?: number) => {
		const isMenu = field.entity && field.entity === "menu_containers";
		const editorID = templateID ? templateID : selectedEditorID;
		if (isMenu) {
			const menu = menus.find((menu: any) => menu.id === value);
			updateEditorContent(selectedEditorID, key, menu);
		} else {
			updateEditorContent(editorID, key, value);
		}
	};

	const isSetAsDefaultField = objKey === "setAsDefault";
	const currentDefaultNav = currentDefaultsContent.find((item: any) => item.setAsDefault);
	const defaultNavId = currentDefaultNav && currentDefaultNav.id;
	const selectedContentId = selectedContent && selectedContent.id;
	const isDefaultNav = defaultNavId === selectedContentId;
	const isDisabled = (isSetAsDefaultField && isDefaultNav) || isReadOnly;
	const isConditional = field.type === "ConditionalField";
	const isArrayGroup = field.type === "ArrayFieldGroup";
	const isFormPage = selectedContent.component === "FormPage";
	const isFormTemplate = field.type === "formTemplate";

	let isTemplateActivated = true;
	if (selectedContent.template) {
		isTemplateActivated = activatedTemplates.find((temp: any) => temp.id === selectedContent.template.templateType)
			? true
			: false;
	}

	let innerFields: JSX.Element[] = [];

	if (isConditional || isArrayGroup) {
		const innerActions = { ...actions, updateValue, goTo };
		innerFields = getInnerFields(
			field.fields,
			innerActions,
			selectedContent,
			isTemplateActivated,
			theme,
			moduleCopy,
			!!disabled || isDisabled,
			site,
		);
	}

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

	if (isFormTemplate) {
		const template = getFormTemplate(selectedContent[field.key].templateType);
		if (!template) return <></>;

		const templateFields: ISchemaField[] = template[tab].filter((templateField: ISchemaField) => {
			const isHidden = templateField.hidden || !templateField.overwrite;
			return !isHidden;
		});

		const templateContent = selectedContent.template;
		const handleUpdate = (fieldKey: string, value: any) => updateValue(fieldKey, value, templateContent.editorID);

		return (
			<>
				{templateFields.map((formField) => {
					const { key, whiteList = [], disabled } = formField;
					return (
						<FieldContainer
							whiteList={whiteList}
							key={key}
							objKey={key}
							field={formField}
							selectedContent={templateContent}
							goTo={goTo}
							updateValue={handleUpdate}
							pages={pages}
							actions={actions}
							site={site}
							lang={lang}
							disabled={disabled}
							innerFields={innerFields}
							theme={theme}
							moduleCopy={moduleCopy}
						/>
					);
				})}
			</>
		);
	}

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

	return (
		<FieldContainer
			whiteList={filteredWhiteList}
			key={objKey}
			objKey={objKey}
			field={field}
			selectedContent={selectedContent}
			goTo={goTo}
			updateValue={updateValue}
			pages={pages}
			actions={actions}
			site={site}
			lang={lang}
			disabled={isDisabled}
			innerFields={innerFields}
			theme={theme}
			moduleCopy={moduleCopy}
		/>
	);
};

const mapStateToProps = (state: IRootState) => ({
	selectedEditorID: state.navigation.selectedEditorID,
	selectedContent: { ...state.navigation.selectedContent },
	pages: state.sites.currentSitePages,
	site: state.sites.currentSiteInfo,
	lang: state.app.lang,
	currentDefaultsContent: state.navigation.currentDefaultsContent,
	activatedTemplates: state.dataPacks.templates,
	menus: state.menu.savedMenus,
	moduleCopy: state.navigation.moduleCopy,
	themeElements: state.sites.themeElements,
	tab: state.navigation.tab,
});

const mapDispatchToProps = {
	updateEditorContent: navigationActions.updateEditorContent,
};

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