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

const { useCallback, useState } = React;

/**
 * @function resolveCount
 * @description Resolves the count of cards in each Kanban item.
 *
 * @since 5.8.4
 *
 * @param {Array<object>} data The Kanban data to resolve counts for.
 *
 * @return {Array<object>} The Kanban data with updated counts.
 */
const resolveCount = ( data ) => data.map( ( item ) => {
	const count = item.cards ? item.cards.length : 0;
	return {
		...item,
		props: {
			...( item?.props || {} ),
			columnCountAttributes: {
				...( item?.props?.columnCountAttributes || {} ),
				label: count.toString(),
			},
		},
	};
} );

/**
 * @module useKanbanState
 * @description Custom hook to manage the state of the Kanban board.
 *
 * @since 5.8.4
 *
 * @param {object} props              The props for the custom hook.
 * @param {Array}  props.initialData  The initial data for the Kanban board.
 * @param {object} props.initialState The initial module state.
 * @param {Array}  props.modules      The modules for the kanban.
 *
 * @return {object} The current data and a function to update the data.
 *
 * @example
 * const initialData = [
 * 	{
 * 		id: 'no-status',
 * 		props: {
 * 			columnCountAttributes: {
 * 				label: '4',
 * 			},
 * 			columnLabelAttributes: {
 * 				label: 'No Status',
 * 			},
 * 		},
 * 		cards: [
 * 			{
 * 				component: KanbanCard,
 * 				props: {
 * 					id: 'card-1',
 * 					children: 'Card 1 Content',
 * 					headerContent: 'Card 1 Header',
 * 					footerContent: 'Card 1 Footer',
 * 				},
 * 			},
 * 			{
 * 				component: KanbanCard,
 * 				props: {
 * 					id: 'card-2',
 * 					children: 'Card 2 Content',
 * 					headerContent: 'Card 2 Header',
 * 					footerContent: 'Card 2 Footer',
 * 				},
 * 			},
 * 			{
 * 				component: KanbanCard,
 * 				props: {
 * 					id: 'card-3',
 * 					children: 'Card 3 Content',
 * 					headerContent: 'Card 3 Header',
 * 					footerContent: 'Card 3 Footer',
 * 				},
 * 			},
 * 			{
 * 				component: KanbanCard,
 * 				props: {
 * 					id: 'card-4',
 * 					children: 'Card 4 Content',
 * 					headerContent: 'Card 4 Header',
 * 					footerContent: 'Card 4 Footer',
 * 				},
 * 			},
 * 		],
 * 	},
 * 	{
 * 		id: 'in-progress',
 * 		props: {
 * 			columnCountAttributes: {
 * 				label: '2',
 * 			},
 * 			columnLabelAttributes: {
 * 				label: 'In Progress',
 * 				status: 'blue',
 * 			},
 * 		},
 * 		cards: [
 * 			{
 * 				component: KanbanCard,
 * 				props: {
 * 					id: 'card-5',
 * 					children: 'Card 5 Content',
 * 					headerContent: 'Card 5 Header',
 * 					footerContent: 'Card 5 Footer',
 * 				},
 * 			},
 * 			{
 * 				component: KanbanCard,
 * 				props: {
 * 					id: 'card-6',
 * 					children: 'Card 6 Content',
 * 					headerContent: 'Card 6 Header',
 * 					footerContent: 'Card 6 Footer',
 * 				},
 * 			},
 * 		],
 * 	},
 * 	{
 * 		id: 'completed',
 * 		props: {
 * 			columnCountAttributes: {
 * 				label: '1',
 * 			},
 * 			columnLabelAttributes: {
 * 				label: 'Completed',
 * 				status: 'active',
 * 			},
 * 		},
 * 		cards: [
 * 			{
 * 				component: KanbanCard,
 * 				props: {
 * 					id: 'card-7',
 * 					children: 'Card 7 Content',
 * 					headerContent: 'Card 7 Header',
 * 					footerContent: 'Card 7 Footer',
 * 				},
 * 			},
 * 		],
 * 	},
 * ];
 * const initialState = {
 * 	moduleState: {},
 * 	isLoading: false,
 * };
 * const modules = [ Search, SimpleFilters ];
 * const { data, updateData, moduleState, updateModuleState, isLoading, setIsLoading } = useKanbanState( {
 * 	initialData,
 * 	initialState,
 * 	modules,
 * } );
 *
 */
const useKanbanState = ( {
	initialData = [],
	initialState = {},
	modules = [],
} ) => {
	const [ moduleState, setModuleState ] = useState( () => {
		const { Search, SimpleFilters } = getModules( modules, [ 'Search', 'SimpleFilters' ] );
		return {
			...( ( Search && Search?.getDefaultState() ) || {} ),
			...( ( SimpleFilters && SimpleFilters?.getDefaultState() ) || {} ),
			...( initialState?.moduleState || {} ),
		};
	} );
	const [ data, setData ] = useState( initialData );
	const [ isLoading, setIsLoading ] = useState( initialState?.isLoading || false );

	/**
	 * @function updateModuleState
	 * @description Updates the module state with new values.
	 *
	 * @since 5.8.4
	 *
	 * @param {object} newState The new state to update the module state with.
	 */
	const updateModuleState = useCallback( ( newState ) => {
		setModuleState( { ...moduleState, ...newState } );
	}, [ moduleState ] );

	/**
	 * @function updateData
	 * @description Updates the Kanban data.
	 *
	 * @since 5.8.4
	 *
	 * @param {Array<object>} newData The new data for the Kanban board.
	 */
	const updateData = useCallback( ( newData ) => {
		const updatedData = resolveCount( newData );
		setData( updatedData );
	}, [] );

	return {
		data,
		updateData,
		moduleState,
		updateModuleState,
		isLoading,
		setIsLoading,
	};
};

export default useKanbanState;

