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

const SUMMARY_DELAY_MS = 180;
const ACTIONS_DELAY_MS = 680;
const VIBRATE_PATTERN = [18, 32, 18] as const;

export type PurchaseMomentPhase = 'intro' | 'summary' | 'actions';

export type PurchaseMomentTimelineState = {
  phase: PurchaseMomentPhase;
  summaryVisible: boolean;
  actionsVisible: boolean;
  reducedMotion: boolean;
};

function readReducedMotion(): boolean {
  if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
    return false;
  }
  return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
}

function subscribeReducedMotion(callback: () => void): () => void {
  if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return () => {};
  const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
  mediaQuery.addEventListener?.('change', callback);
  return () => mediaQuery.removeEventListener?.('change', callback);
}

export function usePurchaseMomentTimeline(): PurchaseMomentTimelineState {
  const [timeline, setTimeline] = useState<PurchaseMomentTimelineState>(() => ({
    phase: 'intro',
    summaryVisible: false,
    actionsVisible: false,
    reducedMotion: false,
  }));
  const startedRef = useRef(false);
  const vibratedRef = useRef(false);
  const reducedMotion = useSyncExternalStore(
    subscribeReducedMotion,
    readReducedMotion,
    () => false,
  );

  useEffect(() => {
    if (reducedMotion) {
      startedRef.current = true;
      void Promise.resolve().then(() =>
        setTimeline({
          phase: 'actions',
          summaryVisible: true,
          actionsVisible: true,
          reducedMotion: true,
        }),
      );
      return;
    }

    if (startedRef.current) {
      return;
    }
    startedRef.current = true;

    if (!vibratedRef.current && typeof navigator !== 'undefined' && 'vibrate' in navigator) {
      navigator.vibrate(VIBRATE_PATTERN);
      vibratedRef.current = true;
    }

    setTimeline({
      phase: 'intro',
      summaryVisible: false,
      actionsVisible: false,
      reducedMotion: false,
    });

    const summaryTimer = window.setTimeout(() => {
      setTimeline({
        phase: 'summary',
        summaryVisible: true,
        actionsVisible: false,
        reducedMotion: false,
      });
    }, SUMMARY_DELAY_MS);

    const actionsTimer = window.setTimeout(() => {
      setTimeline({
        phase: 'actions',
        summaryVisible: true,
        actionsVisible: true,
        reducedMotion: false,
      });
    }, ACTIONS_DELAY_MS);

    return () => {
      window.clearTimeout(summaryTimer);
      window.clearTimeout(actionsTimer);
    };
  }, [reducedMotion]);

  return reducedMotion
    ? { phase: 'actions', summaryVisible: true, actionsVisible: true, reducedMotion: true }
    : timeline;
}
