import { connect } from "react-redux";

import { pageEditorActions } from "@ax/containers/PageEditor";
import { sitesActions } from "@ax/containers/Sites";
import { appActions } from "@ax/containers/App";
import { ConfigPanel, ResizePanel } from "@ax/components";
import type {
	HeadingFilter,
	IBreadcrumbItem,
	IModule,
	INotification,
	IRootState,
	ISchema,
	ISite,
	IUserEditing,
} from "@ax/types";

import PageBrowser from "../PageBrowser";

const Editor = (props: IProps) => {
	const {
		setSelectedContent,
		isTemplateActivated,
		selectedTab,
		schema,
		breadcrumb,
		selectedParent,
		activatedModules,
		setSelectedTab,
		deleteModule,
		addComponent,
		addModule,
		moveElement,
		replaceModule,
		duplicateModule,
		replaceElementsInCollection,
		isLoading,
		isGlobal,
		isEditable,
		pageTitle,
		setHistoryPush,
		getGlobalFromLocalPage,
		saveCurrentSiteInfo,
		isReadOnly,
		userEditing,
		site,
		browserRef,
		lastElementAddedId,
		copyModule,
		pasteModule,
		setNotification,
		restorePageNavigation,
		toggleHeadingsPreview,
		toggleKeywordsPreview,
		content,
		isEditLive,
		isDisabled,
		isHeadingsPreviewOpen,
		headingsFilter,
		isKeywordsPreviewOpen,
		keywordsFilter,
		isDirty,
		onNavigateWithDirty,
	} = props;

	if (!site) {
		throw new Error(`ERROR: User reached Editor with null site info`);
	}

	const { header, footer, theme: pageTheme } = content;
	const { theme: siteTheme } = site;

	const actions = {
		deleteModuleAction: deleteModule,
		addComponentAction: addComponent,
		addModuleAction: addModule,
		moveModuleAction: moveElement,
		replaceModuleAction: replaceModule,
		duplicateModuleAction: duplicateModule,
		replaceElementsInCollectionAction: replaceElementsInCollection,
		getGlobalFromLocalPageAction: getGlobalFromLocalPage,
		saveCurrentSiteInfoAction: saveCurrentSiteInfo,
		copyModuleAction: copyModule,
		pasteModuleAction: pasteModule,
		setNotificationAction: setNotification,
		restorePageNavigationAction: restorePageNavigation,
		toggleHeadingsPreviewAction: toggleHeadingsPreview,
		toggleKeywordsPreviewAction: toggleKeywordsPreview,
	};

	return (
		<ResizePanel
			disabled={isHeadingsPreviewOpen || isKeywordsPreviewOpen}
			leftPanel={
				<PageBrowser
					isTemplateActivated={isTemplateActivated}
					isReadOnly={isReadOnly || isEditLive || isDisabled}
					browserRef={browserRef}
					isHeadingsPreviewOpen={isHeadingsPreviewOpen}
					toggleHeadingsPreview={toggleHeadingsPreview}
					headingsFilter={headingsFilter}
					toggleKeywordsPreview={toggleKeywordsPreview}
					isKeywordsPreviewOpen={isKeywordsPreviewOpen}
					keywordsFilter={keywordsFilter}
				/>
			}
			rightPanel={
				<ConfigPanel
					schema={schema}
					actions={actions}
					breadcrumb={breadcrumb}
					selectedParent={selectedParent}
					activatedModules={activatedModules}
					setSelectedContent={setSelectedContent}
					setSelectedTab={setSelectedTab}
					selectedTab={selectedTab}
					isPage={true}
					isLoading={isLoading}
					isGlobal={isGlobal}
					isEditable={isEditable}
					pageTitle={pageTitle}
					setHistoryPush={setHistoryPush}
					isReadOnly={isReadOnly}
					userEditing={userEditing}
					theme={pageTheme ? pageTheme : siteTheme}
					lastElementAddedId={lastElementAddedId}
					header={header}
					footer={footer}
					isEditLive={isEditLive}
					isDisabled={isDisabled}
					isDirty={isDirty}
					onNavigateWithDirty={onNavigateWithDirty}
				/>
			}
		/>
	);
};

