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<CheckoutWizardContextValue | undefined>(undefined);

export const CheckoutWizardProvider: React.FC<CheckoutWizardProviderProps> = ({
  initialPackage,
  packageOptions,
  initialStep = 'package',
  initialAuthUser = null,
  initialIsAuthenticated,
  children,
}) => {
  const [state, setState] = useState<CheckoutWizardState>(() => ({
    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<CheckoutWizardContextValue['markAuthenticated']>((user) => {
    setState((prev) => ({
      ...prev,
      isAuthenticated: Boolean(user),
      authUser: user ?? null,
    }));
  }, []);

  const setPaymentProvider = useCallback<CheckoutWizardContextValue['setPaymentProvider']>((provider) => {
    setState((prev) => ({
      ...prev,
      paymentProvider: provider,
    }));
  }, []);

  const resetPaymentState = useCallback(() => {
    setState((prev) => ({
      ...prev,
      paymentProvider: undefined,
      isProcessing: false,
    }));
  }, []);

  const value = useMemo<CheckoutWizardContextValue>(() => ({
    ...state,
    setStep,
    nextStep,
    previousStep,
    setSelectedPackage,
    markAuthenticated,
    setPaymentProvider,
    resetPaymentState,
  }), [state, setStep, nextStep, previousStep, setSelectedPackage, markAuthenticated, setPaymentProvider, resetPaymentState]);

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

export const useCheckoutWizard = () => {
  const context = useContext(CheckoutWizardContext);
  if (!context) {
    throw new Error('useCheckoutWizard must be used within CheckoutWizardProvider');
  }
  return context;
};
