import { connect } from "react-redux";

import { filterThemeModules, getModuleCategories } from "@ax/helpers";
import type { IDataPack, IErrorItem, ILanguage, IRootState, ISchemaField, ISite, IThemeElements } from "@ax/types";

import Field from "../Field";

import * as S from "./style";

export const TemplateManager = (props: IProps): JSX.Element => {
	const {
		template,
		selectedTab,
		selectedContent,
		objKey,
		goTo,
		updateValue,
		pages,
		actions,
		site,
		activatedPacks,
		disabled,
		activatedModules = [],
		isTemplateActivated,
		deleteError,
		errors,
		theme,
		moduleCopy,
		availableDataPacks,
		setHistoryPush,
		lang,
		themeElements,
		scrollEditorID,
		isForm,
		languages,
	} = props;

	const isConfig = selectedTab === "config";
	const templateFields = template[selectedTab];
	const templateContent = selectedContent.template;
	const modulesDataPacks = activatedPacks.map((pack: IDataPack) => pack.modules).flat();

	const getFieldProps = (field: ISchemaField) => {
		const { key, type, whiteList = [], slugTo, readonly, disabled } = field;
		const isArr = type === "ComponentArray";
		const currentContent = isArr ? templateContent[key] : templateContent;
		const fieldObjKey = !isArr ? `${key}` : `modules`;
		const mappedField = !isArr ? { ...field, key: fieldObjKey } : field;
		const handleUpdate = (fieldKey: string, value: any) =>
			updateValue(fieldKey, value, templateContent.editorID, slugTo);
		const error = errors.find((err) => err.editorID === templateContent.editorID && err.key === key);
		const isComputedField = Object.prototype.hasOwnProperty.call(field, "computed");

		const addedModules: string[] = modulesDataPacks.reduce((acc: string[], current: any) => {
			if (
				current.sectionList &&
				current.sectionList[template.component] &&
				current.sectionList[template.component].includes(key) &&
				!acc.includes(current.id)
			) {
				return [...acc, current.id];
			}
			return acc;
		}, []);

		const mappedWhiteList: string[] = whiteList ? [...whiteList, ...addedModules].sort() : [...addedModules.sort()];
		const filteredWhiteList = filterThemeModules(themeElements, mappedWhiteList);
		const categories = getModuleCategories(filteredWhiteList);

		return {
			whiteList: filteredWhiteList,
			categories,
			key,
			fieldObjKey,
			mappedField,
			currentContent,
			handleUpdate,
			error,
			readonly,
			disabledField: isComputedField || disabled,
		};
	};

	return (
		<>
			{isConfig && templateFields && !isForm && <S.Title>Template Options</S.Title>}
			{templateFields &&
				templateFields
					.filter((templateField: ISchemaField) => {
						const isHidden = templateField.hidden || (isForm && !templateField.overwrite);
						return !isHidden;
					})
					.map((templateField: ISchemaField, index: number) => {
						const {
							whiteList,
							categories,
							key,
							fieldObjKey,
							mappedField,
							currentContent,
							handleUpdate,
							error,
							readonly,
							disabledField,
						} = getFieldProps(templateField);

						return (
							<Field
								whiteList={whiteList}
								key={`${objKey}.${key}${index}`}
								objKey={fieldObjKey}
								field={mappedField}
								selectedContent={currentContent}
								goTo={goTo}
								updateValue={handleUpdate}
								pages={pages}
								actions={actions}
								site={site}
								disabled={disabled || disabledField}
								activatedModules={activatedModules}
								isTemplateActivated={isTemplateActivated}
								categories={categories}
								error={error}
								deleteError={deleteError}
								errors={errors}
								theme={theme}
								moduleCopy={moduleCopy}
								availableDataPacks={availableDataPacks}
								template={template}
								setHistoryPush={setHistoryPush}
								lang={lang}
								readonly={readonly}
								scrollEditorID={scrollEditorID}
								languages={languages}
							/>
						);
					})}
		</>
	);
};

interface IProps {
	template: any;
	updateValue: (key: string, value: any, templateID?: number, slugTo?: string) => void;
	goTo: any;
	objKey: string;
	pages: any;
	selectedTab: string;
	selectedContent: any;
	actions: any;
	site?: ISite;
	activatedPacks: IDataPack[];
	disabled?: boolean;
	activatedModules: string[];
	isTemplateActivated: boolean;
	deleteError(error: IErrorItem): void;
	errors: IErrorItem[];
	theme: string;
	moduleCopy: { date: string; element: Record<string, unknown> } | null;
	availableDataPacks: Record<string, any>[];
	setHistoryPush?: (path: string, isEditor: boolean) => void;
	lang: number;
	themeElements: IThemeElements | null;
	scrollEditorID: number | null;
	isForm: boolean;
	languages: ILanguage[];
}

const mapStateToProps = (state: IRootState) => ({
	activatedPacks: state.dataPacks.activated,
	availableDataPacks: state.dataPacks.available,
	themeElements: state.sites.themeElements,
	scrollEditorID: state.pageEditor.scrollEditorID,
});

export default connect(mapStateToProps)(TemplateManager);
