import { React } from '@gravityforms/libraries';
import { sprintf } from '@gravityforms/utils';

const { useState, useCallback } = React;

const deepClone = ( obj ) => JSON.parse( JSON.stringify( obj ) );

const resolvePath = ( path, base = window ) => {
	return path.split( '.' ).reduce( ( acc, part ) => acc && acc[ part ], base );
};

const useRepeaterState = ( initialStateOrPath, syncWithWindow = false, titleKey = '', repeaterType = 'inline', titlePrefix = '' ) => {
	const isPath = typeof initialStateOrPath === 'string';
	const initialState = isPath ? deepClone( resolvePath( initialStateOrPath ) || [] ) : deepClone( initialStateOrPath );
	const [ items, setItems ] = useState( initialState );

	const updateExternalState = ( updatedItems ) => {
		if ( isPath && syncWithWindow ) {
			const target = resolvePath( initialStateOrPath );
			if ( target ) {
				target.length = 0;
				target.push( ...updatedItems );
			}
		}
	};

	const handleChange = useCallback( ( updatedItems ) => {
		setItems( updatedItems );
		updateExternalState( updatedItems );
	}, [ isPath, initialStateOrPath, syncWithWindow ] );

	const onChange = useCallback( ( key, index ) => ( value ) => {
		const updatedItems = [ ...items ];
		updatedItems[ index ][ key ] = value;

		if ( titleKey && repeaterType === 'block' && key === titleKey ) {
			updatedItems[ index ].repeater_item_block_content_title = titlePrefix ? sprintf( titlePrefix, value ) : value;
		}

		handleChange( updatedItems );
	}, [ items, handleChange, repeaterType, titleKey ] );

	return { items, handleChange, onChange };
};

export default useRepeaterState;