interface IEditorStateProps {
	// TODO: Define content Type
	schema: ISchema | Record<string, unknown>;
	breadcrumb: IBreadcrumbItem[];
	selectedParent: any;
	activatedModules: string[];
	selectedTab: string;
	isLoading: boolean;
	userEditing: IUserEditing | null;
	site: ISite | null;
	lastElementAddedId: null | number;
	content: any;
}

interface IPageBrowserDispatchProps {
	setSelectedContent(editorID: number): void;
	setSelectedTab(tab: string): void;
	deleteModule(editorID: number[], key?: string): void;
	duplicateModule(editorID: number[], key?: string): number;
	addComponent: (componentType: any, key: string) => void;
	addModule: (moduleType: string, key: string, selectedID: number, isComponentModule?: boolean) => void;
	moveElement(moduleID: number[], selectedContent: any, newIndex: number, key: string): void;
	replaceModule(module: any, parent: any, objKey: string): void;
	replaceElementsInCollection(newValue: string, reference?: string): void;
	setHistoryPush(path: string, isEditor: boolean): void;
	getGlobalFromLocalPage(): void;
	saveCurrentSiteInfo(): void;
	copyModule(editorID: number[]): boolean | number;
	pasteModule(editorID: number, key: string, modulesToPaste: IModule[]): Promise<{ error?: INotification }>;
	setNotification: (notification: INotification) => void;
	restorePageNavigation: (key: string) => void;
	toggleHeadingsPreview: () => void;
	toggleKeywordsPreview: () => void;
	isTemplateActivated: boolean;
	isGlobal: boolean;
	isEditable: boolean;
	pageTitle: string;
	isReadOnly: boolean;
	browserRef: React.RefObject<HTMLDivElement>;
	isEditLive: boolean;
	isDisabled: boolean;
	isHeadingsPreviewOpen: boolean;
	headingsFilter: HeadingFilter;
	isKeywordsPreviewOpen: boolean;
	keywordsFilter: string[];
	isDirty?: boolean;
	onNavigateWithDirty?: (navigateCallback: () => void) => void;
}

type IProps = IEditorStateProps & IPageBrowserDispatchProps;

const mapStateToProps = (state: IRootState): IEditorStateProps => ({
	schema: state.pageEditor.schema,
	breadcrumb: state.pageEditor.breadcrumb,
	selectedParent: state.pageEditor.selectedParent,
	activatedModules: state.dataPacks.modules,
	selectedTab: state.pageEditor.tab,
	isLoading: state.app.isLoading,
	userEditing: state.pageEditor.userEditing,
	site: state.sites.currentSiteInfo,
	lastElementAddedId: state.pageEditor.lastElementAddedId,
	content: state.pageEditor.editorContent,
});

const mapDispatchToProps = {
	setSelectedContent: pageEditorActions.setSelectedContent,
	setSelectedTab: pageEditorActions.setSelectedTab,
	deleteModule: pageEditorActions.deleteModule,
	duplicateModule: pageEditorActions.duplicateModule,
	addComponent: pageEditorActions.addComponent,
	addModule: pageEditorActions.addModule,
	moveElement: pageEditorActions.moveElement,
	replaceModule: pageEditorActions.replaceModule,
	replaceElementsInCollection: pageEditorActions.replaceElementsInCollection,
	setHistoryPush: appActions.setHistoryPush,
	getGlobalFromLocalPage: pageEditorActions.getGlobalFromLocalPage,
	saveCurrentSiteInfo: sitesActions.saveCurrentSiteInfo,
	copyModule: pageEditorActions.copyModule,
	pasteModule: pageEditorActions.pasteModule,
	restorePageNavigation: pageEditorActions.restorePageNavigation,
};

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