import { useEffect, useRef, useState, type ReactNode } from "react";

interface PageTransitionProps {
  viewKey: string;
  children: ReactNode;
}

const EXIT_DURATION_MS = 180;

const NAV_ORDER: string[] = [
  "home",
  "workbench",
  "ecommerce",
  "ecommerceTemplates",
  "sizeTemplate",
  "canvas",
  "scriptTokens",
  "tokenUsage",
  "community",
  "assets",
  "more",
  "imageWorkbench",
  "resolutionUpscale",
  "watermarkRemoval",
  "subtitleRemoval",
  "dialogGenerator",
  "digitalHuman",
  "avatarConsole",
  "characterMix",
  "agent",
  "login",
  "profile",
  "report",
];

function getNavIndex(key: string): number {
  return NAV_ORDER.indexOf(key);
}

export default function PageTransition({ viewKey, children }: PageTransitionProps) {
  const [displayedChildren, setDisplayedChildren] = useState(children);
  const [phase, setPhase] = useState<"idle" | "exit">("idle");
  const [exitDirection, setExitDirection] = useState<"forward" | "backward" | "neutral">("neutral");
  const prevKeyRef = useRef(viewKey);
  const timerRef = useRef<ReturnType<typeof setTimeout>>();

  useEffect(() => {
    if (viewKey === prevKeyRef.current) {
      setDisplayedChildren(children);
      // Cancel any active exit animation — children updated but viewKey stable.
      setPhase("idle");
      return;
    }

    const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (prefersReducedMotion) {
      prevKeyRef.current = viewKey;
      setDisplayedChildren(children);
      setPhase("idle");
      return;
    }

    const prevIndex = getNavIndex(prevKeyRef.current);
    const nextIndex = getNavIndex(viewKey);
    if (prevIndex < nextIndex) {
      setExitDirection("forward");
    } else if (prevIndex > nextIndex) {
      setExitDirection("backward");
    } else {
      setExitDirection("neutral");
    }
    prevKeyRef.current = viewKey;

    setPhase("exit");
    timerRef.current = setTimeout(() => {
      setDisplayedChildren(children);
      setPhase("idle");
    }, EXIT_DURATION_MS);
    return () => clearTimeout(timerRef.current);
  }, [viewKey, children]);

  const dirClass = exitDirection === "forward" ? " is-forward" : exitDirection === "backward" ? " is-backward" : "";

  if (!displayedChildren) return null;

  return (
    <div className={phase === "exit" ? `page-transition-wrap page-motion--exit${dirClass}` : "page-transition-wrap"}>
      {displayedChildren}
    </div>
  );
}
