import { createContext, useCallback, useContext, useMemo, useState } from '@wordpress/element';
import { getFilters, getOptions, isPro as readIsPro, isUltimateActive } from '../Helpers';

const SettingsContext = createContext( null );

export const SettingsProvider = ( { children } ) => {
	// Last values known to be stored on the server, and the working copy the UI edits.
	// Filter rows come from the separate `all_filter` key (removed legacy dashboard.js used it the same way).
	const [ savedOptions, setSavedOptions ] = useState( () => ( { ...getOptions(), all_product_filter_info: getFilters() } ) );
	const [ options, setOptions ] = useState( savedOptions );
	const [ changeCount, setChangeCount ] = useState( 0 );

	// Local edits that the user has not saved yet.
	const updateOption = useCallback( ( key, value ) => {
		setOptions( ( previous ) => ( { ...previous, [ key ]: value } ) );
		setChangeCount( ( count ) => count + 1 );
	}, [] );

	const updateOptions = useCallback( ( updates ) => {
		setOptions( ( previous ) => ( { ...previous, ...updates } ) );
		setChangeCount( ( count ) => count + 1 );
	}, [] );

	// Values the server has already stored (wizard steps, saves) – not counted as unsaved changes.
	const applySavedOptions = useCallback( ( updates ) => {
		setOptions( ( previous ) => ( { ...previous, ...updates } ) );
		setSavedOptions( ( previous ) => ( { ...previous, ...updates } ) );
	}, [] );

	// After a successful save the working copy becomes the new baseline.
	const commitSaved = useCallback( ( values ) => {
		setSavedOptions( values );
		setOptions( values );
		setChangeCount( 0 );
	}, [] );

	const discardChanges = useCallback( () => {
		setOptions( savedOptions );
		setChangeCount( 0 );
	}, [ savedOptions ] );

	const value = useMemo(
		() => ( {
			options,
			savedOptions,
			updateOption,
			updateOptions,
			applySavedOptions,
			commitSaved,
			discardChanges,
			changeCount,
			setChangeCount,
			// Derived from live state so finishing the wizard unlocks the dashboard without a reload.
			isSetupComplete: Number( options.setup_step ) >= 5,
			// Pro features unlock only when Ultimate is active and its licence is valid.
			isPro: isUltimateActive() && readIsPro(),
		} ),
		[ options, savedOptions, updateOption, updateOptions, applySavedOptions, commitSaved, discardChanges, changeCount ]
	);

	return <SettingsContext.Provider value={ value }>{ children }</SettingsContext.Provider>;
};

export const useSettings = () => useContext( SettingsContext );
