import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { ResizePanel } from "@ax/components";
import { IBreadcrumbItem, IErrorItem, IModule, INotification, IRootState, ISchema, ISchemaField } from "@ax/types";
import { formsActions } from "@ax/containers/Forms";
import { getFormTemplate } from "@ax/helpers";
import PageBrowser from "../PageBrowser";
import FormConfigPanel from "./FormConfigPanel";
import SideModal from "./SideModal";

import * as S from "./style";

const Editor = (props: IProps) => {
	const {
		isLoading,
		isGlobal,
		theme,
		browserRef,
		schema,
		selectedTab,
		breadcrumb,
		selectedParent,
		errors,
		template,
		isDisabled,
		setErrors,
		setNotification,
		setSelectedTab,
		setSelectedContent,
		addModule,
		deleteModule,
		duplicateModule,
		moveModule,
		copyModule,
		pasteModule,
	} = props;

	const [selectedField, setSelectedField] = useState<ISchemaField | null>(null);
	const [fieldArrays, setFieldArrays] = useState<ISchemaField[]>([]);

	const hasFieldArrays = !!fieldArrays && fieldArrays.length > 0;
	const isMultiArray = fieldArrays.length > 1;

	useEffect(() => {
		const getFormFieldArrays = (schema: ISchema | Record<string, never>) => {
			let content: ISchemaField[] = [];
			if (schema.component === "FormPage") {
				const templateSchema = getFormTemplate(template);
				content = templateSchema?.content || [];
			} else {
				content = schema.configTabs[0].fields;
			}

			content.forEach((field) => {
				if ((field.type === "FieldGroup" || field.type === "ConditionalField") && field.fields) {
					content = [...content, ...field.fields];
				}
			});

			return content.filter((field: ISchemaField) => field.type === "FormFieldArray");
		};

		const fields = getFormFieldArrays(schema);
		const initState = fields.length === 1 ? fields[0] : null;
		setFieldArrays(fields);
		setSelectedField(initState);
	}, [schema, template]);

	const handleClick = (fieldType: string) => !!selectedField && addModule(fieldType, selectedField.key);

	const handleSetSelectedField = (field: ISchemaField | null) => setSelectedField(field);

	const actions = {
		setNotificationAction: setNotification,
		addModuleAction: addModule,
		deleteModuleAction: deleteModule,
		duplicateModuleAction: duplicateModule,
		moveModuleAction: moveModule,
		copyModuleAction: copyModule,
		pasteModuleAction: pasteModule,
		setSelectedFormFieldAction: isMultiArray ? handleSetSelectedField : undefined,
	};

	return (
		<ResizePanel
			leftPanel={
				<S.EditorWrapper>
					{hasFieldArrays && !isDisabled && (
						<SideModal
							onClick={handleClick}
							theme={theme}
							fieldArrays={fieldArrays}
							selectedField={selectedField}
							selectField={handleSetSelectedField}
						/>
					)}
					<PageBrowser isReadOnly={isDisabled} theme={theme} browserRef={browserRef} />
				</S.EditorWrapper>
			}
			rightPanel={
				<FormConfigPanel
					schema={schema}
					actions={actions}
					isLoading={isLoading}
					isGlobal={isGlobal}
					theme={theme}
					setSelectedTab={setSelectedTab}
					selectedTab={selectedTab}
					setSelectedContent={setSelectedContent}
					breadcrumb={breadcrumb}
					selectedParent={selectedParent}
					errors={errors}
					setErrors={setErrors}
					isDisabled={isDisabled}
				/>
			}
			full={true}
		/>
	);
};

interface IEditorStateProps {
	isLoading: boolean;
	selectedTab: string;
	schema: ISchema | Record<string, never>;
	breadcrumb: IBreadcrumbItem[];
	selectedParent: Record<string, unknown> | null;
	template: string;
}

interface IPageBrowserDispatchProps {
	setNotification: (notification: INotification) => void;
	setSelectedTab(tab: string): void;
	setSelectedContent(editorID: number): void;
	addModule: (moduleType: string, key: string) => void;
	deleteModule: (editorID: number[], key?: string) => void;
	duplicateModule: (editorID: number[], key?: string) => number;
	moveModule: (elementID: number[], content: any, newIndex: number, key: string) => void;
	copyModule: (editorID: number[]) => boolean | number;
	pasteModule: (editorID: number, key: string, modulesToPaste: IModule[]) => Promise<{ error?: INotification }>;
	isGlobal: boolean;
	theme: string;
	browserRef: React.RefObject<HTMLDivElement>;
	errors: IErrorItem[];
	isDisabled: boolean;
	setErrors(errors: IErrorItem[]): void;
}

type IProps = IEditorStateProps & IPageBrowserDispatchProps;

const mapStateToProps = (state: IRootState): IEditorStateProps => ({
	isLoading: state.app.isLoading,
	selectedTab: state.forms.tab,
	schema: state.forms.schema,
	breadcrumb: state.forms.breadcrumb,
	selectedParent: state.forms.selectedParent,
	template: state.forms.template,
});

const mapDispatchToProps = {
	setSelectedTab: formsActions.setSelectedTab,
	setSelectedContent: formsActions.setSelectedContent,
	addModule: formsActions.addModule,
	deleteModule: formsActions.deleteModule,
	duplicateModule: formsActions.duplicateModule,
	moveModule: formsActions.moveModule,
	copyModule: formsActions.copyModule,
	pasteModule: formsActions.pasteModule,
};

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