"use client";

import {
	createContext,
	type ReactNode,
	useCallback,
	useContext,
	useMemo,
} from "react";
import { useLocation, useNavigate } from "react-router-dom";

// =============================================================================
// TYPES
// =============================================================================

export interface OnboardingStepConfig {
	/** URL path segment for this step (e.g., 'business-function') */
	path: string;
	/** Display name for progress indicator */
	name: string;
	/**
	 * The component to render for this step.
	 * Use the `useOnboarding()` hook inside the component to access navigation helpers.
	 */
	component: React.ComponentType;
}

export interface OnboardingStepProps {
	/** Navigate to next step */
	goNext: () => void;
	/** Navigate to previous step */
	goBack: () => void;
	/** Navigate to a specific step by path */
	goTo: (path: string) => void;
	/** Current step index (0-based) */
	currentStep: number;
	/** Total number of steps */
	totalSteps: number;
	/** Whether this is the first step */
	isFirst: boolean;
	/** Whether this is the last step */
	isLast: boolean;
	/** Current step path */
	currentPath: string;
}

export interface OnboardingContextValue extends OnboardingStepProps {
	/** All step configurations */
	steps: OnboardingStepConfig[];
	/** Base path for the wizard */
	basePath: string;
}

export interface OnboardingWizardConfig {
	/** Base path for the onboarding wizard (e.g., '/onboarding') */
	basePath?: string;
	/** Step configurations */
	steps: OnboardingStepConfig[];
	/** Callback when wizard completes (navigates past last step) */
	onComplete?: () => void;
	/** Callback when user exits/cancels */
	onExit?: () => void;
}

// =============================================================================
// CONTEXT
// =============================================================================

const OnboardingContext = createContext<OnboardingContextValue | null>(null);

export function useOnboarding(): OnboardingContextValue {
	const context = useContext(OnboardingContext);
	if (!context) {
		throw new Error("useOnboarding must be used within an OnboardingProvider");
	}
	return context;
}

export function useOnboardingOptional(): OnboardingContextValue | null {
	return useContext(OnboardingContext);
}

// =============================================================================
// PROVIDER
// =============================================================================

interface OnboardingProviderProps {
	children: ReactNode;
	config: OnboardingWizardConfig;
}

export function OnboardingProvider({
	children,
	config,
}: OnboardingProviderProps) {
	const { steps, basePath = "", onComplete } = config;
	const navigate = useNavigate();
	const location = useLocation();

	// Determine current step from URL
	const currentPath = location.pathname.replace(/^\/+/, "").replace(/\/+$/, "");
	const currentStep = useMemo(() => {
		const index = steps.findIndex((step) => step.path === currentPath);
		return index >= 0 ? index : 0;
	}, [steps, currentPath]);

	const totalSteps = steps.length;
	const isFirst = currentStep === 0;
	const isLast = currentStep === totalSteps - 1;

	const goTo = useCallback(
		(path: string) => {
			navigate(`/${path}`);
		},
		[navigate],
	);

	const goNext = useCallback(() => {
		if (isLast) {
			onComplete?.();
		} else {
			const nextStep = steps[currentStep + 1];
			if (nextStep) {
				goTo(nextStep.path);
			}
		}
	}, [currentStep, isLast, steps, goTo, onComplete]);

	const goBack = useCallback(() => {
		if (!isFirst) {
			const prevStep = steps[currentStep - 1];
			if (prevStep) {
				goTo(prevStep.path);
			}
		}
	}, [currentStep, isFirst, steps, goTo]);

	const value = useMemo<OnboardingContextValue>(
		() => ({
			steps,
			basePath,
			currentStep,
			totalSteps,
			isFirst,
			isLast,
			currentPath,
			goNext,
			goBack,
			goTo,
		}),
		[
			steps,
			basePath,
			currentStep,
			totalSteps,
			isFirst,
			isLast,
			currentPath,
			goNext,
			goBack,
			goTo,
		],
	);

	return (
		<OnboardingContext.Provider value={value}>
			{children}
		</OnboardingContext.Provider>
	);
}
