import { useEffect, useState, useRef } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import { connectionBase } from '../Global';
import { SetSnackType } from '../Components/Snack';

const getSessionId = async (userId?: string) => {
  const endpoint = userId
    ? `/api/context/u/${encodeURIComponent(userId)}`
    : `/api/context`;

  const response = await fetch(connectionBase + endpoint, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
  });

  if (!response.ok) {
    throw Error("Server is temporarily down.");
  }

  const newSession = (await response.json()).id;
  console.log(`Session created: ${newSession}`);

  return newSession;
};

interface SessionWrapperProps {
  setSnack: SetSnackType;
  children: React.ReactNode;
}

const SessionWrapper = ({ setSnack, children }: SessionWrapperProps) => {
  const navigate = useNavigate();
  const location = useLocation();
  const [sessionId, setSessionId] = useState<string | undefined>(undefined);
  const fetchingRef = useRef(false);
  const [retry, setRetry] = useState<number>(0);

  useEffect(() => {
    console.log(`SessionWrapper: ${location.pathname}`);

    const ensureSessionId = async () => {
      const parts = location.pathname.split("/").filter(Boolean);
      const pattern = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89ab][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/i;

      // Case: path starts with "u/{USERID}"
      if (parts.length >= 2 && parts[0] === "u") {
        const userId = parts[1];

        // Case: "u/{USERID}" - fetch session for this user
        const activeSession = await getSessionId(userId);
        setSessionId(activeSession);

        // Append session to path
        const newPath = [...parts, activeSession].join("/");
        navigate(`/${activeSession}`, { replace: true });
        return;
      }

      // Default case (original behavior)
      const hasSession = parts.length !== 0 && pattern.test(parts[parts.length - 1]);

      if (!hasSession) {
        let activeSession = sessionId;
        if (!activeSession) {
          activeSession = await getSessionId();
          setSessionId(activeSession);
        }

        const newPath = [...parts, activeSession].join("/");
        navigate(`/${newPath}`, { replace: true });
      }
    };

    if (!fetchingRef.current) {
      fetchingRef.current = true;
      ensureSessionId()
        .catch((e) => {
          console.error(e);
          setSnack("Backstory is temporarily unavailable. Retrying in 5 seconds.", "warning");
          setTimeout(() => {
            fetchingRef.current = false;
            setRetry(retry => retry + 1);
          }, 5000);
        })
        .finally(() => {
          if (fetchingRef.current) {
            fetchingRef.current = false;
          }
        });
    }
  }, [location.pathname, navigate, setSnack, sessionId, retry]);

  return <>{children}</>;
};

export { SessionWrapper };