import { useEffect, useRef, useState } from "react";

import { Loading } from "@ax/components";
import { isEmptyObj } from "@ax/helpers";
import { useFirefoxScrollLock } from "@ax/hooks";
import type { IBreadcrumbItem, IUserEditing } from "@ax/types";

import Form from "./Form";
import GlobalPageForm from "./GlobalPageForm";
import Header from "./Header";
import NavigationForm from "./NavigationForm";
import PreviewForm from "./PreviewForm";

import * as S from "./style";

const navigationModulesTypes = ["header", "footer"];

const ConfigPanel = (props: IStateProps) => {
	const {
		isLoading,
		schema,
		actions,
		breadcrumb,
		selectedParent,
		activatedModules,
		setSelectedContent,
		setSelectedTab,
		selectedTab,
		isPage,
		isGlobal,
		isEditable,
		pageTitle,
		setHistoryPush,
		isReadOnly,
		userEditing,
		theme,
		lastElementAddedId,
		header,
		footer,
		isEditLive,
		isDisabled = false,
		isDirty,
		onNavigateWithDirty,
	} = props;

	const wrapperRef = useRef<HTMLDivElement>(null);
	const headerRef = useRef<HTMLDivElement>(null);
	const [headerHeight, setHeaderHeight] = useState<number>(0);

	useEffect(() => {
		if (lastElementAddedId && wrapperRef.current) {
			const element = document.querySelector(`.editorId-${lastElementAddedId}`);
			element?.scrollIntoView();
		}
	}, [lastElementAddedId]);

	useFirefoxScrollLock(wrapperRef);

	if (isLoading || isEmptyObj(schema)) {
		return <Loading />;
	}
	const showNavigationForm = schema.type !== undefined && navigationModulesTypes.includes(schema.type) && isPage;
	const isGlobalPageNotEditable = isGlobal && isPage && !isEditable;

	const hasStickyHeader = !isReadOnly && !isGlobalPageNotEditable && !showNavigationForm;

	const getForm = () => {
		if (isReadOnly) {
			return <PreviewForm setSelectedTab={setSelectedTab} selectedTab={selectedTab} userEditing={userEditing} />;
		} else if (showNavigationForm) {
			return <NavigationForm schema={schema} theme={theme} />;
		} else if (isGlobalPageNotEditable) {
			return (
				<GlobalPageForm
					setSelectedTab={setSelectedTab}
					selectedTab={selectedTab}
					schema={schema}
					pageTitle={pageTitle}
					setHistoryPush={setHistoryPush}
					actions={actions}
					header={header}
					footer={footer}
					isDirty={isDirty}
					onNavigateWithDirty={onNavigateWithDirty}
				/>
			);
		} else {
			return (
				<Form
					actions={actions}
					schema={schema}
					setSelectedContent={setSelectedContent}
					setSelectedTab={setSelectedTab}
					selectedTab={selectedTab}
					isPage={isPage}
					isGlobal={isGlobal}
					theme={theme}
					setHistoryPush={setHistoryPush}
					header={header}
					footer={footer}
					isEditLive={isEditLive}
					headerHeight={headerHeight}
					isDisabled={isDisabled}
				/>
			);
		}
	};

	return (
		<S.Wrapper data-testid="config-panel-wrapper" ref={wrapperRef}>
			<Header
				schema={schema}
				actions={actions}
				breadcrumb={breadcrumb}
				selectedParent={selectedParent}
				activatedModules={activatedModules}
				setSelectedContent={setSelectedContent}
				headerRef={headerRef}
				setHeaderHeight={setHeaderHeight}
				hasStickyHeader={hasStickyHeader}
			/>
			{getForm()}
		</S.Wrapper>
	);
};

export interface IStateProps {
	isLoading: boolean;
	schema: any;
	actions: any;
	breadcrumb: IBreadcrumbItem[];
	selectedParent: any;
	activatedModules: string[];
	setSelectedContent(editorID: number): void;
	selectedTab: string;
	setSelectedTab(tab: string): void;
	isPage: boolean;
	isEditable: boolean;
	isGlobal?: boolean;
	pageTitle?: string;
	setHistoryPush?: (path: string, isEditor: boolean) => void;
	isReadOnly?: boolean;
	userEditing?: IUserEditing | null;
	theme: string;
	lastElementAddedId?: null | number;
	header?: number | null;
	footer?: number | null;
	isEditLive?: boolean;
	isDisabled?: boolean;
	isDirty?: boolean;
	onNavigateWithDirty?: (navigateCallback: () => void) => void;
}

export default ConfigPanel;
