import { useEffect, useState } from "react";
import { Navigate, Outlet } from "react-router-dom";
import { match } from "ts-pattern";
import { useMaybeUser } from "../providers/UserStoreProvider";
import { LoadingSpinner } from "./LoadingSpinner";

interface ProtectedRouteProps {
  // Fallback URL
  fallback?: string;
  // Only allow regular users (not temporary)
  onlyRegularUser?: boolean;
  // Redirect to current page
  shouldRedirectToCurrentPage?: boolean;
}

export const ProtectedRoute = ({
  fallback,
  onlyRegularUser,
  shouldRedirectToCurrentPage,
}: ProtectedRouteProps) => {
  const user = useMaybeUser();
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const timer = setTimeout(() => {
      setIsLoading(false);
    }, 500);
    return () => clearTimeout(timer);
  }, [user, fallback]);

  let status: "loading" | "should-land-user" | "should-redirect" | "should-pass" = "loading";

  const isFirstTimeUser = localStorage.getItem("xtablo-has-seen-landing-page") === null;

  if (isLoading) {
    status = "loading";
  } else if (!user && isFirstTimeUser) {
    status = "should-land-user";
  } else if (!user) {
    status = "should-redirect";
  } else if (onlyRegularUser && user.is_temporary) {
    status = "should-redirect";
  } else {
    status = "should-pass";
  }

  const fallbackUrl = fallback ?? "/login";

  const redirectUrl = shouldRedirectToCurrentPage
    ? `${fallbackUrl}?redirect=${encodeURIComponent(
        `${window.location.pathname}${window.location.search}`
      )}`
    : fallbackUrl;

  return match(status)
    .with("loading", () => <LoadingSpinner />)
    .with("should-land-user", () => <Navigate to="/landing" replace />)
    .with("should-redirect", () => <Navigate to={redirectUrl} replace />)
    .with("should-pass", () => <Outlet />)
    .exhaustive();
};
