import React, { createContext, useCallback, useContext, useMemo, useState } from "react"; import type { CheckoutPackage, CheckoutStepId, CheckoutWizardContextValue, CheckoutWizardState } from "./types"; interface CheckoutWizardProviderProps { initialPackage: CheckoutPackage; packageOptions: CheckoutPackage[]; initialStep?: CheckoutStepId; initialAuthUser?: CheckoutWizardState['authUser']; initialIsAuthenticated?: boolean; children: React.ReactNode; } const CheckoutWizardContext = createContext(undefined); export const CheckoutWizardProvider: React.FC = ({ initialPackage, packageOptions, initialStep = 'package', initialAuthUser = null, initialIsAuthenticated, children, }) => { const [state, setState] = useState(() => ({ currentStep: initialStep, selectedPackage: initialPackage, packageOptions, isAuthenticated: Boolean(initialIsAuthenticated || initialAuthUser), authUser: initialAuthUser ?? null, paymentProvider: undefined, isProcessing: false, })); const setStep = useCallback((step: CheckoutStepId) => { setState((prev) => ({ ...prev, currentStep: step })); }, []); const nextStep = useCallback(() => { setState((prev) => { const order: CheckoutStepId[] = ['package', 'auth', 'payment', 'confirmation']; const currentIndex = order.indexOf(prev.currentStep); const nextIndex = currentIndex === -1 ? 0 : Math.min(order.length - 1, currentIndex + 1); return { ...prev, currentStep: order[nextIndex] }; }); }, []); const previousStep = useCallback(() => { setState((prev) => { const order: CheckoutStepId[] = ['package', 'auth', 'payment', 'confirmation']; const currentIndex = order.indexOf(prev.currentStep); const nextIndex = currentIndex <= 0 ? 0 : currentIndex - 1; return { ...prev, currentStep: order[nextIndex] }; }); }, []); const setSelectedPackage = useCallback((pkg: CheckoutPackage) => { setState((prev) => ({ ...prev, selectedPackage: pkg, paymentProvider: undefined, })); }, []); const markAuthenticated = useCallback((user) => { setState((prev) => ({ ...prev, isAuthenticated: Boolean(user), authUser: user ?? null, })); }, []); const setPaymentProvider = useCallback((provider) => { setState((prev) => ({ ...prev, paymentProvider: provider, })); }, []); const resetPaymentState = useCallback(() => { setState((prev) => ({ ...prev, paymentProvider: undefined, isProcessing: false, })); }, []); const value = useMemo(() => ({ ...state, setStep, nextStep, previousStep, setSelectedPackage, markAuthenticated, setPaymentProvider, resetPaymentState, }), [state, setStep, nextStep, previousStep, setSelectedPackage, markAuthenticated, setPaymentProvider, resetPaymentState]); return ( {children} ); }; export const useCheckoutWizard = () => { const context = useContext(CheckoutWizardContext); if (!context) { throw new Error('useCheckoutWizard must be used within CheckoutWizardProvider'); } return context; };