import { useEffect, useState } from "react";

import { Button, FieldsDivider } from "@ax/components";
import { getDefaultSchema } from "@ax/helpers";
import type { ISite } from "@ax/types";

import { v4 as uuidv4 } from "uuid";

import ArrayFieldInline from "./ArrayFieldInline";
import ArrayFieldItem from "./ArrayFieldItem";

import * as S from "./style";

const ArrayFieldGroup = (props: IProps): JSX.Element => {
	const {
		value,
		name,
		innerFields,
		onChange,
		divider,
		arrayType,
		site,
		disabled,
		editorID,
		objKey,
		selectedContent,
		actions,
	} = props;

	const [items, setItems] = useState<any[]>([]);
	const [isOpen, setIsOpen] = useState<number | null>(null);

	// biome-ignore lint/correctness/useExhaustiveDependencies: false positive
	useEffect(() => {
		const initialValue = value ? Object.values(value) : [];
		const initialValueMapped = initialValue.map((val) => {
			return val.id ? val : { id: uuidv4(), ...val };
		});
		setItems(initialValueMapped);
	}, [editorID]);

	const handleClick = () => {
		let newComponent = { id: uuidv4() };
		if (selectedContent) {
			const defaultValues = getDefaultSchema(selectedContent.component);
			newComponent =
				!!defaultValues[objKey] && defaultValues[objKey].length
					? { ...defaultValues[objKey][0], id: uuidv4() }
					: newComponent;
		}

		const newItems = [...items, newComponent];
		setItems(newItems);
		onChange(newItems);
		setIsOpen(newItems.length - 1);
	};

	const handleChange = (newValue: Record<string, unknown>, index: number) => {
		const updatedItems = [...items];
		updatedItems[index] = {
			...updatedItems[index],
			...newValue,
		};
		setItems(updatedItems);
		onChange(updatedItems);
	};

	const handleDelete = (index: number) => {
		const updatedItems = [...items];
		updatedItems.splice(index, 1);
		setItems(updatedItems);
		onChange(updatedItems);
	};

	const DividerComponent = () => (divider ? <FieldsDivider data={divider} /> : null);

	return (
		<div>
			<DividerComponent />
			<div>
				{items?.map((item, index) => {
					const handleFieldChange = (newValue: Record<string, unknown>) => handleChange(newValue, index);
					return arrayType === "inline" ? (
						<ArrayFieldInline
							key={item.id}
							fields={innerFields}
							item={item}
							index={index}
							onChange={handleFieldChange}
							handleDelete={handleDelete}
							site={site}
							disabled={disabled}
							parentKey={objKey}
							actions={actions}
						/>
					) : (
						<ArrayFieldItem
							key={item.id}
							name={name}
							fields={innerFields}
							item={item}
							index={index}
							onChange={handleFieldChange}
							handleDelete={handleDelete}
							isOpen={isOpen}
							setIsOpen={setIsOpen}
							site={site}
							disabled={disabled}
							parentKey={objKey}
							actions={actions}
						/>
					);
				})}
			</div>
			<S.ButtonWrapper>
				<Button type="button" onClick={handleClick} buttonStyle="line" disabled={disabled}>
					{`Add ${name}`}
				</Button>
			</S.ButtonWrapper>
		</div>
	);
};

export interface IProps {
	value: Record<string, unknown>[];
	name: string;
	onChange: (value: Record<string, unknown>[]) => void;
	innerFields: any[];
	divider: { title: string; text: string };
	arrayType: string;
	site: ISite | null;
	disabled?: boolean;
	editorID: number;
	objKey: string;
	selectedContent: any;
	actions: any;
}

export default ArrayFieldGroup;
