import React, { createContext, useContext, useState, useCallback } from 'react';

interface StepUpAuthContextType {
  isOpen: boolean;
  actionDescription: string;
  pendingRequest: (() => Promise<unknown>) | null;
  openStepUp: (actionDescription: string, pendingRequest: () => Promise<unknown>) => void;
  closeStepUp: () => void;
  onStepUpSuccess: () => void;
}

const StepUpAuthContext = createContext<StepUpAuthContextType | undefined>(undefined);

export const StepUpAuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [isOpen, setIsOpen] = useState(false);
  const [actionDescription, setActionDescription] = useState('');
  const [pendingRequest, setPendingRequest] = useState<(() => Promise<unknown>) | null>(null);

  const openStepUp = useCallback((action: string, request: () => Promise<unknown>) => {
    console.log('openStepUp called', { action, hasRequest: !!request });
    setActionDescription(action);
    setPendingRequest(() => request);
    setIsOpen(true);
  }, []);

  const closeStepUp = useCallback(() => {
    setIsOpen(false);
    setActionDescription('');
    setPendingRequest(null);
  }, []);

  const onStepUpSuccess = useCallback(async () => {
    if (pendingRequest) {
      try {
        await pendingRequest();
      } catch (error) {
        // Error will be handled by the original request handler
        console.error('Error retrying request after step-up:', error);
      }
    }
    closeStepUp();
  }, [pendingRequest, closeStepUp]);

  return (
    <StepUpAuthContext.Provider
      value={{
        isOpen,
        actionDescription,
        pendingRequest,
        openStepUp,
        closeStepUp,
        onStepUpSuccess,
      }}
    >
      {children}
    </StepUpAuthContext.Provider>
  );
};

// eslint-disable-next-line react-refresh/only-export-components
export const useStepUpAuth = () => {
  const context = useContext(StepUpAuthContext);
  if (context === undefined) {
    throw new Error('useStepUpAuth must be used within a StepUpAuthProvider');
  }
  return context;
};

