import apiFetch from '@wordpress/api-fetch';
import { useDispatch } from '@wordpress/data';
import { useEffect, useState } from '@wordpress/element';
import { store as noticesStore } from '@wordpress/notices';

let sharedSettings = window.jetBookingWidgets?.settings ?? {};

const settingsListeners = new Set();

const notifySettingsUpdate = () => {
	settingsListeners.forEach( ( listener ) => listener( sharedSettings ) );
};

const setSharedSettings = ( value ) => {
	sharedSettings = 'function' === typeof value ? value( sharedSettings ) : value;

	window.jetBookingWidgets = {
		...window.jetBookingWidgets,
		settings: sharedSettings,
	};

	notifySettingsUpdate();
};

const subscribeToSettings = ( listener ) => {
	settingsListeners.add( listener );

	return () => settingsListeners.delete( listener );
};

const useSettings = () => {
	const [ settings, setSettings ] = useState( sharedSettings );
	const [ saving, setSaving ] = useState( false );
	const { createErrorNotice, createSuccessNotice, removeNotice } = useDispatch( noticesStore );

	useEffect( () => subscribeToSettings( setSettings ), [] );

	const updateSetting = ( key, value ) => {
		setSharedSettings( ( prev ) => ( { ...prev, [ key ]: value } ) );
	};

	const saveSettings = () => {
		setSaving( true );

		const formData = new FormData();

		formData.append( 'action', 'jet_abaf_save_settings' );
		formData.append( 'nonce', window.jetBookingWidgets?.nonce || '' );
		formData.append( 'settings', JSON.stringify( sharedSettings ) );

		apiFetch( {
			url: window.jetBookingWidgets?.ajax_url || '',
			method: 'POST',
			body: formData,
		} ).then( ( result ) => {
			const noticeMethod = result.success ? createSuccessNotice : createErrorNotice;

			noticeMethod( result.data.message, { isDismissible: false } )
				.then( ( notice ) => setTimeout( () => removeNotice( notice.notice.id ), 7000 ) );
		} ).catch( ( error ) => {
			createErrorNotice( error.message, { isDismissible: false } )
				.then( ( notice ) => setTimeout( () => removeNotice( notice.notice.id ), 7000 ) );
		} ).finally( () => setSaving( false ) );
	};

	return {
		saving,
		settings,
		saveSettings,
		updateSetting,
	};
};

export default useSettings;
