import React, { useEffect, useRef, useState } from 'react';
import { useLocation } from 'react-router-dom';
import { style } from '@vanilla-extract/css';

const transitionContainer = style({
  position: 'relative',
  width: '100%',
  height: '100%',
  overflow: 'hidden',
});

const transitionContent = style({
  width: '100%',
  height: '100%',
});

const animateIn = style({
  animation: 'routeFadeSlideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1)',
  '@keyframes': {
    routeFadeSlideIn: {
      from: {
        opacity: 0,
        transform: 'translateX(12px)',
      },
      to: {
        opacity: 1,
        transform: 'translateX(0)',
      },
    },
  },
});

const animateOut = style({
  animation: 'routeFadeSlideOut 0.2s cubic-bezier(0.4, 0, 0.2, 1) forwards',
  '@keyframes': {
    routeFadeSlideOut: {
      from: {
        opacity: 1,
        transform: 'translateX(0)',
      },
      to: {
        opacity: 0,
        transform: 'translateX(-12px)',
      },
    },
  },
});

interface RouteTransitionProps {
  children: React.ReactNode;
}

/**
 * Wraps content in a transition animation that triggers on route change
 */
export function RouteTransition({ children }: RouteTransitionProps) {
  const location = useLocation();
  const [displayLocation, setDisplayLocation] = useState(location);
  const [transitionStage, setTransitionStage] = useState<'entering' | 'exiting' | 'idle'>('idle');
  const timeoutRef = useRef<ReturnType<typeof setTimeout>>();

  useEffect(() => {
    if (location.pathname !== displayLocation.pathname) {
      // Start exit animation
      setTransitionStage('exiting');

      // Clear any existing timeout
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }

      // Wait for exit animation, then update location and enter
      timeoutRef.current = setTimeout(() => {
        setDisplayLocation(location);
        setTransitionStage('entering');

        // Reset to idle after enter animation
        timeoutRef.current = setTimeout(() => {
          setTransitionStage('idle');
        }, 250);
      }, 200);
    }

    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, [location, displayLocation]);

  const className = transitionStage === 'entering' 
    ? `${transitionContent} ${animateIn}` 
    : transitionStage === 'exiting'
    ? `${transitionContent} ${animateOut}`
    : transitionContent;

  return (
    <div className={transitionContainer}>
      <div className={className} key={displayLocation.pathname}>
        {children}
      </div>
    </div>
  );
}
