'use client';

import React, { createContext, useContext, useState, useCallback, ReactNode, useEffect } from 'react';
import { useRouter, usePathname, useSearchParams } from 'next/navigation';

interface TransitionContextType {
  isTransitioning: boolean;
  transitionMessage: string | null;
  startTransition: (href: string, message?: string | null) => void;
}

const TransitionContext = createContext<TransitionContextType | undefined>(undefined);

export function TransitionProvider({ children }: { children: ReactNode }) {
  const [isTransitioning, setIsTransitioning] = useState(false);
  const [transitionMessage, setTransitionMessage] = useState<string | null>(null);
  const router = useRouter();

  // We use a ref to track transition state without triggering the route change effect when it turns true
  const isTransitioningRef = React.useRef(isTransitioning);
  useEffect(() => {
    isTransitioningRef.current = isTransitioning;
  }, [isTransitioning]);

  const startTransition = useCallback((href: string, message: string | null = null) => {
    // Wenn wir bereits navigieren, nichts tun
    if (isTransitioning) return;
    
    // Normalize paths to avoid false mismatches (e.g. /de vs /de/)
    const currentPath = typeof window !== 'undefined' ? window.location.pathname.replace(/\/$/, '') || '/' : '';
    const targetPath = href.split('?')[0].replace(/\/$/, '') || '/';
    const currentSearch = typeof window !== 'undefined' ? window.location.search : '';
    const targetSearch = href.includes('?') ? '?' + href.split('?')[1] : '';

    // Aktuelle URL prüfen, falls es dieselbe ist, nicht navigieren
    if (currentPath === targetPath && currentSearch === targetSearch) {
       // Optional: Wir könnten weich nach oben scrollen
       window.scrollTo({ top: 0, behavior: 'smooth' });
       return;
    }

    setTransitionMessage(message);
    setIsTransitioning(true);

    // Die Animation des Shutters abwarten (ca. 700ms), dann pushen
    setTimeout(() => {
      router.push(href);
      
      // Fallback: If for some reason the route doesn't change after 60 seconds (useful for slow dev servers), open the shutter anyway
      setTimeout(() => {
        setIsTransitioning((current) => {
          if (current) {
            setTimeout(() => setTransitionMessage(null), 300);
            return false;
          }
          return current;
        });
      }, 60000);
    }, 700);
  }, [isTransitioning, router]);

  return (
    <TransitionContext.Provider value={{ isTransitioning, transitionMessage, startTransition }}>
      <React.Suspense fallback={null}>
        <TransitionRouteWatcher 
          isTransitioningRef={isTransitioningRef}
          setIsTransitioning={setIsTransitioning}
          setTransitionMessage={setTransitionMessage}
        />
      </React.Suspense>
      {children}
    </TransitionContext.Provider>
  );
}

function TransitionRouteWatcher({ isTransitioningRef, setIsTransitioning, setTransitionMessage }: any) {
  const pathname = usePathname();
  const searchParams = useSearchParams();

  useEffect(() => {
    if (isTransitioningRef.current) {
      const timer = setTimeout(() => {
        setIsTransitioning(false);
        setTimeout(() => setTransitionMessage(null), 300);
      }, 100);
      return () => clearTimeout(timer);
    }
  }, [pathname, searchParams, setIsTransitioning, setTransitionMessage, isTransitioningRef]);

  return null;
}

export function useTransition() {
  const context = useContext(TransitionContext);
  if (!context) {
    throw new Error('useTransition must be used within a TransitionProvider');
  }
  return context;
}
