import { useEffect, useState } from "react";
import { connect } from "react-redux";

import type { IErrorItem, ILanguage, IRootState, ISite } from "@ax/types";
import { structuredDataActions } from "@ax/containers/StructuredData";
import { FieldsBehavior } from "@ax/components";
import { getStructuredDataInnerFields } from "@ax/forms";

import * as S from "./style";

const ConnectedField = (props: IProps) => {
	const { field, site, form, fieldKey, updateFormValue, disabled, errors, deleteError, theme, lang, languages } = props;

	const isConditional = field.type === "ConditionalField";
	const isArrayGroup = field.type === "ArrayFieldGroup";
	const isComputedField = Object.prototype.hasOwnProperty.call(field, "computed");
	const isFieldDisabled = disabled || isComputedField;
	const error = errors.find((err: any) => err.key === field.key);

	const [value, setValue] = useState(form?.content?.[fieldKey]);
	const [timeOut, setTimeOut] = useState(form?.content?.[fieldKey]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		const evaluateDataComputedFields = async () => {
			const data = {
				operation: "refresh",
				apiUrl: process.env.GRIDDO_API_URL || process.env.REACT_APP_API_ENDPOINT,
				publicApiUrl: process.env.GRIDDO_PUBLIC_API_URL || process.env.REACT_APP_PUBLIC_API_ENDPOINT,
			};
			// biome-ignore lint/security/noGlobalEval: its safe
			const computedFunction = eval(`(${field.computed})`);
			const value = await computedFunction(form.content, data);
			setValue(value);
		};

		if (isComputedField && form?.content) {
			if (timeOut) {
				clearTimeout(timeOut);
			}
			const timeoutId = setTimeout(async () => {
				await evaluateDataComputedFields();
			}, 1500);

			setTimeOut(timeoutId);
		}
	}, [form?.content]);

	const handleChange = (newValue: any) => {
		setValue(newValue);
		updateFormValue({ [fieldKey]: newValue });
	};

	let innerFields: JSX.Element[] = [];

	if (isConditional || isArrayGroup) {
		innerFields = getStructuredDataInnerFields(field.fields, form?.content, updateFormValue, theme, errors);
	}

	const fieldProps = {
		objKey: field.key,
		value,
		onChange: handleChange,
		site,
		disabled: isFieldDisabled,
		fieldType: field.type,
		...field,
		innerFields,
		error,
		deleteError,
		theme,
		delayed: false,
		lang: lang.id,
		languages,
	};

	return (
		<S.Wrapper>
			<FieldsBehavior {...fieldProps} />
		</S.Wrapper>
	);
};

interface IProps {
	field: any;
	form: any;
	site: ISite | null;
	fieldKey: string;
	disabled: boolean;
	errors: IErrorItem[];
	updateFormValue: (value: any) => void;
	deleteError: (error: IErrorItem) => void;
	theme: string;
	lang: { locale: string; id: number };
	languages: ILanguage[];
}

const mapStateToProps = (state: IRootState) => ({
	form: state.structuredData.form,
	errors: state.structuredData.errors,
	lang: state.app.lang,
});

const mapDispatchToProps = {
	updateFormValue: structuredDataActions.updateFormValue,
	deleteError: structuredDataActions.deleteError,
};

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