import { IComponent, IIntegration, IRootState, ISavePageParams } from "@ax/types";
import { addElement, cleanContent, updateElementCollection } from "@ax/forms";
import { Dispatch } from "redux";
import { generatePageContent, setSelectedContent } from "./actions";

const getPageParams = (getState: any): ISavePageParams => {
	const {
		sites: { currentSiteInfo },
		pageEditor: { editorContent },
	} = getState();
	return {
		site: currentSiteInfo,
		page: editorContent,
	};
};

const getPageData = (getState: any, deleted: boolean, params = getPageParams(getState)) => {
	const { site, page } = params;
	const siteID = site ? site.id : null;
	const updatedPageContent = { ...page, site: siteID };
	const { id } = page;
	const values = {
		...cleanContent(updatedPageContent),
		deleted,
	};

	return {
		id,
		values,
	};
};

const getTemplateValues = (template: any) => {
	const sections = Object.keys(template)
		.map((key: string) => ({ ...template[key], key }))
		.filter((value: any) => typeof value === "object" && value !== null && value.component === "Section");

	return sections;
};

const getStateValues = (getState: any) => {
	const {
		pageEditor: { editorContent, selectedEditorID, selectedContent, template, errors },
	} = getState();
	const { header, footer } = editorContent;

	const editorID: number = selectedEditorID;
	const sections = getTemplateValues(editorContent.template);

	return {
		editorContent,
		header,
		footer,
		sections,
		editorID,
		template,
		selectedContent,
		errors,
	};
};

const getPageNavigation = (
	headerID: number | null,
	footerID: number | null,
	defaultsContent: any,
	isGlobal?: boolean,
): { header: any; footer: any } => {
	if (isGlobal) {
		return { header: null, footer: null };
	}

	const headers: any = defaultsContent.filter((content: any) => content.type === "header");
	const footers: any = defaultsContent.filter((content: any) => content.type === "footer");

	const headerDefault = headers.find((content: any) => content.setAsDefault);
	const footerDefault = footers.find((content: any) => content.setAsDefault);

	const header =
		headerID === 0
			? headerID
			: headerID === undefined || headerID === null
				? headerDefault
				: headers.find((content: any) =>
						content.navigationLanguages.some((navLang: any) => navLang.navigationId === headerID),
					) || headerDefault;

	const footer =
		footerID === 0
			? footerID
			: footerID === undefined || footerID === null
				? footerDefault
				: footers.find((content: any) =>
						content.navigationLanguages.some((navLang: any) => navLang.navigationId === footerID),
					) || footerDefault;

	return { header, footer };
};

const getDefaultIntegrations = (dataPacks: any, integrations: IIntegration[], template: string): IIntegration[] => {
	const templateIntegrations = dataPacks.activated.find((pack: any) =>
		pack.templates.some((packTemplate: any) => packTemplate.id === template),
	)?.config?.templates?.[template]?.integrations;

	const availableIntegrations = integrations.filter(
		(integration: IIntegration) =>
			!templateIntegrations?.some((_integration: IIntegration) => Number(_integration.id) === Number(integration.id)),
	);

	const allPagesIntegrations = availableIntegrations.filter(
		(integration: IIntegration) => integration.contentPresence.presenceType === "all" && integration.active,
	);

	const defaultIntegrations: IIntegration[] = [];
	templateIntegrations && defaultIntegrations.push(...templateIntegrations);
	allPagesIntegrations && defaultIntegrations.push(...allPagesIntegrations);

	return defaultIntegrations;
};

const getDefaultPageNavigation = (defaultsContent: any, type: string) => {
	const navigations: any = defaultsContent.filter((content: any) => content.type === type);

	const navitagion = navigations.find((content: any) => content.setAsDefault);

	return navitagion;
};

const addElementToComponent = (component: Record<string, any>, type: IComponent) => {
	const element = addElement(type);
	Object.keys(component).forEach((key: string) => {
		const containedValue = component[key];
		if (containedValue?.editorID === type.editorID) {
			component[key] = element;
		}
	});
	return component;
};

const addElementToCollection = (
	type: string | IComponent,
	key: string,
	dispatch: Dispatch,
	getState: () => IRootState,
) => {
	const isSimpleField = typeof type === "string";
	const { editorContent } = getStateValues(getState);

	const updatedComponent = isSimpleField
		? updateElementCollection(type, editorContent.template[key])
		: addElementToComponent(editorContent.template[key], type);

	const updatedPageContent = { ...editorContent, template: { ...editorContent.template, [key]: updatedComponent } };

	generatePageContent(updatedPageContent)(dispatch, getState);

	if (isSimpleField) {
		const { editorContent: generatedEditor } = getStateValues(getState);
		const generatedElement = generatedEditor.template[key];
		const lastModuleEditorID = generatedElement[generatedElement.length - 1].editorID as number;
		return lastModuleEditorID;
	} else {
		setSelectedContent(type.editorID)(dispatch, getState);
	}
};

export {
	getPageParams,
	getPageData,
	getStateValues,
	getPageNavigation,
	getDefaultIntegrations,
	getDefaultPageNavigation,
	addElementToCollection,
	addElementToComponent,
};
