import React, {useEffect} from "react";
import {
	GlobalStateProvider,
	useGlobalStateReducers, useGlobalStateValue,
} from "../../GlobalState";
import {usePreviousValue} from "../../Utils";
import {StepKeyType, stepsGlobalState, useCurrentStepKey, useStepsNavigator} from "./StepsContext";



/**
 * Main Steps component.
 */
export function Steps({children}: React.PropsWithChildren<{}>)
{
	return (
		<GlobalStateProvider globalState={stepsGlobalState}>
			<div className={"steps"}>
				<StepsNavigatorComponent />

				<div>
					{children}
				</div>
			</div>
		</GlobalStateProvider>
	);
}

/**
 * Steps navigator component.
 */
export function StepsNavigatorComponent()
{
	// Get the steps navigator functions.
	const stepsNavigator = useStepsNavigator();

	// Get the current steps state.
	const stepsState = useGlobalStateValue(stepsGlobalState);

	// Get the current step.
	const currentStep = useCurrentStepKey();

	return (
		<nav className={"steps"}>
			<ul>
				{ // Showing a button for each step.
					stepsState.steps.map((step, index) => (
						// Rendering the current step button.
						<li key={step.key} className={currentStep == step.key ? "active" : undefined}>
							<button type={"button"} onClick={() => {
								stepsNavigator.set(step.key);
							}}>
								{step.title ?? (index + 1)}
							</button>
						</li>
					))
				}
			</ul>
		</nav>
	);
}


/**
 * Component of a step.
 */
export function Step({stepKey, stepTitle, children}: React.PropsWithChildren<{
	/**
	 * The current step unique key.
	 */
	stepKey: StepKeyType;

	/**
	 * The step title, to show in the navigator.
	 */
	stepTitle?: React.ReactNode;
}>)
{
	// Get the global state reducers class.
	const stepsGlobalStateReducers = useGlobalStateReducers(stepsGlobalState);

	// Get the previous step key.
	const previousStepKey = usePreviousValue(stepKey);

	useEffect(() => {
		// Remove the previous step key, if there is one.
		if (previousStepKey) stepsGlobalStateReducers.removeStep(previousStepKey);

		// Register the current step key.
		stepsGlobalStateReducers.registerStep(stepKey, stepTitle);

		// Remove the step key when component is removed.
		return () => stepsGlobalStateReducers.removeStep(stepKey);
	}, [stepsGlobalStateReducers, previousStepKey, stepTitle]);

	// Get the current step key.
	const currentStep = useCurrentStepKey();

	if (currentStep != stepKey)
		// If this step is not the current one, rendering nothing.
		return undefined;

	// Rendering the current step.
	return (
		<section className={"step"}>
			{children}
		</section>
	);
}
