import { useState } from "react";

import { Tabs } from "@ax/components";
import { usePermission } from "@ax/hooks";
import type { ISchema, ISchemaField, ISchemaTab } from "@ax/types";

import ConnectedField from "./ConnectedField";

import * as S from "./style";

const tabPermissions: Record<string, string> = {
	content: "content",
	config: "config",
	"seo & analytics": "seo",
};

export const Form = (props: IFormProps): JSX.Element => {
	const {
		schema,
		selectedTab,
		setSelectedTab,
		setSelectedContent,
		actions,
		isPage,
		isGlobal,
		theme,
		setHistoryPush,
		header,
		footer,
		isEditLive,
		headerHeight,
		isDisabled,
	} = props;

	const isAllowedToEditSitePages = usePermission("content.editContentPages");
	const isAllowedToEditGlobalData = usePermission("global.globalData.editAllGlobalData");
	const isAllowedToEditConfigPages = usePermission("content.editConfigPages");
	const isAllowedToEditSiteSeo = usePermission("seoAnalytics.editSeoAnalyticsPages");
	const isAllowedToEditGlobalSeo = usePermission("global.seoAnalytics.editSeoAnalyticsInGlobalPages");
	const [oldConfig, setOldConfig] = useState<IOldConfig | null>(null);

	const isAllowedToEditPageContent = (!isGlobal && isAllowedToEditSitePages) || (isGlobal && isAllowedToEditGlobalData);
	const isAllowedToEditPageConfig =
		(!isGlobal && isAllowedToEditConfigPages) || (isGlobal && isAllowedToEditGlobalData);
	const isAllowedToEditPageSEO = (!isGlobal && isAllowedToEditSiteSeo) || (isGlobal && isAllowedToEditGlobalSeo);

	const permissionsByTab: Record<string, boolean | undefined> = {
		content: isAllowedToEditPageContent,
		config: isAllowedToEditPageConfig,
		seo: isAllowedToEditPageSEO,
	};

	const tabContent = schema.configTabs.find((tab: ISchemaTab) => tab.title.toLowerCase() === selectedTab);

	const goTo = (editorID: number) => setSelectedContent(editorID);

	const generateFields = (field: ISchemaField) => {
		const { key, whiteList } = field;

		return (
			<ConnectedField
				selectedTab={selectedTab}
				whiteList={whiteList}
				key={key}
				objKey={key}
				field={field}
				goTo={goTo}
				actions={actions}
				componentType={schema.schemaType}
				isPage={isPage}
				isGlobal={isGlobal}
				theme={theme}
				setHistoryPush={setHistoryPush}
				isReadOnly={isEditLive || isDisabled}
				oldConfig={oldConfig}
				setOldConfig={setOldConfig}
			/>
		);
	};

	const getTabs = (): string[] => {
		const isHeader = schema.type === "header";
		const isPageSchema = schema.schemaType === "page";

		if (isHeader && isPage) {
			return schema.configTabs
				.filter((tab) => tab.fields.some((field: any) => field.modifiable))
				.map((tab) => tab.title);
		}

		return schema.configTabs
			.filter((tab: ISchemaTab) => {
				const currTitle = tab.title.toLowerCase();
				const permKey = tabPermissions[currTitle];
				return !isPageSchema || (permKey && permissionsByTab[permKey]);
			})
			.map((tab: ISchemaTab) => tab.title.toLowerCase());
	};

	const tabs = getTabs();

	const handleRestore = (type: "header" | "footer") => actions.restorePageNavigationAction?.(type);

	const renderRestoreNotice = (type: "header" | "footer", value?: number | null) => {
		if (selectedTab !== "content" || isGlobal || value !== 0) return null;

		return (
			<S.FieldWrapper>
				This page doesn&apos;t have a {type}. Click{" "}
				<S.Link data-testid={`${type}-link`} onClick={() => handleRestore(type)}>
					here
				</S.Link>{" "}
				to restore it.
			</S.FieldWrapper>
		);
	};

	return (
		<S.Wrapper data-testid="form-section">
			<S.TabsWrapper headerHeight={headerHeight}>
				<Tabs tabs={tabs} active={selectedTab} setSelectedTab={setSelectedTab} />
			</S.TabsWrapper>
			{selectedTab === "content" && isEditLive && (
				<S.FieldWrapper>
					There are some changes in the <strong>draft associated</strong> with this page. Before making changes to the
					published version, you should <strong>discard or publish your draft</strong>.
				</S.FieldWrapper>
			)}
			{renderRestoreNotice("header", header)}
			{renderRestoreNotice("footer", footer)}
			{tabContent?.fields.map((field: ISchemaField) => generateFields(field))}
		</S.Wrapper>
	);
};

interface IOldConfig {
	slug: string;
	parent: number;
}

export interface IFormProps {
	selectedTab: string;
	schema: ISchema;
	actions: any;
	setSelectedTab(tab: string): void;
	setSelectedContent(editorID: number): void;
	isPage: boolean;
	isGlobal?: boolean;
	theme: string;
	setHistoryPush?: (path: string, isEditor: boolean) => void;
	header?: number | null;
	footer?: number | null;
	isEditLive?: boolean;
	headerHeight: number;
	isDisabled: boolean;
}

export default Form;
