import { useCallback, useRef, useEffect, useState } from 'react';

import { useAnalytics } from '../analytics-context';

import type { FunnelStepData } from '../types';

export interface UseFunnelTrackingOptions {
  /** Whether to auto-track abandonment on unmount */
  trackAbandonOnUnmount?: boolean;
}

export function useFunnelTracking(
  funnelId: string,
  options: UseFunnelTrackingOptions = {},
) {
  const { trackInteraction } = useAnalytics();
  const { trackAbandonOnUnmount = true } = options;

  const [initialTime] = useState(() => Date.now());
  const stateRef = useRef<{
    currentStepId: string | null;
    currentStepNumber: number | null;
    stepEntryTime: number;
  }>({
    currentStepId: null,
    currentStepNumber: null,
    stepEntryTime: initialTime,
  });

  const trackStep = useCallback(
    (action: FunnelStepData['action'], stepId: string, stepNumber: number) => {
      const timeInStepMs =
        action !== 'enter'
          ? Date.now() - stateRef.current.stepEntryTime
          : undefined;

      trackInteraction({
        type: 'funnel_step',
        data: {
          funnelId,
          stepId,
          stepNumber,
          action,
          timeInStepMs,
        },
      });
    },
    [funnelId, trackInteraction],
  );

  const enterStep = useCallback(
    (stepId: string, stepNumber: number) => {
      stateRef.current = {
        currentStepId: stepId,
        currentStepNumber: stepNumber,
        stepEntryTime: Date.now(),
      };
      trackStep('enter', stepId, stepNumber);
    },
    [trackStep],
  );

  const completeStep = useCallback(
    (stepId: string, stepNumber: number) => {
      trackStep('complete', stepId, stepNumber);
      stateRef.current.currentStepId = null;
      stateRef.current.currentStepNumber = null;
    },
    [trackStep],
  );

  const abandonStep = useCallback(
    (stepId?: string, stepNumber?: number) => {
      const { currentStepId, currentStepNumber } = stateRef.current;
      const targetStepId = stepId ?? currentStepId;
      const targetStepNumber = stepNumber ?? currentStepNumber;

      if (targetStepId && targetStepNumber !== null) {
        trackStep('abandon', targetStepId, targetStepNumber);
        stateRef.current.currentStepId = null;
        stateRef.current.currentStepNumber = null;
      }
    },
    [trackStep],
  );

  // Track abandonment on unmount if in a step
  useEffect(() => {
    return () => {
      if (trackAbandonOnUnmount) {
        const { currentStepId, currentStepNumber } = stateRef.current;
        if (currentStepId && currentStepNumber !== null) {
          // Note: This runs in cleanup, so trackInteraction may not complete
          // if the component unmounts due to navigation. Consider using
          // navigator.sendBeacon for critical abandonment tracking.
          trackStep('abandon', currentStepId, currentStepNumber);
        }
      }
    };
  }, [trackAbandonOnUnmount, trackStep]);

  return {
    enterStep,
    completeStep,
    abandonStep,
    /** Current step ID if in a funnel step */
    getCurrentStep: () => stateRef.current.currentStepId,
  };
}
